mirror of
https://github.com/kubernetes/client-go.git
synced 2025-06-26 15:12:06 +00:00
Merge pull request #54971 from itowlson/azure-sdk-v11.1.1
Automatic merge from submit-queue (batch tested with PRs 55093, 54966, 55047, 54971, 54786). If you want to cherry-pick this change to another branch, please follow the instructions <a href="https://github.com/kubernetes/community/blob/master/contributors/devel/cherry-picks.md">here</a>. Upgrade Azure SDK to v11.1.1 **What this PR does / why we need it**: This fixes various Azure SDK bugs per the Azure SDK for Go changelogs: * Fixed bug in which blob types were unmarshaled incorrectly * Fixed various package names * Miscellaneous unspecified storage bug fixes This is also a prerequisite for a bug fix for running out of firewall rules when exposing large numbers of services from an Azure cluster. **Which issue(s) this PR fixes**: None **Special notes for your reviewer**: 1. I inadvertently committed a compatibility fix along with the dependency upgrade (which the guidelines say should have been two separate commits). The offending file is `pkg/cloudprovider/providers/azure.go`. 2. We require an urgent bug fix for the firewall rules limit so it would be great if we could get this agreed quickly. I have struggled with the dependency upgrade process a bit so if it looks wrong, please let me know as soon as you can! Thanks! **Release note**: ```release-note Upgraded Azure SDK to v11.1.1. ``` Kubernetes-commit: b4588383503743f70a01cc26e303de481dc02de0
This commit is contained in:
commit
55df955d1d
1392
Godeps/Godeps.json
generated
1392
Godeps/Godeps.json
generated
File diff suppressed because it is too large
Load Diff
14
vendor/github.com/Azure/go-autorest/autorest/adal/config.go
generated
vendored
14
vendor/github.com/Azure/go-autorest/autorest/adal/config.go
generated
vendored
@ -1,5 +1,19 @@
|
|||||||
package adal
|
package adal
|
||||||
|
|
||||||
|
// 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.
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"net/url"
|
"net/url"
|
||||||
|
14
vendor/github.com/Azure/go-autorest/autorest/adal/devicetoken.go
generated
vendored
14
vendor/github.com/Azure/go-autorest/autorest/adal/devicetoken.go
generated
vendored
@ -1,5 +1,19 @@
|
|||||||
package adal
|
package adal
|
||||||
|
|
||||||
|
// 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 is largely based on rjw57/oauth2device's code, with the follow differences:
|
This file is largely based on rjw57/oauth2device's code, with the follow differences:
|
||||||
* scope -> resource, and only allow a single one
|
* scope -> resource, and only allow a single one
|
||||||
|
20
vendor/github.com/Azure/go-autorest/autorest/adal/msi.go
generated
vendored
Normal file
20
vendor/github.com/Azure/go-autorest/autorest/adal/msi.go
generated
vendored
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
// +build !windows
|
||||||
|
|
||||||
|
package adal
|
||||||
|
|
||||||
|
// 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.
|
||||||
|
|
||||||
|
// msiPath is the path to the MSI Extension settings file (to discover the endpoint)
|
||||||
|
var msiPath = "/var/lib/waagent/ManagedIdentity-Settings"
|
25
vendor/github.com/Azure/go-autorest/autorest/adal/msi_windows.go
generated
vendored
Normal file
25
vendor/github.com/Azure/go-autorest/autorest/adal/msi_windows.go
generated
vendored
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
// +build windows
|
||||||
|
|
||||||
|
package adal
|
||||||
|
|
||||||
|
// 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.
|
||||||
|
|
||||||
|
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"}, "/")
|
14
vendor/github.com/Azure/go-autorest/autorest/adal/persist.go
generated
vendored
14
vendor/github.com/Azure/go-autorest/autorest/adal/persist.go
generated
vendored
@ -1,5 +1,19 @@
|
|||||||
package adal
|
package adal
|
||||||
|
|
||||||
|
// 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.
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
14
vendor/github.com/Azure/go-autorest/autorest/adal/sender.go
generated
vendored
14
vendor/github.com/Azure/go-autorest/autorest/adal/sender.go
generated
vendored
@ -1,5 +1,19 @@
|
|||||||
package adal
|
package adal
|
||||||
|
|
||||||
|
// 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.
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"net/http"
|
"net/http"
|
||||||
)
|
)
|
||||||
|
73
vendor/github.com/Azure/go-autorest/autorest/adal/token.go
generated
vendored
73
vendor/github.com/Azure/go-autorest/autorest/adal/token.go
generated
vendored
@ -1,5 +1,19 @@
|
|||||||
package adal
|
package adal
|
||||||
|
|
||||||
|
// 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.
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"crypto/rand"
|
"crypto/rand"
|
||||||
"crypto/rsa"
|
"crypto/rsa"
|
||||||
@ -15,12 +29,12 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/Azure/go-autorest/autorest/date"
|
||||||
"github.com/dgrijalva/jwt-go"
|
"github.com/dgrijalva/jwt-go"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
defaultRefresh = 5 * time.Minute
|
defaultRefresh = 5 * time.Minute
|
||||||
tokenBaseDate = "1970-01-01T00:00:00Z"
|
|
||||||
|
|
||||||
// OAuthGrantTypeDeviceCode is the "grant_type" identifier used in device flow
|
// OAuthGrantTypeDeviceCode is the "grant_type" identifier used in device flow
|
||||||
OAuthGrantTypeDeviceCode = "device_code"
|
OAuthGrantTypeDeviceCode = "device_code"
|
||||||
@ -31,16 +45,10 @@ const (
|
|||||||
// OAuthGrantTypeRefreshToken is the "grant_type" identifier used in refresh token flows
|
// OAuthGrantTypeRefreshToken is the "grant_type" identifier used in refresh token flows
|
||||||
OAuthGrantTypeRefreshToken = "refresh_token"
|
OAuthGrantTypeRefreshToken = "refresh_token"
|
||||||
|
|
||||||
// managedIdentitySettingsPath is the path to the MSI Extension settings file (to discover the endpoint)
|
// metadataHeader is the header required by MSI extension
|
||||||
managedIdentitySettingsPath = "/var/lib/waagent/ManagedIdentity-Settings"
|
metadataHeader = "Metadata"
|
||||||
)
|
)
|
||||||
|
|
||||||
var expirationBase time.Time
|
|
||||||
|
|
||||||
func init() {
|
|
||||||
expirationBase, _ = time.Parse(time.RFC3339, tokenBaseDate)
|
|
||||||
}
|
|
||||||
|
|
||||||
// OAuthTokenProvider is an interface which should be implemented by an access token retriever
|
// OAuthTokenProvider is an interface which should be implemented by an access token retriever
|
||||||
type OAuthTokenProvider interface {
|
type OAuthTokenProvider interface {
|
||||||
OAuthToken() string
|
OAuthToken() string
|
||||||
@ -76,7 +84,10 @@ func (t Token) Expires() time.Time {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
s = -3600
|
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.
|
// IsExpired returns true if the Token is expired, false otherwise.
|
||||||
@ -135,9 +146,7 @@ type ServicePrincipalMSISecret struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// SetAuthenticationValues is a method of the interface ServicePrincipalSecret.
|
// SetAuthenticationValues is a method of the interface ServicePrincipalSecret.
|
||||||
// MSI extension requires the authority field to be set to the real tenant authority endpoint
|
|
||||||
func (msiSecret *ServicePrincipalMSISecret) SetAuthenticationValues(spt *ServicePrincipalToken, v *url.Values) error {
|
func (msiSecret *ServicePrincipalMSISecret) SetAuthenticationValues(spt *ServicePrincipalToken, v *url.Values) error {
|
||||||
v.Set("authority", spt.oauthConfig.AuthorityEndpoint.String())
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -261,41 +270,43 @@ func NewServicePrincipalTokenFromCertificate(oauthConfig OAuthConfig, clientID s
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewServicePrincipalTokenFromMSI creates a ServicePrincipalToken via the MSI VM Extension.
|
// GetMSIVMEndpoint gets the MSI endpoint on Virtual Machines.
|
||||||
func NewServicePrincipalTokenFromMSI(oauthConfig OAuthConfig, resource string, callbacks ...TokenRefreshCallback) (*ServicePrincipalToken, error) {
|
func GetMSIVMEndpoint() (string, error) {
|
||||||
return newServicePrincipalTokenFromMSI(oauthConfig, resource, managedIdentitySettingsPath, callbacks...)
|
return getMSIVMEndpoint(msiPath)
|
||||||
}
|
}
|
||||||
|
|
||||||
func newServicePrincipalTokenFromMSI(oauthConfig OAuthConfig, resource, settingsPath string, callbacks ...TokenRefreshCallback) (*ServicePrincipalToken, error) {
|
func getMSIVMEndpoint(path string) (string, error) {
|
||||||
// Read MSI settings
|
// Read MSI settings
|
||||||
bytes, err := ioutil.ReadFile(settingsPath)
|
bytes, err := ioutil.ReadFile(path)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return "", err
|
||||||
}
|
}
|
||||||
msiSettings := struct {
|
msiSettings := struct {
|
||||||
URL string `json:"url"`
|
URL string `json:"url"`
|
||||||
}{}
|
}{}
|
||||||
err = json.Unmarshal(bytes, &msiSettings)
|
err = json.Unmarshal(bytes, &msiSettings)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
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
|
// We set the oauth config token endpoint to be MSI's endpoint
|
||||||
// We leave the authority as-is so MSI can POST it with the token request
|
msiEndpointURL, err := url.Parse(msiEndpoint)
|
||||||
msiEndpointURL, err := url.Parse(msiSettings.URL)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
msiTokenEndpointURL, err := msiEndpointURL.Parse("/oauth2/token")
|
oauthConfig, err := NewOAuthConfig(msiEndpointURL.String(), "")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
oauthConfig.TokenEndpoint = *msiTokenEndpointURL
|
|
||||||
|
|
||||||
spt := &ServicePrincipalToken{
|
spt := &ServicePrincipalToken{
|
||||||
oauthConfig: oauthConfig,
|
oauthConfig: *oauthConfig,
|
||||||
secret: &ServicePrincipalMSISecret{},
|
secret: &ServicePrincipalMSISecret{},
|
||||||
resource: resource,
|
resource: resource,
|
||||||
autoRefresh: true,
|
autoRefresh: true,
|
||||||
@ -364,16 +375,24 @@ func (spt *ServicePrincipalToken) refreshInternal(resource string) error {
|
|||||||
|
|
||||||
req.ContentLength = int64(len(s))
|
req.ContentLength = int64(len(s))
|
||||||
req.Header.Set(contentType, mimeTypeFormPost)
|
req.Header.Set(contentType, mimeTypeFormPost)
|
||||||
|
if _, ok := spt.secret.(*ServicePrincipalMSISecret); ok {
|
||||||
|
req.Header.Set(metadataHeader, "true")
|
||||||
|
}
|
||||||
resp, err := spt.sender.Do(req)
|
resp, err := spt.sender.Do(req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("adal: Failed to execute the refresh request. Error = '%v'", err)
|
return fmt.Errorf("adal: Failed to execute the refresh request. Error = '%v'", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
defer resp.Body.Close()
|
defer resp.Body.Close()
|
||||||
|
rb, err := ioutil.ReadAll(resp.Body)
|
||||||
|
|
||||||
if resp.StatusCode != http.StatusOK {
|
if resp.StatusCode != http.StatusOK {
|
||||||
return fmt.Errorf("adal: Refresh request failed. Status Code = '%d'", resp.StatusCode)
|
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))
|
||||||
}
|
}
|
||||||
|
|
||||||
rb, err := ioutil.ReadAll(resp.Body)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("adal: Failed to read a new service principal token during refresh. Error = '%v'", err)
|
return fmt.Errorf("adal: Failed to read a new service principal token during refresh. Error = '%v'", err)
|
||||||
}
|
}
|
||||||
|
124
vendor/github.com/Azure/go-autorest/autorest/authorization.go
generated
vendored
124
vendor/github.com/Azure/go-autorest/autorest/authorization.go
generated
vendored
@ -1,12 +1,34 @@
|
|||||||
package autorest
|
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.
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"net/url"
|
||||||
|
"strings"
|
||||||
|
|
||||||
"github.com/Azure/go-autorest/autorest/adal"
|
"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
|
// 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
|
// authorization. Most often, the Authorizer decorator runs last so it has access to the full
|
||||||
// state of the formed HTTP request.
|
// state of the formed HTTP request.
|
||||||
@ -55,3 +77,105 @@ func (ba *BearerAuthorizer) WithAuthorization() PrepareDecorator {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 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
|
||||||
|
}
|
||||||
|
14
vendor/github.com/Azure/go-autorest/autorest/autorest.go
generated
vendored
14
vendor/github.com/Azure/go-autorest/autorest/autorest.go
generated
vendored
@ -57,6 +57,20 @@ generated clients, see the Client described below.
|
|||||||
*/
|
*/
|
||||||
package autorest
|
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.
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"net/http"
|
"net/http"
|
||||||
"time"
|
"time"
|
||||||
|
14
vendor/github.com/Azure/go-autorest/autorest/azure/async.go
generated
vendored
14
vendor/github.com/Azure/go-autorest/autorest/azure/async.go
generated
vendored
@ -1,5 +1,19 @@
|
|||||||
package azure
|
package azure
|
||||||
|
|
||||||
|
// 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.
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
22
vendor/github.com/Azure/go-autorest/autorest/azure/azure.go
generated
vendored
22
vendor/github.com/Azure/go-autorest/autorest/azure/azure.go
generated
vendored
@ -5,6 +5,20 @@ See the included examples for more detail.
|
|||||||
*/
|
*/
|
||||||
package azure
|
package azure
|
||||||
|
|
||||||
|
// 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.
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
@ -165,7 +179,13 @@ func WithErrorUnlessStatusCode(codes ...int) autorest.RespondDecorator {
|
|||||||
if decodeErr != nil {
|
if decodeErr != nil {
|
||||||
return fmt.Errorf("autorest/azure: error response cannot be parsed: %q error: %v", b.String(), decodeErr)
|
return fmt.Errorf("autorest/azure: error response cannot be parsed: %q error: %v", b.String(), decodeErr)
|
||||||
} else if e.ServiceError == nil {
|
} else if e.ServiceError == nil {
|
||||||
e.ServiceError = &ServiceError{Code: "Unknown", Message: "Unknown service error"}
|
// Check if error is unwrapped ServiceError
|
||||||
|
if err := json.Unmarshal(b.Bytes(), &e.ServiceError); err != nil || e.ServiceError.Message == "" {
|
||||||
|
e.ServiceError = &ServiceError{
|
||||||
|
Code: "Unknown",
|
||||||
|
Message: "Unknown service error",
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
e.RequestID = ExtractRequestID(resp)
|
e.RequestID = ExtractRequestID(resp)
|
||||||
|
14
vendor/github.com/Azure/go-autorest/autorest/azure/environments.go
generated
vendored
14
vendor/github.com/Azure/go-autorest/autorest/azure/environments.go
generated
vendored
@ -1,5 +1,19 @@
|
|||||||
package azure
|
package azure
|
||||||
|
|
||||||
|
// 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.
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"strings"
|
"strings"
|
||||||
|
188
vendor/github.com/Azure/go-autorest/autorest/azure/rp.go
generated
vendored
Normal file
188
vendor/github.com/Azure/go-autorest/autorest/azure/rp.go
generated
vendored
Normal file
@ -0,0 +1,188 @@
|
|||||||
|
package azure
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"net/http"
|
||||||
|
"net/url"
|
||||||
|
"strings"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/Azure/go-autorest/autorest"
|
||||||
|
)
|
||||||
|
|
||||||
|
// DoRetryWithRegistration tries to register the resource provider in case it is unregistered.
|
||||||
|
// It also handles request retries
|
||||||
|
func DoRetryWithRegistration(client autorest.Client) autorest.SendDecorator {
|
||||||
|
return func(s autorest.Sender) autorest.Sender {
|
||||||
|
return autorest.SenderFunc(func(r *http.Request) (resp *http.Response, err error) {
|
||||||
|
rr := autorest.NewRetriableRequest(r)
|
||||||
|
for currentAttempt := 0; currentAttempt < client.RetryAttempts; currentAttempt++ {
|
||||||
|
err = rr.Prepare()
|
||||||
|
if err != nil {
|
||||||
|
return resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
resp, err = autorest.SendWithSender(s, rr.Request(),
|
||||||
|
autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...),
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
return resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if resp.StatusCode != http.StatusConflict {
|
||||||
|
return resp, err
|
||||||
|
}
|
||||||
|
var re RequestError
|
||||||
|
err = autorest.Respond(
|
||||||
|
resp,
|
||||||
|
autorest.ByUnmarshallingJSON(&re),
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
return resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if re.ServiceError != nil && re.ServiceError.Code == "MissingSubscriptionRegistration" {
|
||||||
|
err = register(client, r, re)
|
||||||
|
if err != nil {
|
||||||
|
return resp, fmt.Errorf("failed auto registering Resource Provider: %s", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return resp, errors.New("failed request and resource provider registration")
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func getProvider(re RequestError) (string, error) {
|
||||||
|
if re.ServiceError != nil {
|
||||||
|
if re.ServiceError.Details != nil && len(*re.ServiceError.Details) > 0 {
|
||||||
|
detail := (*re.ServiceError.Details)[0].(map[string]interface{})
|
||||||
|
return detail["target"].(string), nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return "", errors.New("provider was not found in the response")
|
||||||
|
}
|
||||||
|
|
||||||
|
func register(client autorest.Client, originalReq *http.Request, re RequestError) error {
|
||||||
|
subID := getSubscription(originalReq.URL.Path)
|
||||||
|
if subID == "" {
|
||||||
|
return errors.New("missing parameter subscriptionID to register resource provider")
|
||||||
|
}
|
||||||
|
providerName, err := getProvider(re)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("missing parameter provider to register resource provider: %s", err)
|
||||||
|
}
|
||||||
|
newURL := url.URL{
|
||||||
|
Scheme: originalReq.URL.Scheme,
|
||||||
|
Host: originalReq.URL.Host,
|
||||||
|
}
|
||||||
|
|
||||||
|
// taken from the resources SDK
|
||||||
|
// with almost identical code, this sections are easier to mantain
|
||||||
|
// It is also not a good idea to import the SDK here
|
||||||
|
// https://github.com/Azure/azure-sdk-for-go/blob/9f366792afa3e0ddaecdc860e793ba9d75e76c27/arm/resources/resources/providers.go#L252
|
||||||
|
pathParameters := map[string]interface{}{
|
||||||
|
"resourceProviderNamespace": autorest.Encode("path", providerName),
|
||||||
|
"subscriptionId": autorest.Encode("path", subID),
|
||||||
|
}
|
||||||
|
|
||||||
|
const APIVersion = "2016-09-01"
|
||||||
|
queryParameters := map[string]interface{}{
|
||||||
|
"api-version": APIVersion,
|
||||||
|
}
|
||||||
|
|
||||||
|
preparer := autorest.CreatePreparer(
|
||||||
|
autorest.AsPost(),
|
||||||
|
autorest.WithBaseURL(newURL.String()),
|
||||||
|
autorest.WithPathParameters("/subscriptions/{subscriptionId}/providers/{resourceProviderNamespace}/register", pathParameters),
|
||||||
|
autorest.WithQueryParameters(queryParameters),
|
||||||
|
)
|
||||||
|
|
||||||
|
req, err := preparer.Prepare(&http.Request{})
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
req.Cancel = originalReq.Cancel
|
||||||
|
|
||||||
|
resp, err := autorest.SendWithSender(client, req,
|
||||||
|
autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...),
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
type Provider struct {
|
||||||
|
RegistrationState *string `json:"registrationState,omitempty"`
|
||||||
|
}
|
||||||
|
var provider Provider
|
||||||
|
|
||||||
|
err = autorest.Respond(
|
||||||
|
resp,
|
||||||
|
WithErrorUnlessStatusCode(http.StatusOK),
|
||||||
|
autorest.ByUnmarshallingJSON(&provider),
|
||||||
|
autorest.ByClosing(),
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// poll for registered provisioning state
|
||||||
|
now := time.Now()
|
||||||
|
for err == nil && time.Since(now) < client.PollingDuration {
|
||||||
|
// taken from the resources SDK
|
||||||
|
// https://github.com/Azure/azure-sdk-for-go/blob/9f366792afa3e0ddaecdc860e793ba9d75e76c27/arm/resources/resources/providers.go#L45
|
||||||
|
preparer := autorest.CreatePreparer(
|
||||||
|
autorest.AsGet(),
|
||||||
|
autorest.WithBaseURL(newURL.String()),
|
||||||
|
autorest.WithPathParameters("/subscriptions/{subscriptionId}/providers/{resourceProviderNamespace}", pathParameters),
|
||||||
|
autorest.WithQueryParameters(queryParameters),
|
||||||
|
)
|
||||||
|
req, err = preparer.Prepare(&http.Request{})
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
req.Cancel = originalReq.Cancel
|
||||||
|
|
||||||
|
resp, err := autorest.SendWithSender(client.Sender, req,
|
||||||
|
autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...),
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
err = autorest.Respond(
|
||||||
|
resp,
|
||||||
|
WithErrorUnlessStatusCode(http.StatusOK),
|
||||||
|
autorest.ByUnmarshallingJSON(&provider),
|
||||||
|
autorest.ByClosing(),
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if provider.RegistrationState != nil &&
|
||||||
|
*provider.RegistrationState == "Registered" {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
delayed := autorest.DelayWithRetryAfter(resp, originalReq.Cancel)
|
||||||
|
if !delayed {
|
||||||
|
autorest.DelayForBackoff(client.PollingDelay, 0, originalReq.Cancel)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if !(time.Since(now) < client.PollingDuration) {
|
||||||
|
return errors.New("polling for resource provider registration has exceeded the polling duration")
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func getSubscription(path string) string {
|
||||||
|
parts := strings.Split(path, "/")
|
||||||
|
for i, v := range parts {
|
||||||
|
if v == "subscriptions" && (i+1) < len(parts) {
|
||||||
|
return parts[i+1]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ""
|
||||||
|
}
|
21
vendor/github.com/Azure/go-autorest/autorest/client.go
generated
vendored
21
vendor/github.com/Azure/go-autorest/autorest/client.go
generated
vendored
@ -1,5 +1,19 @@
|
|||||||
package autorest
|
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.
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"fmt"
|
"fmt"
|
||||||
@ -33,8 +47,10 @@ var (
|
|||||||
Version(),
|
Version(),
|
||||||
)
|
)
|
||||||
|
|
||||||
statusCodesForRetry = []int{
|
// StatusCodesForRetry are a defined group of status code for which the client will retry
|
||||||
|
StatusCodesForRetry = []int{
|
||||||
http.StatusRequestTimeout, // 408
|
http.StatusRequestTimeout, // 408
|
||||||
|
http.StatusTooManyRequests, // 429
|
||||||
http.StatusInternalServerError, // 500
|
http.StatusInternalServerError, // 500
|
||||||
http.StatusBadGateway, // 502
|
http.StatusBadGateway, // 502
|
||||||
http.StatusServiceUnavailable, // 503
|
http.StatusServiceUnavailable, // 503
|
||||||
@ -186,8 +202,7 @@ func (c Client) Do(r *http.Request) (*http.Response, error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, NewErrorWithError(err, "autorest/Client", "Do", nil, "Preparing request failed")
|
return nil, NewErrorWithError(err, "autorest/Client", "Do", nil, "Preparing request failed")
|
||||||
}
|
}
|
||||||
resp, err := SendWithSender(c.sender(), r,
|
resp, err := SendWithSender(c.sender(), r)
|
||||||
DoRetryForStatusCodes(c.RetryAttempts, c.RetryDuration, statusCodesForRetry...))
|
|
||||||
Respond(resp,
|
Respond(resp,
|
||||||
c.ByInspecting())
|
c.ByInspecting())
|
||||||
return resp, err
|
return resp, err
|
||||||
|
14
vendor/github.com/Azure/go-autorest/autorest/date/date.go
generated
vendored
14
vendor/github.com/Azure/go-autorest/autorest/date/date.go
generated
vendored
@ -5,6 +5,20 @@ time.Time types. And both convert to time.Time through a ToTime method.
|
|||||||
*/
|
*/
|
||||||
package date
|
package date
|
||||||
|
|
||||||
|
// 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.
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"time"
|
"time"
|
||||||
|
14
vendor/github.com/Azure/go-autorest/autorest/date/time.go
generated
vendored
14
vendor/github.com/Azure/go-autorest/autorest/date/time.go
generated
vendored
@ -1,5 +1,19 @@
|
|||||||
package date
|
package date
|
||||||
|
|
||||||
|
// 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.
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"regexp"
|
"regexp"
|
||||||
"time"
|
"time"
|
||||||
|
14
vendor/github.com/Azure/go-autorest/autorest/date/timerfc1123.go
generated
vendored
14
vendor/github.com/Azure/go-autorest/autorest/date/timerfc1123.go
generated
vendored
@ -1,5 +1,19 @@
|
|||||||
package date
|
package date
|
||||||
|
|
||||||
|
// 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.
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
"time"
|
"time"
|
||||||
|
14
vendor/github.com/Azure/go-autorest/autorest/date/unixtime.go
generated
vendored
14
vendor/github.com/Azure/go-autorest/autorest/date/unixtime.go
generated
vendored
@ -1,5 +1,19 @@
|
|||||||
package date
|
package date
|
||||||
|
|
||||||
|
// 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.
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"encoding/binary"
|
"encoding/binary"
|
||||||
|
14
vendor/github.com/Azure/go-autorest/autorest/date/utility.go
generated
vendored
14
vendor/github.com/Azure/go-autorest/autorest/date/utility.go
generated
vendored
@ -1,5 +1,19 @@
|
|||||||
package date
|
package date
|
||||||
|
|
||||||
|
// 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.
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
18
vendor/github.com/Azure/go-autorest/autorest/error.go
generated
vendored
18
vendor/github.com/Azure/go-autorest/autorest/error.go
generated
vendored
@ -1,5 +1,19 @@
|
|||||||
package autorest
|
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.
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"net/http"
|
"net/http"
|
||||||
@ -31,6 +45,9 @@ type DetailedError struct {
|
|||||||
|
|
||||||
// Service Error is the response body of failed API in bytes
|
// Service Error is the response body of failed API in bytes
|
||||||
ServiceError []byte
|
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
|
// NewError creates a new Error conforming object from the passed packageType, method, and
|
||||||
@ -67,6 +84,7 @@ func NewErrorWithError(original error, packageType string, method string, resp *
|
|||||||
Method: method,
|
Method: method,
|
||||||
StatusCode: statusCode,
|
StatusCode: statusCode,
|
||||||
Message: fmt.Sprintf(message, args...),
|
Message: fmt.Sprintf(message, args...),
|
||||||
|
Response: resp,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
14
vendor/github.com/Azure/go-autorest/autorest/preparer.go
generated
vendored
14
vendor/github.com/Azure/go-autorest/autorest/preparer.go
generated
vendored
@ -1,5 +1,19 @@
|
|||||||
package autorest
|
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.
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
14
vendor/github.com/Azure/go-autorest/autorest/responder.go
generated
vendored
14
vendor/github.com/Azure/go-autorest/autorest/responder.go
generated
vendored
@ -1,5 +1,19 @@
|
|||||||
package autorest
|
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.
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
52
vendor/github.com/Azure/go-autorest/autorest/retriablerequest.go
generated
vendored
Normal file
52
vendor/github.com/Azure/go-autorest/autorest/retriablerequest.go
generated
vendored
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
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.
|
||||||
|
|
||||||
|
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
|
||||||
|
}
|
54
vendor/github.com/Azure/go-autorest/autorest/retriablerequest_1.7.go
generated
vendored
Normal file
54
vendor/github.com/Azure/go-autorest/autorest/retriablerequest_1.7.go
generated
vendored
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
// +build !go1.8
|
||||||
|
|
||||||
|
// 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 (
|
||||||
|
"bytes"
|
||||||
|
"io/ioutil"
|
||||||
|
"net/http"
|
||||||
|
)
|
||||||
|
|
||||||
|
// RetriableRequest provides facilities for retrying an HTTP request.
|
||||||
|
type RetriableRequest struct {
|
||||||
|
req *http.Request
|
||||||
|
br *bytes.Reader
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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.br != nil {
|
||||||
|
_, err = rr.br.Seek(0, 0 /*io.SeekStart*/)
|
||||||
|
rr.req.Body = ioutil.NopCloser(rr.br)
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if rr.br == nil {
|
||||||
|
// fall back to making a copy (only do this once)
|
||||||
|
err = rr.prepareFromByteReader()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func removeRequestBody(req *http.Request) {
|
||||||
|
req.Body = nil
|
||||||
|
req.ContentLength = 0
|
||||||
|
}
|
66
vendor/github.com/Azure/go-autorest/autorest/retriablerequest_1.8.go
generated
vendored
Normal file
66
vendor/github.com/Azure/go-autorest/autorest/retriablerequest_1.8.go
generated
vendored
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
// +build go1.8
|
||||||
|
|
||||||
|
// 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 (
|
||||||
|
"bytes"
|
||||||
|
"io"
|
||||||
|
"io/ioutil"
|
||||||
|
"net/http"
|
||||||
|
)
|
||||||
|
|
||||||
|
// RetriableRequest provides facilities for retrying an HTTP request.
|
||||||
|
type RetriableRequest struct {
|
||||||
|
req *http.Request
|
||||||
|
rc io.ReadCloser
|
||||||
|
br *bytes.Reader
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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.rc != nil {
|
||||||
|
rr.req.Body = rr.rc
|
||||||
|
} else if rr.br != nil {
|
||||||
|
_, err = rr.br.Seek(0, io.SeekStart)
|
||||||
|
rr.req.Body = ioutil.NopCloser(rr.br)
|
||||||
|
}
|
||||||
|
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()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func removeRequestBody(req *http.Request) {
|
||||||
|
req.Body = nil
|
||||||
|
req.GetBody = nil
|
||||||
|
req.ContentLength = 0
|
||||||
|
}
|
67
vendor/github.com/Azure/go-autorest/autorest/sender.go
generated
vendored
67
vendor/github.com/Azure/go-autorest/autorest/sender.go
generated
vendored
@ -1,12 +1,25 @@
|
|||||||
package autorest
|
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.
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"io/ioutil"
|
|
||||||
"log"
|
"log"
|
||||||
"math"
|
"math"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"strconv"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -175,8 +188,13 @@ func DoPollForStatusCodes(duration time.Duration, delay time.Duration, codes ...
|
|||||||
func DoRetryForAttempts(attempts int, backoff time.Duration) SendDecorator {
|
func DoRetryForAttempts(attempts int, backoff time.Duration) SendDecorator {
|
||||||
return func(s Sender) Sender {
|
return func(s Sender) Sender {
|
||||||
return SenderFunc(func(r *http.Request) (resp *http.Response, err error) {
|
return SenderFunc(func(r *http.Request) (resp *http.Response, err error) {
|
||||||
|
rr := NewRetriableRequest(r)
|
||||||
for attempt := 0; attempt < attempts; attempt++ {
|
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 {
|
if err == nil {
|
||||||
return resp, err
|
return resp, err
|
||||||
}
|
}
|
||||||
@ -194,29 +212,43 @@ func DoRetryForAttempts(attempts int, backoff time.Duration) SendDecorator {
|
|||||||
func DoRetryForStatusCodes(attempts int, backoff time.Duration, codes ...int) SendDecorator {
|
func DoRetryForStatusCodes(attempts int, backoff time.Duration, codes ...int) SendDecorator {
|
||||||
return func(s Sender) Sender {
|
return func(s Sender) Sender {
|
||||||
return SenderFunc(func(r *http.Request) (resp *http.Response, err error) {
|
return SenderFunc(func(r *http.Request) (resp *http.Response, err error) {
|
||||||
b := []byte{}
|
rr := NewRetriableRequest(r)
|
||||||
if r.Body != nil {
|
|
||||||
b, err = ioutil.ReadAll(r.Body)
|
|
||||||
if err != nil {
|
|
||||||
return resp, err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Increment to add the first call (attempts denotes number of retries)
|
// Increment to add the first call (attempts denotes number of retries)
|
||||||
attempts++
|
attempts++
|
||||||
for attempt := 0; attempt < attempts; attempt++ {
|
for attempt := 0; attempt < attempts; attempt++ {
|
||||||
r.Body = ioutil.NopCloser(bytes.NewBuffer(b))
|
err = rr.Prepare()
|
||||||
resp, err = s.Do(r)
|
if err != nil {
|
||||||
|
return resp, err
|
||||||
|
}
|
||||||
|
resp, err = s.Do(rr.Request())
|
||||||
if err != nil || !ResponseHasStatusCode(resp, codes...) {
|
if err != nil || !ResponseHasStatusCode(resp, codes...) {
|
||||||
return resp, err
|
return resp, err
|
||||||
}
|
}
|
||||||
DelayForBackoff(backoff, attempt, r.Cancel)
|
delayed := DelayWithRetryAfter(resp, r.Cancel)
|
||||||
|
if !delayed {
|
||||||
|
DelayForBackoff(backoff, attempt, r.Cancel)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return resp, err
|
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
|
// 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
|
// 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
|
// supplied backoff time.Duration (which may be zero). Retrying may be canceled by closing the
|
||||||
@ -224,9 +256,14 @@ func DoRetryForStatusCodes(attempts int, backoff time.Duration, codes ...int) Se
|
|||||||
func DoRetryForDuration(d time.Duration, backoff time.Duration) SendDecorator {
|
func DoRetryForDuration(d time.Duration, backoff time.Duration) SendDecorator {
|
||||||
return func(s Sender) Sender {
|
return func(s Sender) Sender {
|
||||||
return SenderFunc(func(r *http.Request) (resp *http.Response, err error) {
|
return SenderFunc(func(r *http.Request) (resp *http.Response, err error) {
|
||||||
|
rr := NewRetriableRequest(r)
|
||||||
end := time.Now().Add(d)
|
end := time.Now().Add(d)
|
||||||
for attempt := 0; time.Now().Before(end); attempt++ {
|
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 {
|
if err == nil {
|
||||||
return resp, err
|
return resp, err
|
||||||
}
|
}
|
||||||
|
14
vendor/github.com/Azure/go-autorest/autorest/utility.go
generated
vendored
14
vendor/github.com/Azure/go-autorest/autorest/utility.go
generated
vendored
@ -1,5 +1,19 @@
|
|||||||
package autorest
|
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.
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
14
vendor/github.com/Azure/go-autorest/autorest/version.go
generated
vendored
14
vendor/github.com/Azure/go-autorest/autorest/version.go
generated
vendored
@ -1,5 +1,19 @@
|
|||||||
package autorest
|
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.
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
Loading…
Reference in New Issue
Block a user