From b1be0624371c4b9e3690fec977c417dba765984c Mon Sep 17 00:00:00 2001 From: Ludovic Fernandez Date: Mon, 9 Apr 2018 18:28:03 +0200 Subject: [PATCH] fix: update lego. --- Gopkg.lock | 18 +- .../Azure/azure-sdk-for-go/arm/dns/models.go | 338 -------- .../dns/mgmt/2017-09-01}/dns/client.go | 16 +- .../dns/mgmt/2017-09-01/dns/models.go | 763 ++++++++++++++++++ .../dns/mgmt/2017-09-01}/dns/recordsets.go | 263 +++--- .../dns/mgmt/2017-09-01}/dns/version.go | 6 +- .../dns/mgmt/2017-09-01}/dns/zones.go | 277 +++---- .../Azure/azure-sdk-for-go/version/version.go | 21 + .../Azure/go-autorest/autorest/adal/config.go | 30 + .../go-autorest/autorest/adal/devicetoken.go | 14 + .../Azure/go-autorest/autorest/adal/msi.go | 6 - .../go-autorest/autorest/adal/msi_windows.go | 11 - .../go-autorest/autorest/adal/persist.go | 14 + .../Azure/go-autorest/autorest/adal/sender.go | 14 + .../Azure/go-autorest/autorest/adal/token.go | 369 +++++++-- .../go-autorest/autorest/authorization.go | 148 +++- .../Azure/go-autorest/autorest/autorest.go | 35 + .../Azure/go-autorest/autorest/azure/async.go | 331 ++++++-- .../Azure/go-autorest/autorest/azure/azure.go | 153 +++- .../autorest/azure/environments.go | 71 +- .../autorest/azure/metadata_environment.go | 245 ++++++ .../Azure/go-autorest/autorest/azure/rp.go | 200 +++++ .../Azure/go-autorest/autorest/client.go | 46 +- .../Azure/go-autorest/autorest/date/date.go | 14 + .../Azure/go-autorest/autorest/date/time.go | 14 + .../go-autorest/autorest/date/timerfc1123.go | 14 + .../go-autorest/autorest/date/unixtime.go | 14 + .../go-autorest/autorest/date/utility.go | 14 + .../Azure/go-autorest/autorest/error.go | 14 + .../Azure/go-autorest/autorest/preparer.go | 60 +- .../Azure/go-autorest/autorest/responder.go | 14 + .../go-autorest/autorest/retriablerequest.go | 14 + .../autorest/retriablerequest_1.7.go | 36 +- .../autorest/retriablerequest_1.8.go | 42 +- .../Azure/go-autorest/autorest/sender.go | 46 +- .../Azure/go-autorest/autorest/to/convert.go | 14 + .../Azure/go-autorest/autorest/utility.go | 98 ++- .../Azure/go-autorest/autorest/version.go | 43 +- vendor/github.com/dgrijalva/jwt-go/ecdsa.go | 1 + vendor/github.com/dgrijalva/jwt-go/errors.go | 6 +- vendor/github.com/dgrijalva/jwt-go/hmac.go | 3 +- vendor/github.com/dgrijalva/jwt-go/parser.go | 134 +-- vendor/github.com/dgrijalva/jwt-go/rsa.go | 5 +- .../github.com/dgrijalva/jwt-go/rsa_utils.go | 32 + .../github.com/xenolf/lego/acmev2/client.go | 10 +- .../github.com/xenolf/lego/acmev2/messages.go | 3 +- .../xenolf/lego/providers/dns/azure/azure.go | 17 +- .../dns/digitalocean/digitalocean.go | 4 +- 48 files changed, 2979 insertions(+), 1076 deletions(-) delete mode 100755 vendor/github.com/Azure/azure-sdk-for-go/arm/dns/models.go rename vendor/github.com/Azure/azure-sdk-for-go/{arm => services/dns/mgmt/2017-09-01}/dns/client.go (77%) mode change 100755 => 100644 create mode 100644 vendor/github.com/Azure/azure-sdk-for-go/services/dns/mgmt/2017-09-01/dns/models.go rename vendor/github.com/Azure/azure-sdk-for-go/{arm => services/dns/mgmt/2017-09-01}/dns/recordsets.go (66%) mode change 100755 => 100644 rename vendor/github.com/Azure/azure-sdk-for-go/{arm => services/dns/mgmt/2017-09-01}/dns/version.go (87%) mode change 100755 => 100644 rename vendor/github.com/Azure/azure-sdk-for-go/{arm => services/dns/mgmt/2017-09-01}/dns/zones.go (63%) mode change 100755 => 100644 create mode 100644 vendor/github.com/Azure/azure-sdk-for-go/version/version.go delete mode 100644 vendor/github.com/Azure/go-autorest/autorest/adal/msi.go delete mode 100644 vendor/github.com/Azure/go-autorest/autorest/adal/msi_windows.go create mode 100644 vendor/github.com/Azure/go-autorest/autorest/azure/metadata_environment.go create mode 100644 vendor/github.com/Azure/go-autorest/autorest/azure/rp.go diff --git a/Gopkg.lock b/Gopkg.lock index 133a63b46..1781467f7 100644 --- a/Gopkg.lock +++ b/Gopkg.lock @@ -24,8 +24,12 @@ [[projects]] name = "github.com/Azure/azure-sdk-for-go" - packages = ["arm/dns"] - revision = "f7bb4db3ea4c73dc58bd284c38ea644a79324be0" + packages = [ + "services/dns/mgmt/2017-09-01/dns", + "version" + ] + revision = "068ec4d616be5b2175509bf1fb3e4c8ea160d5c8" + version = "v15.0.1" [[projects]] branch = "master" @@ -45,8 +49,8 @@ "autorest/date", "autorest/to" ] - revision = "f6be1abbb5abd0517522f850dd785990d373da7e" - version = "v9.0.0" + revision = "9ad9326b278af8fa5cc67c30c0ce9a58cc0862b2" + version = "v10.6.0" [[projects]] branch = "master" @@ -312,8 +316,8 @@ [[projects]] name = "github.com/dgrijalva/jwt-go" packages = ["."] - revision = "d2709f9f1f31ebcda9651b03077758c1f3a0018c" - version = "v3.0.0" + revision = "06ea1031745cb8b3dab3f6a236daf2b0aa468b7e" + version = "v3.2.0" [[projects]] name = "github.com/dnsimple/dnsimple-go" @@ -1274,7 +1278,7 @@ "providers/dns/route53", "providers/dns/vultr" ] - revision = "2357607e4ddeb93d5364c9ae6571ded32b7d01f1" + revision = "2817d2131186742bc98830c73a5d9c255b3f4537" source = "github.com/containous/lego" [[projects]] diff --git a/vendor/github.com/Azure/azure-sdk-for-go/arm/dns/models.go b/vendor/github.com/Azure/azure-sdk-for-go/arm/dns/models.go deleted file mode 100755 index a81f49b8e..000000000 --- a/vendor/github.com/Azure/azure-sdk-for-go/arm/dns/models.go +++ /dev/null @@ -1,338 +0,0 @@ -package dns - -// Copyright (c) Microsoft and contributors. All rights reserved. -// -// 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. -// -// Code generated by Microsoft (R) AutoRest Code Generator. -// Changes may cause incorrect behavior and will be lost if the code is regenerated. - -import ( - "github.com/Azure/go-autorest/autorest" - "github.com/Azure/go-autorest/autorest/to" - "net/http" -) - -// HTTPStatusCode enumerates the values for http status code. -type HTTPStatusCode string - -const ( - // Accepted specifies the accepted state for http status code. - Accepted HTTPStatusCode = "Accepted" - // Ambiguous specifies the ambiguous state for http status code. - Ambiguous HTTPStatusCode = "Ambiguous" - // BadGateway specifies the bad gateway state for http status code. - BadGateway HTTPStatusCode = "BadGateway" - // BadRequest specifies the bad request state for http status code. - BadRequest HTTPStatusCode = "BadRequest" - // Conflict specifies the conflict state for http status code. - Conflict HTTPStatusCode = "Conflict" - // Continue specifies the continue state for http status code. - Continue HTTPStatusCode = "Continue" - // Created specifies the created state for http status code. - Created HTTPStatusCode = "Created" - // ExpectationFailed specifies the expectation failed state for http status code. - ExpectationFailed HTTPStatusCode = "ExpectationFailed" - // Forbidden specifies the forbidden state for http status code. - Forbidden HTTPStatusCode = "Forbidden" - // Found specifies the found state for http status code. - Found HTTPStatusCode = "Found" - // GatewayTimeout specifies the gateway timeout state for http status code. - GatewayTimeout HTTPStatusCode = "GatewayTimeout" - // Gone specifies the gone state for http status code. - Gone HTTPStatusCode = "Gone" - // HTTPVersionNotSupported specifies the http version not supported state for http status code. - HTTPVersionNotSupported HTTPStatusCode = "HttpVersionNotSupported" - // InternalServerError specifies the internal server error state for http status code. - InternalServerError HTTPStatusCode = "InternalServerError" - // LengthRequired specifies the length required state for http status code. - LengthRequired HTTPStatusCode = "LengthRequired" - // MethodNotAllowed specifies the method not allowed state for http status code. - MethodNotAllowed HTTPStatusCode = "MethodNotAllowed" - // Moved specifies the moved state for http status code. - Moved HTTPStatusCode = "Moved" - // MovedPermanently specifies the moved permanently state for http status code. - MovedPermanently HTTPStatusCode = "MovedPermanently" - // MultipleChoices specifies the multiple choices state for http status code. - MultipleChoices HTTPStatusCode = "MultipleChoices" - // NoContent specifies the no content state for http status code. - NoContent HTTPStatusCode = "NoContent" - // NonAuthoritativeInformation specifies the non authoritative information state for http status code. - NonAuthoritativeInformation HTTPStatusCode = "NonAuthoritativeInformation" - // NotAcceptable specifies the not acceptable state for http status code. - NotAcceptable HTTPStatusCode = "NotAcceptable" - // NotFound specifies the not found state for http status code. - NotFound HTTPStatusCode = "NotFound" - // NotImplemented specifies the not implemented state for http status code. - NotImplemented HTTPStatusCode = "NotImplemented" - // NotModified specifies the not modified state for http status code. - NotModified HTTPStatusCode = "NotModified" - // OK specifies the ok state for http status code. - OK HTTPStatusCode = "OK" - // PartialContent specifies the partial content state for http status code. - PartialContent HTTPStatusCode = "PartialContent" - // PaymentRequired specifies the payment required state for http status code. - PaymentRequired HTTPStatusCode = "PaymentRequired" - // PreconditionFailed specifies the precondition failed state for http status code. - PreconditionFailed HTTPStatusCode = "PreconditionFailed" - // ProxyAuthenticationRequired specifies the proxy authentication required state for http status code. - ProxyAuthenticationRequired HTTPStatusCode = "ProxyAuthenticationRequired" - // Redirect specifies the redirect state for http status code. - Redirect HTTPStatusCode = "Redirect" - // RedirectKeepVerb specifies the redirect keep verb state for http status code. - RedirectKeepVerb HTTPStatusCode = "RedirectKeepVerb" - // RedirectMethod specifies the redirect method state for http status code. - RedirectMethod HTTPStatusCode = "RedirectMethod" - // RequestedRangeNotSatisfiable specifies the requested range not satisfiable state for http status code. - RequestedRangeNotSatisfiable HTTPStatusCode = "RequestedRangeNotSatisfiable" - // RequestEntityTooLarge specifies the request entity too large state for http status code. - RequestEntityTooLarge HTTPStatusCode = "RequestEntityTooLarge" - // RequestTimeout specifies the request timeout state for http status code. - RequestTimeout HTTPStatusCode = "RequestTimeout" - // RequestURITooLong specifies the request uri too long state for http status code. - RequestURITooLong HTTPStatusCode = "RequestUriTooLong" - // ResetContent specifies the reset content state for http status code. - ResetContent HTTPStatusCode = "ResetContent" - // SeeOther specifies the see other state for http status code. - SeeOther HTTPStatusCode = "SeeOther" - // ServiceUnavailable specifies the service unavailable state for http status code. - ServiceUnavailable HTTPStatusCode = "ServiceUnavailable" - // SwitchingProtocols specifies the switching protocols state for http status code. - SwitchingProtocols HTTPStatusCode = "SwitchingProtocols" - // TemporaryRedirect specifies the temporary redirect state for http status code. - TemporaryRedirect HTTPStatusCode = "TemporaryRedirect" - // Unauthorized specifies the unauthorized state for http status code. - Unauthorized HTTPStatusCode = "Unauthorized" - // UnsupportedMediaType specifies the unsupported media type state for http status code. - UnsupportedMediaType HTTPStatusCode = "UnsupportedMediaType" - // Unused specifies the unused state for http status code. - Unused HTTPStatusCode = "Unused" - // UpgradeRequired specifies the upgrade required state for http status code. - UpgradeRequired HTTPStatusCode = "UpgradeRequired" - // UseProxy specifies the use proxy state for http status code. - UseProxy HTTPStatusCode = "UseProxy" -) - -// OperationStatus enumerates the values for operation status. -type OperationStatus string - -const ( - // Failed specifies the failed state for operation status. - Failed OperationStatus = "Failed" - // InProgress specifies the in progress state for operation status. - InProgress OperationStatus = "InProgress" - // Succeeded specifies the succeeded state for operation status. - Succeeded OperationStatus = "Succeeded" -) - -// RecordType enumerates the values for record type. -type RecordType string - -const ( - // A specifies the a state for record type. - A RecordType = "A" - // AAAA specifies the aaaa state for record type. - AAAA RecordType = "AAAA" - // CNAME specifies the cname state for record type. - CNAME RecordType = "CNAME" - // MX specifies the mx state for record type. - MX RecordType = "MX" - // NS specifies the ns state for record type. - NS RecordType = "NS" - // PTR specifies the ptr state for record type. - PTR RecordType = "PTR" - // SOA specifies the soa state for record type. - SOA RecordType = "SOA" - // SRV specifies the srv state for record type. - SRV RecordType = "SRV" - // TXT specifies the txt state for record type. - TXT RecordType = "TXT" -) - -// AaaaRecord is an AAAA record. -type AaaaRecord struct { - Ipv6Address *string `json:"ipv6Address,omitempty"` -} - -// ARecord is an A record. -type ARecord struct { - Ipv4Address *string `json:"ipv4Address,omitempty"` -} - -// CloudError is -type CloudError struct { - Error *CloudErrorBody `json:"error,omitempty"` -} - -// CloudErrorBody is -type CloudErrorBody struct { - Code *string `json:"code,omitempty"` - Message *string `json:"message,omitempty"` - Target *string `json:"target,omitempty"` - Details *[]CloudErrorBody `json:"details,omitempty"` -} - -// CnameRecord is a CNAME record. -type CnameRecord struct { - Cname *string `json:"cname,omitempty"` -} - -// MxRecord is an MX record. -type MxRecord struct { - Preference *int32 `json:"preference,omitempty"` - Exchange *string `json:"exchange,omitempty"` -} - -// NsRecord is an NS record. -type NsRecord struct { - Nsdname *string `json:"nsdname,omitempty"` -} - -// PtrRecord is a PTR record. -type PtrRecord struct { - Ptrdname *string `json:"ptrdname,omitempty"` -} - -// RecordSet is describes a DNS record set (a collection of DNS records with the same name and type). -type RecordSet struct { - autorest.Response `json:"-"` - ID *string `json:"id,omitempty"` - Name *string `json:"name,omitempty"` - Type *string `json:"type,omitempty"` - Etag *string `json:"etag,omitempty"` - *RecordSetProperties `json:"properties,omitempty"` -} - -// RecordSetListResult is the response to a record set List operation. -type RecordSetListResult struct { - autorest.Response `json:"-"` - Value *[]RecordSet `json:"value,omitempty"` - NextLink *string `json:"nextLink,omitempty"` -} - -// RecordSetListResultPreparer prepares a request to retrieve the next set of results. It returns -// nil if no more results exist. -func (client RecordSetListResult) RecordSetListResultPreparer() (*http.Request, error) { - if client.NextLink == nil || len(to.String(client.NextLink)) <= 0 { - return nil, nil - } - return autorest.Prepare(&http.Request{}, - autorest.AsJSON(), - autorest.AsGet(), - autorest.WithBaseURL(to.String(client.NextLink))) -} - -// RecordSetProperties is represents the properties of the records in the record set. -type RecordSetProperties struct { - Metadata *map[string]*string `json:"metadata,omitempty"` - TTL *int64 `json:"TTL,omitempty"` - ARecords *[]ARecord `json:"ARecords,omitempty"` - AaaaRecords *[]AaaaRecord `json:"AAAARecords,omitempty"` - MxRecords *[]MxRecord `json:"MXRecords,omitempty"` - NsRecords *[]NsRecord `json:"NSRecords,omitempty"` - PtrRecords *[]PtrRecord `json:"PTRRecords,omitempty"` - SrvRecords *[]SrvRecord `json:"SRVRecords,omitempty"` - TxtRecords *[]TxtRecord `json:"TXTRecords,omitempty"` - CnameRecord *CnameRecord `json:"CNAMERecord,omitempty"` - SoaRecord *SoaRecord `json:"SOARecord,omitempty"` -} - -// RecordSetUpdateParameters is parameters supplied to update a record set. -type RecordSetUpdateParameters struct { - RecordSet *RecordSet `json:"RecordSet,omitempty"` -} - -// Resource is -type Resource struct { - ID *string `json:"id,omitempty"` - Name *string `json:"name,omitempty"` - Type *string `json:"type,omitempty"` - Location *string `json:"location,omitempty"` - Tags *map[string]*string `json:"tags,omitempty"` -} - -// SoaRecord is an SOA record. -type SoaRecord struct { - Host *string `json:"host,omitempty"` - Email *string `json:"email,omitempty"` - SerialNumber *int64 `json:"serialNumber,omitempty"` - RefreshTime *int64 `json:"refreshTime,omitempty"` - RetryTime *int64 `json:"retryTime,omitempty"` - ExpireTime *int64 `json:"expireTime,omitempty"` - MinimumTTL *int64 `json:"minimumTTL,omitempty"` -} - -// SrvRecord is an SRV record. -type SrvRecord struct { - Priority *int32 `json:"priority,omitempty"` - Weight *int32 `json:"weight,omitempty"` - Port *int32 `json:"port,omitempty"` - Target *string `json:"target,omitempty"` -} - -// SubResource is -type SubResource struct { - ID *string `json:"id,omitempty"` -} - -// TxtRecord is a TXT record. -type TxtRecord struct { - Value *[]string `json:"value,omitempty"` -} - -// Zone is describes a DNS zone. -type Zone struct { - autorest.Response `json:"-"` - ID *string `json:"id,omitempty"` - Name *string `json:"name,omitempty"` - Type *string `json:"type,omitempty"` - Location *string `json:"location,omitempty"` - Tags *map[string]*string `json:"tags,omitempty"` - Etag *string `json:"etag,omitempty"` - *ZoneProperties `json:"properties,omitempty"` -} - -// ZoneDeleteResult is the response to a Zone Delete operation. -type ZoneDeleteResult struct { - autorest.Response `json:"-"` - AzureAsyncOperation *string `json:"azureAsyncOperation,omitempty"` - Status OperationStatus `json:"status,omitempty"` - StatusCode HTTPStatusCode `json:"statusCode,omitempty"` - RequestID *string `json:"requestId,omitempty"` -} - -// ZoneListResult is the response to a Zone List or ListAll operation. -type ZoneListResult struct { - autorest.Response `json:"-"` - Value *[]Zone `json:"value,omitempty"` - NextLink *string `json:"nextLink,omitempty"` -} - -// ZoneListResultPreparer prepares a request to retrieve the next set of results. It returns -// nil if no more results exist. -func (client ZoneListResult) ZoneListResultPreparer() (*http.Request, error) { - if client.NextLink == nil || len(to.String(client.NextLink)) <= 0 { - return nil, nil - } - return autorest.Prepare(&http.Request{}, - autorest.AsJSON(), - autorest.AsGet(), - autorest.WithBaseURL(to.String(client.NextLink))) -} - -// ZoneProperties is represents the properties of the zone. -type ZoneProperties struct { - MaxNumberOfRecordSets *int64 `json:"maxNumberOfRecordSets,omitempty"` - NumberOfRecordSets *int64 `json:"numberOfRecordSets,omitempty"` - NameServers *[]string `json:"nameServers,omitempty"` -} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/arm/dns/client.go b/vendor/github.com/Azure/azure-sdk-for-go/services/dns/mgmt/2017-09-01/dns/client.go old mode 100755 new mode 100644 similarity index 77% rename from vendor/github.com/Azure/azure-sdk-for-go/arm/dns/client.go rename to vendor/github.com/Azure/azure-sdk-for-go/services/dns/mgmt/2017-09-01/dns/client.go index 714b698b5..482d2f943 --- a/vendor/github.com/Azure/azure-sdk-for-go/arm/dns/client.go +++ b/vendor/github.com/Azure/azure-sdk-for-go/services/dns/mgmt/2017-09-01/dns/client.go @@ -1,4 +1,4 @@ -// Package dns implements the Azure ARM Dns service API version 2016-04-01. +// Package dns implements the Azure ARM Dns service API version 2017-09-01. // // The DNS Management Client. package dns @@ -29,21 +29,21 @@ const ( DefaultBaseURI = "https://management.azure.com" ) -// ManagementClient is the base client for Dns. -type ManagementClient struct { +// BaseClient is the base client for Dns. +type BaseClient struct { autorest.Client BaseURI string SubscriptionID string } -// New creates an instance of the ManagementClient client. -func New(subscriptionID string) ManagementClient { +// New creates an instance of the BaseClient client. +func New(subscriptionID string) BaseClient { return NewWithBaseURI(DefaultBaseURI, subscriptionID) } -// NewWithBaseURI creates an instance of the ManagementClient client. -func NewWithBaseURI(baseURI string, subscriptionID string) ManagementClient { - return ManagementClient{ +// NewWithBaseURI creates an instance of the BaseClient client. +func NewWithBaseURI(baseURI string, subscriptionID string) BaseClient { + return BaseClient{ Client: autorest.NewClientWithUserAgent(UserAgent()), BaseURI: baseURI, SubscriptionID: subscriptionID, diff --git a/vendor/github.com/Azure/azure-sdk-for-go/services/dns/mgmt/2017-09-01/dns/models.go b/vendor/github.com/Azure/azure-sdk-for-go/services/dns/mgmt/2017-09-01/dns/models.go new file mode 100644 index 000000000..53d57a6ad --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/services/dns/mgmt/2017-09-01/dns/models.go @@ -0,0 +1,763 @@ +package dns + +// Copyright (c) Microsoft and contributors. All rights reserved. +// +// 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. +// +// Code generated by Microsoft (R) AutoRest Code Generator. +// Changes may cause incorrect behavior and will be lost if the code is regenerated. + +import ( + "encoding/json" + "github.com/Azure/go-autorest/autorest" + "github.com/Azure/go-autorest/autorest/azure" + "github.com/Azure/go-autorest/autorest/to" + "net/http" +) + +// RecordType enumerates the values for record type. +type RecordType string + +const ( + // A ... + A RecordType = "A" + // AAAA ... + AAAA RecordType = "AAAA" + // CAA ... + CAA RecordType = "CAA" + // CNAME ... + CNAME RecordType = "CNAME" + // MX ... + MX RecordType = "MX" + // NS ... + NS RecordType = "NS" + // PTR ... + PTR RecordType = "PTR" + // SOA ... + SOA RecordType = "SOA" + // SRV ... + SRV RecordType = "SRV" + // TXT ... + TXT RecordType = "TXT" +) + +// PossibleRecordTypeValues returns an array of possible values for the RecordType const type. +func PossibleRecordTypeValues() []RecordType { + return []RecordType{A, AAAA, CAA, CNAME, MX, NS, PTR, SOA, SRV, TXT} +} + +// AaaaRecord an AAAA record. +type AaaaRecord struct { + // Ipv6Address - The IPv6 address of this AAAA record. + Ipv6Address *string `json:"ipv6Address,omitempty"` +} + +// ARecord an A record. +type ARecord struct { + // Ipv4Address - The IPv4 address of this A record. + Ipv4Address *string `json:"ipv4Address,omitempty"` +} + +// CaaRecord a CAA record. +type CaaRecord struct { + // Flags - The flags for this CAA record as an integer between 0 and 255. + Flags *int32 `json:"flags,omitempty"` + // Tag - The tag for this CAA record. + Tag *string `json:"tag,omitempty"` + // Value - The value for this CAA record. + Value *string `json:"value,omitempty"` +} + +// CloudError an error message +type CloudError struct { + // Error - The error message body + Error *CloudErrorBody `json:"error,omitempty"` +} + +// CloudErrorBody the body of an error message +type CloudErrorBody struct { + // Code - The error code + Code *string `json:"code,omitempty"` + // Message - A description of what caused the error + Message *string `json:"message,omitempty"` + // Target - The target resource of the error message + Target *string `json:"target,omitempty"` + // Details - Extra error information + Details *[]CloudErrorBody `json:"details,omitempty"` +} + +// CnameRecord a CNAME record. +type CnameRecord struct { + // Cname - The canonical name for this CNAME record. + Cname *string `json:"cname,omitempty"` +} + +// MxRecord an MX record. +type MxRecord struct { + // Preference - The preference value for this MX record. + Preference *int32 `json:"preference,omitempty"` + // Exchange - The domain name of the mail host for this MX record. + Exchange *string `json:"exchange,omitempty"` +} + +// NsRecord an NS record. +type NsRecord struct { + // Nsdname - The name server name for this NS record. + Nsdname *string `json:"nsdname,omitempty"` +} + +// PtrRecord a PTR record. +type PtrRecord struct { + // Ptrdname - The PTR target domain name for this PTR record. + Ptrdname *string `json:"ptrdname,omitempty"` +} + +// RecordSet describes a DNS record set (a collection of DNS records with the same name and type). +type RecordSet struct { + autorest.Response `json:"-"` + // ID - The ID of the record set. + ID *string `json:"id,omitempty"` + // Name - The name of the record set. + Name *string `json:"name,omitempty"` + // Type - The type of the record set. + Type *string `json:"type,omitempty"` + // Etag - The etag of the record set. + Etag *string `json:"etag,omitempty"` + // RecordSetProperties - The properties of the record set. + *RecordSetProperties `json:"properties,omitempty"` +} + +// MarshalJSON is the custom marshaler for RecordSet. +func (rs RecordSet) MarshalJSON() ([]byte, error) { + objectMap := make(map[string]interface{}) + if rs.ID != nil { + objectMap["id"] = rs.ID + } + if rs.Name != nil { + objectMap["name"] = rs.Name + } + if rs.Type != nil { + objectMap["type"] = rs.Type + } + if rs.Etag != nil { + objectMap["etag"] = rs.Etag + } + if rs.RecordSetProperties != nil { + objectMap["properties"] = rs.RecordSetProperties + } + return json.Marshal(objectMap) +} + +// UnmarshalJSON is the custom unmarshaler for RecordSet struct. +func (rs *RecordSet) UnmarshalJSON(body []byte) error { + var m map[string]*json.RawMessage + err := json.Unmarshal(body, &m) + if err != nil { + return err + } + for k, v := range m { + switch k { + case "id": + if v != nil { + var ID string + err = json.Unmarshal(*v, &ID) + if err != nil { + return err + } + rs.ID = &ID + } + case "name": + if v != nil { + var name string + err = json.Unmarshal(*v, &name) + if err != nil { + return err + } + rs.Name = &name + } + case "type": + if v != nil { + var typeVar string + err = json.Unmarshal(*v, &typeVar) + if err != nil { + return err + } + rs.Type = &typeVar + } + case "etag": + if v != nil { + var etag string + err = json.Unmarshal(*v, &etag) + if err != nil { + return err + } + rs.Etag = &etag + } + case "properties": + if v != nil { + var recordSetProperties RecordSetProperties + err = json.Unmarshal(*v, &recordSetProperties) + if err != nil { + return err + } + rs.RecordSetProperties = &recordSetProperties + } + } + } + + return nil +} + +// RecordSetListResult the response to a record set List operation. +type RecordSetListResult struct { + autorest.Response `json:"-"` + // Value - Information about the record sets in the response. + Value *[]RecordSet `json:"value,omitempty"` + // NextLink - The continuation token for the next page of results. + NextLink *string `json:"nextLink,omitempty"` +} + +// RecordSetListResultIterator provides access to a complete listing of RecordSet values. +type RecordSetListResultIterator struct { + i int + page RecordSetListResultPage +} + +// Next advances to the next value. If there was an error making +// the request the iterator does not advance and the error is returned. +func (iter *RecordSetListResultIterator) Next() error { + iter.i++ + if iter.i < len(iter.page.Values()) { + return nil + } + err := iter.page.Next() + if err != nil { + iter.i-- + return err + } + iter.i = 0 + return nil +} + +// NotDone returns true if the enumeration should be started or is not yet complete. +func (iter RecordSetListResultIterator) NotDone() bool { + return iter.page.NotDone() && iter.i < len(iter.page.Values()) +} + +// Response returns the raw server response from the last page request. +func (iter RecordSetListResultIterator) Response() RecordSetListResult { + return iter.page.Response() +} + +// Value returns the current value or a zero-initialized value if the +// iterator has advanced beyond the end of the collection. +func (iter RecordSetListResultIterator) Value() RecordSet { + if !iter.page.NotDone() { + return RecordSet{} + } + return iter.page.Values()[iter.i] +} + +// IsEmpty returns true if the ListResult contains no values. +func (rslr RecordSetListResult) IsEmpty() bool { + return rslr.Value == nil || len(*rslr.Value) == 0 +} + +// recordSetListResultPreparer prepares a request to retrieve the next set of results. +// It returns nil if no more results exist. +func (rslr RecordSetListResult) recordSetListResultPreparer() (*http.Request, error) { + if rslr.NextLink == nil || len(to.String(rslr.NextLink)) < 1 { + return nil, nil + } + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsGet(), + autorest.WithBaseURL(to.String(rslr.NextLink))) +} + +// RecordSetListResultPage contains a page of RecordSet values. +type RecordSetListResultPage struct { + fn func(RecordSetListResult) (RecordSetListResult, error) + rslr RecordSetListResult +} + +// Next advances to the next page of values. If there was an error making +// the request the page does not advance and the error is returned. +func (page *RecordSetListResultPage) Next() error { + next, err := page.fn(page.rslr) + if err != nil { + return err + } + page.rslr = next + return nil +} + +// NotDone returns true if the page enumeration should be started or is not yet complete. +func (page RecordSetListResultPage) NotDone() bool { + return !page.rslr.IsEmpty() +} + +// Response returns the raw server response from the last page request. +func (page RecordSetListResultPage) Response() RecordSetListResult { + return page.rslr +} + +// Values returns the slice of values for the current page or nil if there are no values. +func (page RecordSetListResultPage) Values() []RecordSet { + if page.rslr.IsEmpty() { + return nil + } + return *page.rslr.Value +} + +// RecordSetProperties represents the properties of the records in the record set. +type RecordSetProperties struct { + // Metadata - The metadata attached to the record set. + Metadata map[string]*string `json:"metadata"` + // TTL - The TTL (time-to-live) of the records in the record set. + TTL *int64 `json:"TTL,omitempty"` + // Fqdn - Fully qualified domain name of the record set. + Fqdn *string `json:"fqdn,omitempty"` + // ARecords - The list of A records in the record set. + ARecords *[]ARecord `json:"ARecords,omitempty"` + // AaaaRecords - The list of AAAA records in the record set. + AaaaRecords *[]AaaaRecord `json:"AAAARecords,omitempty"` + // MxRecords - The list of MX records in the record set. + MxRecords *[]MxRecord `json:"MXRecords,omitempty"` + // NsRecords - The list of NS records in the record set. + NsRecords *[]NsRecord `json:"NSRecords,omitempty"` + // PtrRecords - The list of PTR records in the record set. + PtrRecords *[]PtrRecord `json:"PTRRecords,omitempty"` + // SrvRecords - The list of SRV records in the record set. + SrvRecords *[]SrvRecord `json:"SRVRecords,omitempty"` + // TxtRecords - The list of TXT records in the record set. + TxtRecords *[]TxtRecord `json:"TXTRecords,omitempty"` + // CnameRecord - The CNAME record in the record set. + CnameRecord *CnameRecord `json:"CNAMERecord,omitempty"` + // SoaRecord - The SOA record in the record set. + SoaRecord *SoaRecord `json:"SOARecord,omitempty"` + // CaaRecords - The list of CAA records in the record set. + CaaRecords *[]CaaRecord `json:"caaRecords,omitempty"` +} + +// MarshalJSON is the custom marshaler for RecordSetProperties. +func (rsp RecordSetProperties) MarshalJSON() ([]byte, error) { + objectMap := make(map[string]interface{}) + if rsp.Metadata != nil { + objectMap["metadata"] = rsp.Metadata + } + if rsp.TTL != nil { + objectMap["TTL"] = rsp.TTL + } + if rsp.Fqdn != nil { + objectMap["fqdn"] = rsp.Fqdn + } + if rsp.ARecords != nil { + objectMap["ARecords"] = rsp.ARecords + } + if rsp.AaaaRecords != nil { + objectMap["AAAARecords"] = rsp.AaaaRecords + } + if rsp.MxRecords != nil { + objectMap["MXRecords"] = rsp.MxRecords + } + if rsp.NsRecords != nil { + objectMap["NSRecords"] = rsp.NsRecords + } + if rsp.PtrRecords != nil { + objectMap["PTRRecords"] = rsp.PtrRecords + } + if rsp.SrvRecords != nil { + objectMap["SRVRecords"] = rsp.SrvRecords + } + if rsp.TxtRecords != nil { + objectMap["TXTRecords"] = rsp.TxtRecords + } + if rsp.CnameRecord != nil { + objectMap["CNAMERecord"] = rsp.CnameRecord + } + if rsp.SoaRecord != nil { + objectMap["SOARecord"] = rsp.SoaRecord + } + if rsp.CaaRecords != nil { + objectMap["caaRecords"] = rsp.CaaRecords + } + return json.Marshal(objectMap) +} + +// RecordSetUpdateParameters parameters supplied to update a record set. +type RecordSetUpdateParameters struct { + // RecordSet - Specifies information about the record set being updated. + RecordSet *RecordSet `json:"RecordSet,omitempty"` +} + +// Resource common properties of an Azure Resource Manager resource +type Resource struct { + // ID - Resource ID. + ID *string `json:"id,omitempty"` + // Name - Resource name. + Name *string `json:"name,omitempty"` + // Type - Resource type. + Type *string `json:"type,omitempty"` + // Location - Resource location. + Location *string `json:"location,omitempty"` + // Tags - Resource tags. + Tags map[string]*string `json:"tags"` +} + +// MarshalJSON is the custom marshaler for Resource. +func (r Resource) MarshalJSON() ([]byte, error) { + objectMap := make(map[string]interface{}) + if r.ID != nil { + objectMap["id"] = r.ID + } + if r.Name != nil { + objectMap["name"] = r.Name + } + if r.Type != nil { + objectMap["type"] = r.Type + } + if r.Location != nil { + objectMap["location"] = r.Location + } + if r.Tags != nil { + objectMap["tags"] = r.Tags + } + return json.Marshal(objectMap) +} + +// SoaRecord an SOA record. +type SoaRecord struct { + // Host - The domain name of the authoritative name server for this SOA record. + Host *string `json:"host,omitempty"` + // Email - The email contact for this SOA record. + Email *string `json:"email,omitempty"` + // SerialNumber - The serial number for this SOA record. + SerialNumber *int64 `json:"serialNumber,omitempty"` + // RefreshTime - The refresh value for this SOA record. + RefreshTime *int64 `json:"refreshTime,omitempty"` + // RetryTime - The retry time for this SOA record. + RetryTime *int64 `json:"retryTime,omitempty"` + // ExpireTime - The expire time for this SOA record. + ExpireTime *int64 `json:"expireTime,omitempty"` + // MinimumTTL - The minimum value for this SOA record. By convention this is used to determine the negative caching duration. + MinimumTTL *int64 `json:"minimumTTL,omitempty"` +} + +// SrvRecord an SRV record. +type SrvRecord struct { + // Priority - The priority value for this SRV record. + Priority *int32 `json:"priority,omitempty"` + // Weight - The weight value for this SRV record. + Weight *int32 `json:"weight,omitempty"` + // Port - The port value for this SRV record. + Port *int32 `json:"port,omitempty"` + // Target - The target domain name for this SRV record. + Target *string `json:"target,omitempty"` +} + +// SubResource a reference to a another resource +type SubResource struct { + // ID - Resource Id. + ID *string `json:"id,omitempty"` +} + +// TxtRecord a TXT record. +type TxtRecord struct { + // Value - The text value of this TXT record. + Value *[]string `json:"value,omitempty"` +} + +// Zone describes a DNS zone. +type Zone struct { + autorest.Response `json:"-"` + // Etag - The etag of the zone. + Etag *string `json:"etag,omitempty"` + // ZoneProperties - The properties of the zone. + *ZoneProperties `json:"properties,omitempty"` + // ID - Resource ID. + ID *string `json:"id,omitempty"` + // Name - Resource name. + Name *string `json:"name,omitempty"` + // Type - Resource type. + Type *string `json:"type,omitempty"` + // Location - Resource location. + Location *string `json:"location,omitempty"` + // Tags - Resource tags. + Tags map[string]*string `json:"tags"` +} + +// MarshalJSON is the custom marshaler for Zone. +func (z Zone) MarshalJSON() ([]byte, error) { + objectMap := make(map[string]interface{}) + if z.Etag != nil { + objectMap["etag"] = z.Etag + } + if z.ZoneProperties != nil { + objectMap["properties"] = z.ZoneProperties + } + if z.ID != nil { + objectMap["id"] = z.ID + } + if z.Name != nil { + objectMap["name"] = z.Name + } + if z.Type != nil { + objectMap["type"] = z.Type + } + if z.Location != nil { + objectMap["location"] = z.Location + } + if z.Tags != nil { + objectMap["tags"] = z.Tags + } + return json.Marshal(objectMap) +} + +// UnmarshalJSON is the custom unmarshaler for Zone struct. +func (z *Zone) UnmarshalJSON(body []byte) error { + var m map[string]*json.RawMessage + err := json.Unmarshal(body, &m) + if err != nil { + return err + } + for k, v := range m { + switch k { + case "etag": + if v != nil { + var etag string + err = json.Unmarshal(*v, &etag) + if err != nil { + return err + } + z.Etag = &etag + } + case "properties": + if v != nil { + var zoneProperties ZoneProperties + err = json.Unmarshal(*v, &zoneProperties) + if err != nil { + return err + } + z.ZoneProperties = &zoneProperties + } + case "id": + if v != nil { + var ID string + err = json.Unmarshal(*v, &ID) + if err != nil { + return err + } + z.ID = &ID + } + case "name": + if v != nil { + var name string + err = json.Unmarshal(*v, &name) + if err != nil { + return err + } + z.Name = &name + } + case "type": + if v != nil { + var typeVar string + err = json.Unmarshal(*v, &typeVar) + if err != nil { + return err + } + z.Type = &typeVar + } + case "location": + if v != nil { + var location string + err = json.Unmarshal(*v, &location) + if err != nil { + return err + } + z.Location = &location + } + case "tags": + if v != nil { + var tags map[string]*string + err = json.Unmarshal(*v, &tags) + if err != nil { + return err + } + z.Tags = tags + } + } + } + + return nil +} + +// ZoneListResult the response to a Zone List or ListAll operation. +type ZoneListResult struct { + autorest.Response `json:"-"` + // Value - Information about the DNS zones. + Value *[]Zone `json:"value,omitempty"` + // NextLink - The continuation token for the next page of results. + NextLink *string `json:"nextLink,omitempty"` +} + +// ZoneListResultIterator provides access to a complete listing of Zone values. +type ZoneListResultIterator struct { + i int + page ZoneListResultPage +} + +// Next advances to the next value. If there was an error making +// the request the iterator does not advance and the error is returned. +func (iter *ZoneListResultIterator) Next() error { + iter.i++ + if iter.i < len(iter.page.Values()) { + return nil + } + err := iter.page.Next() + if err != nil { + iter.i-- + return err + } + iter.i = 0 + return nil +} + +// NotDone returns true if the enumeration should be started or is not yet complete. +func (iter ZoneListResultIterator) NotDone() bool { + return iter.page.NotDone() && iter.i < len(iter.page.Values()) +} + +// Response returns the raw server response from the last page request. +func (iter ZoneListResultIterator) Response() ZoneListResult { + return iter.page.Response() +} + +// Value returns the current value or a zero-initialized value if the +// iterator has advanced beyond the end of the collection. +func (iter ZoneListResultIterator) Value() Zone { + if !iter.page.NotDone() { + return Zone{} + } + return iter.page.Values()[iter.i] +} + +// IsEmpty returns true if the ListResult contains no values. +func (zlr ZoneListResult) IsEmpty() bool { + return zlr.Value == nil || len(*zlr.Value) == 0 +} + +// zoneListResultPreparer prepares a request to retrieve the next set of results. +// It returns nil if no more results exist. +func (zlr ZoneListResult) zoneListResultPreparer() (*http.Request, error) { + if zlr.NextLink == nil || len(to.String(zlr.NextLink)) < 1 { + return nil, nil + } + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsGet(), + autorest.WithBaseURL(to.String(zlr.NextLink))) +} + +// ZoneListResultPage contains a page of Zone values. +type ZoneListResultPage struct { + fn func(ZoneListResult) (ZoneListResult, error) + zlr ZoneListResult +} + +// Next advances to the next page of values. If there was an error making +// the request the page does not advance and the error is returned. +func (page *ZoneListResultPage) Next() error { + next, err := page.fn(page.zlr) + if err != nil { + return err + } + page.zlr = next + return nil +} + +// NotDone returns true if the page enumeration should be started or is not yet complete. +func (page ZoneListResultPage) NotDone() bool { + return !page.zlr.IsEmpty() +} + +// Response returns the raw server response from the last page request. +func (page ZoneListResultPage) Response() ZoneListResult { + return page.zlr +} + +// Values returns the slice of values for the current page or nil if there are no values. +func (page ZoneListResultPage) Values() []Zone { + if page.zlr.IsEmpty() { + return nil + } + return *page.zlr.Value +} + +// ZoneProperties represents the properties of the zone. +type ZoneProperties struct { + // MaxNumberOfRecordSets - The maximum number of record sets that can be created in this DNS zone. This is a read-only property and any attempt to set this value will be ignored. + MaxNumberOfRecordSets *int64 `json:"maxNumberOfRecordSets,omitempty"` + // NumberOfRecordSets - The current number of record sets in this DNS zone. This is a read-only property and any attempt to set this value will be ignored. + NumberOfRecordSets *int64 `json:"numberOfRecordSets,omitempty"` + // NameServers - The name servers for this DNS zone. This is a read-only property and any attempt to set this value will be ignored. + NameServers *[]string `json:"nameServers,omitempty"` +} + +// ZonesDeleteFuture an abstraction for monitoring and retrieving the results of a long-running operation. +type ZonesDeleteFuture struct { + azure.Future + req *http.Request +} + +// Result returns the result of the asynchronous operation. +// If the operation has not completed it will return an error. +func (future ZonesDeleteFuture) Result(client ZonesClient) (ar autorest.Response, err error) { + var done bool + done, err = future.Done(client) + if err != nil { + err = autorest.NewErrorWithError(err, "dns.ZonesDeleteFuture", "Result", future.Response(), "Polling failure") + return + } + if !done { + return ar, azure.NewAsyncOpIncompleteError("dns.ZonesDeleteFuture") + } + if future.PollingMethod() == azure.PollingLocation { + ar, err = client.DeleteResponder(future.Response()) + if err != nil { + err = autorest.NewErrorWithError(err, "dns.ZonesDeleteFuture", "Result", future.Response(), "Failure responding to request") + } + return + } + var req *http.Request + var resp *http.Response + if future.PollingURL() != "" { + req, err = http.NewRequest(http.MethodGet, future.PollingURL(), nil) + if err != nil { + return + } + } else { + req = autorest.ChangeToGet(future.req) + } + resp, err = autorest.SendWithSender(client, req, + autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) + if err != nil { + err = autorest.NewErrorWithError(err, "dns.ZonesDeleteFuture", "Result", resp, "Failure sending request") + return + } + ar, err = client.DeleteResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "dns.ZonesDeleteFuture", "Result", resp, "Failure responding to request") + } + return +} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/arm/dns/recordsets.go b/vendor/github.com/Azure/azure-sdk-for-go/services/dns/mgmt/2017-09-01/dns/recordsets.go old mode 100755 new mode 100644 similarity index 66% rename from vendor/github.com/Azure/azure-sdk-for-go/arm/dns/recordsets.go rename to vendor/github.com/Azure/azure-sdk-for-go/services/dns/mgmt/2017-09-01/dns/recordsets.go index 8d59929f7..45ea7a8c8 --- a/vendor/github.com/Azure/azure-sdk-for-go/arm/dns/recordsets.go +++ b/vendor/github.com/Azure/azure-sdk-for-go/services/dns/mgmt/2017-09-01/dns/recordsets.go @@ -18,6 +18,7 @@ package dns // Changes may cause incorrect behavior and will be lost if the code is regenerated. import ( + "context" "github.com/Azure/go-autorest/autorest" "github.com/Azure/go-autorest/autorest/azure" "net/http" @@ -25,7 +26,7 @@ import ( // RecordSetsClient is the the DNS Management Client. type RecordSetsClient struct { - ManagementClient + BaseClient } // NewRecordSetsClient creates an instance of the RecordSetsClient client. @@ -41,14 +42,14 @@ func NewRecordSetsClientWithBaseURI(baseURI string, subscriptionID string) Recor // CreateOrUpdate creates or updates a record set within a DNS zone. // // resourceGroupName is the name of the resource group. zoneName is the name of the DNS zone (without a terminating -// dot). relativeRecordSetName is the name of the record set, relative to the name of the zone. recordType is the type -// of DNS record in this record set. Record sets of type SOA can be updated but not created (they are created when the -// DNS zone is created). parameters is parameters supplied to the CreateOrUpdate operation. ifMatch is the etag of the -// record set. Omit this value to always overwrite the current record set. Specify the last-seen etag value to prevent -// accidentally overwritting any concurrent changes. ifNoneMatch is set to '*' to allow a new record set to be created, -// but to prevent updating an existing record set. Other values will be ignored. -func (client RecordSetsClient) CreateOrUpdate(resourceGroupName string, zoneName string, relativeRecordSetName string, recordType RecordType, parameters RecordSet, ifMatch string, ifNoneMatch string) (result RecordSet, err error) { - req, err := client.CreateOrUpdatePreparer(resourceGroupName, zoneName, relativeRecordSetName, recordType, parameters, ifMatch, ifNoneMatch) +// dot). relativeRecordSetName is the name of the record set, relative to the name of the zone. recordType is the +// type of DNS record in this record set. Record sets of type SOA can be updated but not created (they are created +// when the DNS zone is created). parameters is parameters supplied to the CreateOrUpdate operation. ifMatch is the +// etag of the record set. Omit this value to always overwrite the current record set. Specify the last-seen etag +// value to prevent accidentally overwritting any concurrent changes. ifNoneMatch is set to '*' to allow a new +// record set to be created, but to prevent updating an existing record set. Other values will be ignored. +func (client RecordSetsClient) CreateOrUpdate(ctx context.Context, resourceGroupName string, zoneName string, relativeRecordSetName string, recordType RecordType, parameters RecordSet, ifMatch string, ifNoneMatch string) (result RecordSet, err error) { + req, err := client.CreateOrUpdatePreparer(ctx, resourceGroupName, zoneName, relativeRecordSetName, recordType, parameters, ifMatch, ifNoneMatch) if err != nil { err = autorest.NewErrorWithError(err, "dns.RecordSetsClient", "CreateOrUpdate", nil, "Failure preparing request") return @@ -70,7 +71,7 @@ func (client RecordSetsClient) CreateOrUpdate(resourceGroupName string, zoneName } // CreateOrUpdatePreparer prepares the CreateOrUpdate request. -func (client RecordSetsClient) CreateOrUpdatePreparer(resourceGroupName string, zoneName string, relativeRecordSetName string, recordType RecordType, parameters RecordSet, ifMatch string, ifNoneMatch string) (*http.Request, error) { +func (client RecordSetsClient) CreateOrUpdatePreparer(ctx context.Context, resourceGroupName string, zoneName string, relativeRecordSetName string, recordType RecordType, parameters RecordSet, ifMatch string, ifNoneMatch string) (*http.Request, error) { pathParameters := map[string]interface{}{ "recordType": autorest.Encode("path", recordType), "relativeRecordSetName": relativeRecordSetName, @@ -79,13 +80,13 @@ func (client RecordSetsClient) CreateOrUpdatePreparer(resourceGroupName string, "zoneName": autorest.Encode("path", zoneName), } - const APIVersion = "2016-04-01" + const APIVersion = "2017-09-01" queryParameters := map[string]interface{}{ "api-version": APIVersion, } preparer := autorest.CreatePreparer( - autorest.AsJSON(), + autorest.AsContentType("application/json; charset=utf-8"), autorest.AsPut(), autorest.WithBaseURL(client.BaseURI), autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Network/dnsZones/{zoneName}/{recordType}/{relativeRecordSetName}", pathParameters), @@ -99,13 +100,14 @@ func (client RecordSetsClient) CreateOrUpdatePreparer(resourceGroupName string, preparer = autorest.DecoratePreparer(preparer, autorest.WithHeader("If-None-Match", autorest.String(ifNoneMatch))) } - return preparer.Prepare(&http.Request{}) + return preparer.Prepare((&http.Request{}).WithContext(ctx)) } // CreateOrUpdateSender sends the CreateOrUpdate request. The method will close the // http.Response Body if it receives an error. func (client RecordSetsClient) CreateOrUpdateSender(req *http.Request) (*http.Response, error) { - return autorest.SendWithSender(client, req) + return autorest.SendWithSender(client, req, + azure.DoRetryWithRegistration(client.Client)) } // CreateOrUpdateResponder handles the response to the CreateOrUpdate request. The method always @@ -114,7 +116,7 @@ func (client RecordSetsClient) CreateOrUpdateResponder(resp *http.Response) (res err = autorest.Respond( resp, client.ByInspecting(), - azure.WithErrorUnlessStatusCode(http.StatusCreated, http.StatusOK), + azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusCreated), autorest.ByUnmarshallingJSON(&result), autorest.ByClosing()) result.Response = autorest.Response{Response: resp} @@ -124,12 +126,12 @@ func (client RecordSetsClient) CreateOrUpdateResponder(resp *http.Response) (res // Delete deletes a record set from a DNS zone. This operation cannot be undone. // // resourceGroupName is the name of the resource group. zoneName is the name of the DNS zone (without a terminating -// dot). relativeRecordSetName is the name of the record set, relative to the name of the zone. recordType is the type -// of DNS record in this record set. Record sets of type SOA cannot be deleted (they are deleted when the DNS zone is -// deleted). ifMatch is the etag of the record set. Omit this value to always delete the current record set. Specify -// the last-seen etag value to prevent accidentally deleting any concurrent changes. -func (client RecordSetsClient) Delete(resourceGroupName string, zoneName string, relativeRecordSetName string, recordType RecordType, ifMatch string) (result autorest.Response, err error) { - req, err := client.DeletePreparer(resourceGroupName, zoneName, relativeRecordSetName, recordType, ifMatch) +// dot). relativeRecordSetName is the name of the record set, relative to the name of the zone. recordType is the +// type of DNS record in this record set. Record sets of type SOA cannot be deleted (they are deleted when the DNS +// zone is deleted). ifMatch is the etag of the record set. Omit this value to always delete the current record +// set. Specify the last-seen etag value to prevent accidentally deleting any concurrent changes. +func (client RecordSetsClient) Delete(ctx context.Context, resourceGroupName string, zoneName string, relativeRecordSetName string, recordType RecordType, ifMatch string) (result autorest.Response, err error) { + req, err := client.DeletePreparer(ctx, resourceGroupName, zoneName, relativeRecordSetName, recordType, ifMatch) if err != nil { err = autorest.NewErrorWithError(err, "dns.RecordSetsClient", "Delete", nil, "Failure preparing request") return @@ -151,7 +153,7 @@ func (client RecordSetsClient) Delete(resourceGroupName string, zoneName string, } // DeletePreparer prepares the Delete request. -func (client RecordSetsClient) DeletePreparer(resourceGroupName string, zoneName string, relativeRecordSetName string, recordType RecordType, ifMatch string) (*http.Request, error) { +func (client RecordSetsClient) DeletePreparer(ctx context.Context, resourceGroupName string, zoneName string, relativeRecordSetName string, recordType RecordType, ifMatch string) (*http.Request, error) { pathParameters := map[string]interface{}{ "recordType": autorest.Encode("path", recordType), "relativeRecordSetName": relativeRecordSetName, @@ -160,7 +162,7 @@ func (client RecordSetsClient) DeletePreparer(resourceGroupName string, zoneName "zoneName": autorest.Encode("path", zoneName), } - const APIVersion = "2016-04-01" + const APIVersion = "2017-09-01" queryParameters := map[string]interface{}{ "api-version": APIVersion, } @@ -174,13 +176,14 @@ func (client RecordSetsClient) DeletePreparer(resourceGroupName string, zoneName preparer = autorest.DecoratePreparer(preparer, autorest.WithHeader("If-Match", autorest.String(ifMatch))) } - return preparer.Prepare(&http.Request{}) + return preparer.Prepare((&http.Request{}).WithContext(ctx)) } // DeleteSender sends the Delete request. The method will close the // http.Response Body if it receives an error. func (client RecordSetsClient) DeleteSender(req *http.Request) (*http.Response, error) { - return autorest.SendWithSender(client, req) + return autorest.SendWithSender(client, req, + azure.DoRetryWithRegistration(client.Client)) } // DeleteResponder handles the response to the Delete request. The method always @@ -189,7 +192,7 @@ func (client RecordSetsClient) DeleteResponder(resp *http.Response) (result auto err = autorest.Respond( resp, client.ByInspecting(), - azure.WithErrorUnlessStatusCode(http.StatusNoContent, http.StatusOK), + azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusNoContent), autorest.ByClosing()) result.Response = resp return @@ -198,10 +201,10 @@ func (client RecordSetsClient) DeleteResponder(resp *http.Response) (result auto // Get gets a record set. // // resourceGroupName is the name of the resource group. zoneName is the name of the DNS zone (without a terminating -// dot). relativeRecordSetName is the name of the record set, relative to the name of the zone. recordType is the type -// of DNS record in this record set. -func (client RecordSetsClient) Get(resourceGroupName string, zoneName string, relativeRecordSetName string, recordType RecordType) (result RecordSet, err error) { - req, err := client.GetPreparer(resourceGroupName, zoneName, relativeRecordSetName, recordType) +// dot). relativeRecordSetName is the name of the record set, relative to the name of the zone. recordType is the +// type of DNS record in this record set. +func (client RecordSetsClient) Get(ctx context.Context, resourceGroupName string, zoneName string, relativeRecordSetName string, recordType RecordType) (result RecordSet, err error) { + req, err := client.GetPreparer(ctx, resourceGroupName, zoneName, relativeRecordSetName, recordType) if err != nil { err = autorest.NewErrorWithError(err, "dns.RecordSetsClient", "Get", nil, "Failure preparing request") return @@ -223,7 +226,7 @@ func (client RecordSetsClient) Get(resourceGroupName string, zoneName string, re } // GetPreparer prepares the Get request. -func (client RecordSetsClient) GetPreparer(resourceGroupName string, zoneName string, relativeRecordSetName string, recordType RecordType) (*http.Request, error) { +func (client RecordSetsClient) GetPreparer(ctx context.Context, resourceGroupName string, zoneName string, relativeRecordSetName string, recordType RecordType) (*http.Request, error) { pathParameters := map[string]interface{}{ "recordType": autorest.Encode("path", recordType), "relativeRecordSetName": relativeRecordSetName, @@ -232,7 +235,7 @@ func (client RecordSetsClient) GetPreparer(resourceGroupName string, zoneName st "zoneName": autorest.Encode("path", zoneName), } - const APIVersion = "2016-04-01" + const APIVersion = "2017-09-01" queryParameters := map[string]interface{}{ "api-version": APIVersion, } @@ -242,13 +245,14 @@ func (client RecordSetsClient) GetPreparer(resourceGroupName string, zoneName st autorest.WithBaseURL(client.BaseURI), autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Network/dnsZones/{zoneName}/{recordType}/{relativeRecordSetName}", pathParameters), autorest.WithQueryParameters(queryParameters)) - return preparer.Prepare(&http.Request{}) + return preparer.Prepare((&http.Request{}).WithContext(ctx)) } // GetSender sends the Get request. The method will close the // http.Response Body if it receives an error. func (client RecordSetsClient) GetSender(req *http.Request) (*http.Response, error) { - return autorest.SendWithSender(client, req) + return autorest.SendWithSender(client, req, + azure.DoRetryWithRegistration(client.Client)) } // GetResponder handles the response to the Get request. The method always @@ -271,8 +275,9 @@ func (client RecordSetsClient) GetResponder(resp *http.Response) (result RecordS // recordsetnamesuffix is the suffix label of the record set name that has to be used to filter the record set // enumerations. If this parameter is specified, Enumeration will return only records that end with // . -func (client RecordSetsClient) ListByDNSZone(resourceGroupName string, zoneName string, top *int32, recordsetnamesuffix string) (result RecordSetListResult, err error) { - req, err := client.ListByDNSZonePreparer(resourceGroupName, zoneName, top, recordsetnamesuffix) +func (client RecordSetsClient) ListByDNSZone(ctx context.Context, resourceGroupName string, zoneName string, top *int32, recordsetnamesuffix string) (result RecordSetListResultPage, err error) { + result.fn = client.listByDNSZoneNextResults + req, err := client.ListByDNSZonePreparer(ctx, resourceGroupName, zoneName, top, recordsetnamesuffix) if err != nil { err = autorest.NewErrorWithError(err, "dns.RecordSetsClient", "ListByDNSZone", nil, "Failure preparing request") return @@ -280,12 +285,12 @@ func (client RecordSetsClient) ListByDNSZone(resourceGroupName string, zoneName resp, err := client.ListByDNSZoneSender(req) if err != nil { - result.Response = autorest.Response{Response: resp} + result.rslr.Response = autorest.Response{Response: resp} err = autorest.NewErrorWithError(err, "dns.RecordSetsClient", "ListByDNSZone", resp, "Failure sending request") return } - result, err = client.ListByDNSZoneResponder(resp) + result.rslr, err = client.ListByDNSZoneResponder(resp) if err != nil { err = autorest.NewErrorWithError(err, "dns.RecordSetsClient", "ListByDNSZone", resp, "Failure responding to request") } @@ -294,14 +299,14 @@ func (client RecordSetsClient) ListByDNSZone(resourceGroupName string, zoneName } // ListByDNSZonePreparer prepares the ListByDNSZone request. -func (client RecordSetsClient) ListByDNSZonePreparer(resourceGroupName string, zoneName string, top *int32, recordsetnamesuffix string) (*http.Request, error) { +func (client RecordSetsClient) ListByDNSZonePreparer(ctx context.Context, resourceGroupName string, zoneName string, top *int32, recordsetnamesuffix string) (*http.Request, error) { pathParameters := map[string]interface{}{ "resourceGroupName": autorest.Encode("path", resourceGroupName), "subscriptionId": autorest.Encode("path", client.SubscriptionID), "zoneName": autorest.Encode("path", zoneName), } - const APIVersion = "2016-04-01" + const APIVersion = "2017-09-01" queryParameters := map[string]interface{}{ "api-version": APIVersion, } @@ -317,13 +322,14 @@ func (client RecordSetsClient) ListByDNSZonePreparer(resourceGroupName string, z autorest.WithBaseURL(client.BaseURI), autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Network/dnsZones/{zoneName}/recordsets", pathParameters), autorest.WithQueryParameters(queryParameters)) - return preparer.Prepare(&http.Request{}) + return preparer.Prepare((&http.Request{}).WithContext(ctx)) } // ListByDNSZoneSender sends the ListByDNSZone request. The method will close the // http.Response Body if it receives an error. func (client RecordSetsClient) ListByDNSZoneSender(req *http.Request) (*http.Response, error) { - return autorest.SendWithSender(client, req) + return autorest.SendWithSender(client, req, + azure.DoRetryWithRegistration(client.Client)) } // ListByDNSZoneResponder handles the response to the ListByDNSZone request. The method always @@ -339,84 +345,43 @@ func (client RecordSetsClient) ListByDNSZoneResponder(resp *http.Response) (resu return } -// ListByDNSZoneNextResults retrieves the next set of results, if any. -func (client RecordSetsClient) ListByDNSZoneNextResults(lastResults RecordSetListResult) (result RecordSetListResult, err error) { - req, err := lastResults.RecordSetListResultPreparer() +// listByDNSZoneNextResults retrieves the next set of results, if any. +func (client RecordSetsClient) listByDNSZoneNextResults(lastResults RecordSetListResult) (result RecordSetListResult, err error) { + req, err := lastResults.recordSetListResultPreparer() if err != nil { - return result, autorest.NewErrorWithError(err, "dns.RecordSetsClient", "ListByDNSZone", nil, "Failure preparing next results request") + return result, autorest.NewErrorWithError(err, "dns.RecordSetsClient", "listByDNSZoneNextResults", nil, "Failure preparing next results request") } if req == nil { return } - resp, err := client.ListByDNSZoneSender(req) if err != nil { result.Response = autorest.Response{Response: resp} - return result, autorest.NewErrorWithError(err, "dns.RecordSetsClient", "ListByDNSZone", resp, "Failure sending next results request") + return result, autorest.NewErrorWithError(err, "dns.RecordSetsClient", "listByDNSZoneNextResults", resp, "Failure sending next results request") } - result, err = client.ListByDNSZoneResponder(resp) if err != nil { - err = autorest.NewErrorWithError(err, "dns.RecordSetsClient", "ListByDNSZone", resp, "Failure responding to next results request") + err = autorest.NewErrorWithError(err, "dns.RecordSetsClient", "listByDNSZoneNextResults", resp, "Failure responding to next results request") } - return } -// ListByDNSZoneComplete gets all elements from the list without paging. -func (client RecordSetsClient) ListByDNSZoneComplete(resourceGroupName string, zoneName string, top *int32, recordsetnamesuffix string, cancel <-chan struct{}) (<-chan RecordSet, <-chan error) { - resultChan := make(chan RecordSet) - errChan := make(chan error, 1) - go func() { - defer func() { - close(resultChan) - close(errChan) - }() - list, err := client.ListByDNSZone(resourceGroupName, zoneName, top, recordsetnamesuffix) - if err != nil { - errChan <- err - return - } - if list.Value != nil { - for _, item := range *list.Value { - select { - case <-cancel: - return - case resultChan <- item: - // Intentionally left blank - } - } - } - for list.NextLink != nil { - list, err = client.ListByDNSZoneNextResults(list) - if err != nil { - errChan <- err - return - } - if list.Value != nil { - for _, item := range *list.Value { - select { - case <-cancel: - return - case resultChan <- item: - // Intentionally left blank - } - } - } - } - }() - return resultChan, errChan +// ListByDNSZoneComplete enumerates all values, automatically crossing page boundaries as required. +func (client RecordSetsClient) ListByDNSZoneComplete(ctx context.Context, resourceGroupName string, zoneName string, top *int32, recordsetnamesuffix string) (result RecordSetListResultIterator, err error) { + result.page, err = client.ListByDNSZone(ctx, resourceGroupName, zoneName, top, recordsetnamesuffix) + return } // ListByType lists the record sets of a specified type in a DNS zone. // // resourceGroupName is the name of the resource group. zoneName is the name of the DNS zone (without a terminating -// dot). recordType is the type of record sets to enumerate. top is the maximum number of record sets to return. If not -// specified, returns up to 100 record sets. recordsetnamesuffix is the suffix label of the record set name that has to -// be used to filter the record set enumerations. If this parameter is specified, Enumeration will return only records -// that end with . -func (client RecordSetsClient) ListByType(resourceGroupName string, zoneName string, recordType RecordType, top *int32, recordsetnamesuffix string) (result RecordSetListResult, err error) { - req, err := client.ListByTypePreparer(resourceGroupName, zoneName, recordType, top, recordsetnamesuffix) +// dot). recordType is the type of record sets to enumerate. top is the maximum number of record sets to return. If +// not specified, returns up to 100 record sets. recordsetnamesuffix is the suffix label of the record set name +// that has to be used to filter the record set enumerations. If this parameter is specified, Enumeration will +// return only records that end with . +func (client RecordSetsClient) ListByType(ctx context.Context, resourceGroupName string, zoneName string, recordType RecordType, top *int32, recordsetnamesuffix string) (result RecordSetListResultPage, err error) { + result.fn = client.listByTypeNextResults + req, err := client.ListByTypePreparer(ctx, resourceGroupName, zoneName, recordType, top, recordsetnamesuffix) if err != nil { err = autorest.NewErrorWithError(err, "dns.RecordSetsClient", "ListByType", nil, "Failure preparing request") return @@ -424,12 +389,12 @@ func (client RecordSetsClient) ListByType(resourceGroupName string, zoneName str resp, err := client.ListByTypeSender(req) if err != nil { - result.Response = autorest.Response{Response: resp} + result.rslr.Response = autorest.Response{Response: resp} err = autorest.NewErrorWithError(err, "dns.RecordSetsClient", "ListByType", resp, "Failure sending request") return } - result, err = client.ListByTypeResponder(resp) + result.rslr, err = client.ListByTypeResponder(resp) if err != nil { err = autorest.NewErrorWithError(err, "dns.RecordSetsClient", "ListByType", resp, "Failure responding to request") } @@ -438,7 +403,7 @@ func (client RecordSetsClient) ListByType(resourceGroupName string, zoneName str } // ListByTypePreparer prepares the ListByType request. -func (client RecordSetsClient) ListByTypePreparer(resourceGroupName string, zoneName string, recordType RecordType, top *int32, recordsetnamesuffix string) (*http.Request, error) { +func (client RecordSetsClient) ListByTypePreparer(ctx context.Context, resourceGroupName string, zoneName string, recordType RecordType, top *int32, recordsetnamesuffix string) (*http.Request, error) { pathParameters := map[string]interface{}{ "recordType": autorest.Encode("path", recordType), "resourceGroupName": autorest.Encode("path", resourceGroupName), @@ -446,7 +411,7 @@ func (client RecordSetsClient) ListByTypePreparer(resourceGroupName string, zone "zoneName": autorest.Encode("path", zoneName), } - const APIVersion = "2016-04-01" + const APIVersion = "2017-09-01" queryParameters := map[string]interface{}{ "api-version": APIVersion, } @@ -462,13 +427,14 @@ func (client RecordSetsClient) ListByTypePreparer(resourceGroupName string, zone autorest.WithBaseURL(client.BaseURI), autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Network/dnsZones/{zoneName}/{recordType}", pathParameters), autorest.WithQueryParameters(queryParameters)) - return preparer.Prepare(&http.Request{}) + return preparer.Prepare((&http.Request{}).WithContext(ctx)) } // ListByTypeSender sends the ListByType request. The method will close the // http.Response Body if it receives an error. func (client RecordSetsClient) ListByTypeSender(req *http.Request) (*http.Response, error) { - return autorest.SendWithSender(client, req) + return autorest.SendWithSender(client, req, + azure.DoRetryWithRegistration(client.Client)) } // ListByTypeResponder handles the response to the ListByType request. The method always @@ -484,84 +450,42 @@ func (client RecordSetsClient) ListByTypeResponder(resp *http.Response) (result return } -// ListByTypeNextResults retrieves the next set of results, if any. -func (client RecordSetsClient) ListByTypeNextResults(lastResults RecordSetListResult) (result RecordSetListResult, err error) { - req, err := lastResults.RecordSetListResultPreparer() +// listByTypeNextResults retrieves the next set of results, if any. +func (client RecordSetsClient) listByTypeNextResults(lastResults RecordSetListResult) (result RecordSetListResult, err error) { + req, err := lastResults.recordSetListResultPreparer() if err != nil { - return result, autorest.NewErrorWithError(err, "dns.RecordSetsClient", "ListByType", nil, "Failure preparing next results request") + return result, autorest.NewErrorWithError(err, "dns.RecordSetsClient", "listByTypeNextResults", nil, "Failure preparing next results request") } if req == nil { return } - resp, err := client.ListByTypeSender(req) if err != nil { result.Response = autorest.Response{Response: resp} - return result, autorest.NewErrorWithError(err, "dns.RecordSetsClient", "ListByType", resp, "Failure sending next results request") + return result, autorest.NewErrorWithError(err, "dns.RecordSetsClient", "listByTypeNextResults", resp, "Failure sending next results request") } - result, err = client.ListByTypeResponder(resp) if err != nil { - err = autorest.NewErrorWithError(err, "dns.RecordSetsClient", "ListByType", resp, "Failure responding to next results request") + err = autorest.NewErrorWithError(err, "dns.RecordSetsClient", "listByTypeNextResults", resp, "Failure responding to next results request") } - return } -// ListByTypeComplete gets all elements from the list without paging. -func (client RecordSetsClient) ListByTypeComplete(resourceGroupName string, zoneName string, recordType RecordType, top *int32, recordsetnamesuffix string, cancel <-chan struct{}) (<-chan RecordSet, <-chan error) { - resultChan := make(chan RecordSet) - errChan := make(chan error, 1) - go func() { - defer func() { - close(resultChan) - close(errChan) - }() - list, err := client.ListByType(resourceGroupName, zoneName, recordType, top, recordsetnamesuffix) - if err != nil { - errChan <- err - return - } - if list.Value != nil { - for _, item := range *list.Value { - select { - case <-cancel: - return - case resultChan <- item: - // Intentionally left blank - } - } - } - for list.NextLink != nil { - list, err = client.ListByTypeNextResults(list) - if err != nil { - errChan <- err - return - } - if list.Value != nil { - for _, item := range *list.Value { - select { - case <-cancel: - return - case resultChan <- item: - // Intentionally left blank - } - } - } - } - }() - return resultChan, errChan +// ListByTypeComplete enumerates all values, automatically crossing page boundaries as required. +func (client RecordSetsClient) ListByTypeComplete(ctx context.Context, resourceGroupName string, zoneName string, recordType RecordType, top *int32, recordsetnamesuffix string) (result RecordSetListResultIterator, err error) { + result.page, err = client.ListByType(ctx, resourceGroupName, zoneName, recordType, top, recordsetnamesuffix) + return } // Update updates a record set within a DNS zone. // // resourceGroupName is the name of the resource group. zoneName is the name of the DNS zone (without a terminating -// dot). relativeRecordSetName is the name of the record set, relative to the name of the zone. recordType is the type -// of DNS record in this record set. parameters is parameters supplied to the Update operation. ifMatch is the etag of -// the record set. Omit this value to always overwrite the current record set. Specify the last-seen etag value to -// prevent accidentally overwritting concurrent changes. -func (client RecordSetsClient) Update(resourceGroupName string, zoneName string, relativeRecordSetName string, recordType RecordType, parameters RecordSet, ifMatch string) (result RecordSet, err error) { - req, err := client.UpdatePreparer(resourceGroupName, zoneName, relativeRecordSetName, recordType, parameters, ifMatch) +// dot). relativeRecordSetName is the name of the record set, relative to the name of the zone. recordType is the +// type of DNS record in this record set. parameters is parameters supplied to the Update operation. ifMatch is the +// etag of the record set. Omit this value to always overwrite the current record set. Specify the last-seen etag +// value to prevent accidentally overwritting concurrent changes. +func (client RecordSetsClient) Update(ctx context.Context, resourceGroupName string, zoneName string, relativeRecordSetName string, recordType RecordType, parameters RecordSet, ifMatch string) (result RecordSet, err error) { + req, err := client.UpdatePreparer(ctx, resourceGroupName, zoneName, relativeRecordSetName, recordType, parameters, ifMatch) if err != nil { err = autorest.NewErrorWithError(err, "dns.RecordSetsClient", "Update", nil, "Failure preparing request") return @@ -583,7 +507,7 @@ func (client RecordSetsClient) Update(resourceGroupName string, zoneName string, } // UpdatePreparer prepares the Update request. -func (client RecordSetsClient) UpdatePreparer(resourceGroupName string, zoneName string, relativeRecordSetName string, recordType RecordType, parameters RecordSet, ifMatch string) (*http.Request, error) { +func (client RecordSetsClient) UpdatePreparer(ctx context.Context, resourceGroupName string, zoneName string, relativeRecordSetName string, recordType RecordType, parameters RecordSet, ifMatch string) (*http.Request, error) { pathParameters := map[string]interface{}{ "recordType": autorest.Encode("path", recordType), "relativeRecordSetName": relativeRecordSetName, @@ -592,13 +516,13 @@ func (client RecordSetsClient) UpdatePreparer(resourceGroupName string, zoneName "zoneName": autorest.Encode("path", zoneName), } - const APIVersion = "2016-04-01" + const APIVersion = "2017-09-01" queryParameters := map[string]interface{}{ "api-version": APIVersion, } preparer := autorest.CreatePreparer( - autorest.AsJSON(), + autorest.AsContentType("application/json; charset=utf-8"), autorest.AsPatch(), autorest.WithBaseURL(client.BaseURI), autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Network/dnsZones/{zoneName}/{recordType}/{relativeRecordSetName}", pathParameters), @@ -608,13 +532,14 @@ func (client RecordSetsClient) UpdatePreparer(resourceGroupName string, zoneName preparer = autorest.DecoratePreparer(preparer, autorest.WithHeader("If-Match", autorest.String(ifMatch))) } - return preparer.Prepare(&http.Request{}) + return preparer.Prepare((&http.Request{}).WithContext(ctx)) } // UpdateSender sends the Update request. The method will close the // http.Response Body if it receives an error. func (client RecordSetsClient) UpdateSender(req *http.Request) (*http.Response, error) { - return autorest.SendWithSender(client, req) + return autorest.SendWithSender(client, req, + azure.DoRetryWithRegistration(client.Client)) } // UpdateResponder handles the response to the Update request. The method always diff --git a/vendor/github.com/Azure/azure-sdk-for-go/arm/dns/version.go b/vendor/github.com/Azure/azure-sdk-for-go/services/dns/mgmt/2017-09-01/dns/version.go old mode 100755 new mode 100644 similarity index 87% rename from vendor/github.com/Azure/azure-sdk-for-go/arm/dns/version.go rename to vendor/github.com/Azure/azure-sdk-for-go/services/dns/mgmt/2017-09-01/dns/version.go index d5ade9afd..0556b6130 --- a/vendor/github.com/Azure/azure-sdk-for-go/arm/dns/version.go +++ b/vendor/github.com/Azure/azure-sdk-for-go/services/dns/mgmt/2017-09-01/dns/version.go @@ -1,5 +1,7 @@ package dns +import "github.com/Azure/azure-sdk-for-go/version" + // Copyright (c) Microsoft and contributors. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); @@ -19,10 +21,10 @@ package dns // UserAgent returns the UserAgent string to use when sending http.Requests. func UserAgent() string { - return "Azure-SDK-For-Go/v11.0.0-beta arm-dns/2016-04-01" + return "Azure-SDK-For-Go/" + version.Number + " dns/2017-09-01" } // Version returns the semantic version (see http://semver.org) of the client. func Version() string { - return "v11.0.0-beta" + return version.Number } diff --git a/vendor/github.com/Azure/azure-sdk-for-go/arm/dns/zones.go b/vendor/github.com/Azure/azure-sdk-for-go/services/dns/mgmt/2017-09-01/dns/zones.go old mode 100755 new mode 100644 similarity index 63% rename from vendor/github.com/Azure/azure-sdk-for-go/arm/dns/zones.go rename to vendor/github.com/Azure/azure-sdk-for-go/services/dns/mgmt/2017-09-01/dns/zones.go index 33b230b03..04ac760d0 --- a/vendor/github.com/Azure/azure-sdk-for-go/arm/dns/zones.go +++ b/vendor/github.com/Azure/azure-sdk-for-go/services/dns/mgmt/2017-09-01/dns/zones.go @@ -18,6 +18,7 @@ package dns // Changes may cause incorrect behavior and will be lost if the code is regenerated. import ( + "context" "github.com/Azure/go-autorest/autorest" "github.com/Azure/go-autorest/autorest/azure" "net/http" @@ -25,7 +26,7 @@ import ( // ZonesClient is the the DNS Management Client. type ZonesClient struct { - ManagementClient + BaseClient } // NewZonesClient creates an instance of the ZonesClient client. @@ -41,12 +42,12 @@ func NewZonesClientWithBaseURI(baseURI string, subscriptionID string) ZonesClien // CreateOrUpdate creates or updates a DNS zone. Does not modify DNS records within the zone. // // resourceGroupName is the name of the resource group. zoneName is the name of the DNS zone (without a terminating -// dot). parameters is parameters supplied to the CreateOrUpdate operation. ifMatch is the etag of the DNS zone. Omit -// this value to always overwrite the current zone. Specify the last-seen etag value to prevent accidentally -// overwritting any concurrent changes. ifNoneMatch is set to '*' to allow a new DNS zone to be created, but to prevent -// updating an existing zone. Other values will be ignored. -func (client ZonesClient) CreateOrUpdate(resourceGroupName string, zoneName string, parameters Zone, ifMatch string, ifNoneMatch string) (result Zone, err error) { - req, err := client.CreateOrUpdatePreparer(resourceGroupName, zoneName, parameters, ifMatch, ifNoneMatch) +// dot). parameters is parameters supplied to the CreateOrUpdate operation. ifMatch is the etag of the DNS zone. +// Omit this value to always overwrite the current zone. Specify the last-seen etag value to prevent accidentally +// overwritting any concurrent changes. ifNoneMatch is set to '*' to allow a new DNS zone to be created, but to +// prevent updating an existing zone. Other values will be ignored. +func (client ZonesClient) CreateOrUpdate(ctx context.Context, resourceGroupName string, zoneName string, parameters Zone, ifMatch string, ifNoneMatch string) (result Zone, err error) { + req, err := client.CreateOrUpdatePreparer(ctx, resourceGroupName, zoneName, parameters, ifMatch, ifNoneMatch) if err != nil { err = autorest.NewErrorWithError(err, "dns.ZonesClient", "CreateOrUpdate", nil, "Failure preparing request") return @@ -68,20 +69,20 @@ func (client ZonesClient) CreateOrUpdate(resourceGroupName string, zoneName stri } // CreateOrUpdatePreparer prepares the CreateOrUpdate request. -func (client ZonesClient) CreateOrUpdatePreparer(resourceGroupName string, zoneName string, parameters Zone, ifMatch string, ifNoneMatch string) (*http.Request, error) { +func (client ZonesClient) CreateOrUpdatePreparer(ctx context.Context, resourceGroupName string, zoneName string, parameters Zone, ifMatch string, ifNoneMatch string) (*http.Request, error) { pathParameters := map[string]interface{}{ "resourceGroupName": autorest.Encode("path", resourceGroupName), "subscriptionId": autorest.Encode("path", client.SubscriptionID), "zoneName": autorest.Encode("path", zoneName), } - const APIVersion = "2016-04-01" + const APIVersion = "2017-09-01" queryParameters := map[string]interface{}{ "api-version": APIVersion, } preparer := autorest.CreatePreparer( - autorest.AsJSON(), + autorest.AsContentType("application/json; charset=utf-8"), autorest.AsPut(), autorest.WithBaseURL(client.BaseURI), autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Network/dnsZones/{zoneName}", pathParameters), @@ -95,13 +96,14 @@ func (client ZonesClient) CreateOrUpdatePreparer(resourceGroupName string, zoneN preparer = autorest.DecoratePreparer(preparer, autorest.WithHeader("If-None-Match", autorest.String(ifNoneMatch))) } - return preparer.Prepare(&http.Request{}) + return preparer.Prepare((&http.Request{}).WithContext(ctx)) } // CreateOrUpdateSender sends the CreateOrUpdate request. The method will close the // http.Response Body if it receives an error. func (client ZonesClient) CreateOrUpdateSender(req *http.Request) (*http.Response, error) { - return autorest.SendWithSender(client, req) + return autorest.SendWithSender(client, req, + azure.DoRetryWithRegistration(client.Client)) } // CreateOrUpdateResponder handles the response to the CreateOrUpdate request. The method always @@ -118,56 +120,36 @@ func (client ZonesClient) CreateOrUpdateResponder(resp *http.Response) (result Z } // Delete deletes a DNS zone. WARNING: All DNS records in the zone will also be deleted. This operation cannot be -// undone. This method may poll for completion. Polling can be canceled by passing the cancel channel argument. The -// channel will be used to cancel polling and any outstanding HTTP requests. +// undone. // // resourceGroupName is the name of the resource group. zoneName is the name of the DNS zone (without a terminating -// dot). ifMatch is the etag of the DNS zone. Omit this value to always delete the current zone. Specify the last-seen -// etag value to prevent accidentally deleting any concurrent changes. -func (client ZonesClient) Delete(resourceGroupName string, zoneName string, ifMatch string, cancel <-chan struct{}) (<-chan ZoneDeleteResult, <-chan error) { - resultChan := make(chan ZoneDeleteResult, 1) - errChan := make(chan error, 1) - go func() { - var err error - var result ZoneDeleteResult - defer func() { - if err != nil { - errChan <- err - } - resultChan <- result - close(resultChan) - close(errChan) - }() - req, err := client.DeletePreparer(resourceGroupName, zoneName, ifMatch, cancel) - if err != nil { - err = autorest.NewErrorWithError(err, "dns.ZonesClient", "Delete", nil, "Failure preparing request") - return - } +// dot). ifMatch is the etag of the DNS zone. Omit this value to always delete the current zone. Specify the +// last-seen etag value to prevent accidentally deleting any concurrent changes. +func (client ZonesClient) Delete(ctx context.Context, resourceGroupName string, zoneName string, ifMatch string) (result ZonesDeleteFuture, err error) { + req, err := client.DeletePreparer(ctx, resourceGroupName, zoneName, ifMatch) + if err != nil { + err = autorest.NewErrorWithError(err, "dns.ZonesClient", "Delete", nil, "Failure preparing request") + return + } - resp, err := client.DeleteSender(req) - if err != nil { - result.Response = autorest.Response{Response: resp} - err = autorest.NewErrorWithError(err, "dns.ZonesClient", "Delete", resp, "Failure sending request") - return - } + result, err = client.DeleteSender(req) + if err != nil { + err = autorest.NewErrorWithError(err, "dns.ZonesClient", "Delete", result.Response(), "Failure sending request") + return + } - result, err = client.DeleteResponder(resp) - if err != nil { - err = autorest.NewErrorWithError(err, "dns.ZonesClient", "Delete", resp, "Failure responding to request") - } - }() - return resultChan, errChan + return } // DeletePreparer prepares the Delete request. -func (client ZonesClient) DeletePreparer(resourceGroupName string, zoneName string, ifMatch string, cancel <-chan struct{}) (*http.Request, error) { +func (client ZonesClient) DeletePreparer(ctx context.Context, resourceGroupName string, zoneName string, ifMatch string) (*http.Request, error) { pathParameters := map[string]interface{}{ "resourceGroupName": autorest.Encode("path", resourceGroupName), "subscriptionId": autorest.Encode("path", client.SubscriptionID), "zoneName": autorest.Encode("path", zoneName), } - const APIVersion = "2016-04-01" + const APIVersion = "2017-09-01" queryParameters := map[string]interface{}{ "api-version": APIVersion, } @@ -181,27 +163,33 @@ func (client ZonesClient) DeletePreparer(resourceGroupName string, zoneName stri preparer = autorest.DecoratePreparer(preparer, autorest.WithHeader("If-Match", autorest.String(ifMatch))) } - return preparer.Prepare(&http.Request{Cancel: cancel}) + return preparer.Prepare((&http.Request{}).WithContext(ctx)) } // DeleteSender sends the Delete request. The method will close the // http.Response Body if it receives an error. -func (client ZonesClient) DeleteSender(req *http.Request) (*http.Response, error) { - return autorest.SendWithSender(client, - req, - azure.DoPollForAsynchronous(client.PollingDelay)) +func (client ZonesClient) DeleteSender(req *http.Request) (future ZonesDeleteFuture, err error) { + sender := autorest.DecorateSender(client, azure.DoRetryWithRegistration(client.Client)) + future.Future = azure.NewFuture(req) + future.req = req + _, err = future.Done(sender) + if err != nil { + return + } + err = autorest.Respond(future.Response(), + azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted, http.StatusNoContent)) + return } // DeleteResponder handles the response to the Delete request. The method always // closes the http.Response Body. -func (client ZonesClient) DeleteResponder(resp *http.Response) (result ZoneDeleteResult, err error) { +func (client ZonesClient) DeleteResponder(resp *http.Response) (result autorest.Response, err error) { err = autorest.Respond( resp, client.ByInspecting(), - azure.WithErrorUnlessStatusCode(http.StatusNoContent, http.StatusAccepted, http.StatusOK), - autorest.ByUnmarshallingJSON(&result), + azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted, http.StatusNoContent), autorest.ByClosing()) - result.Response = autorest.Response{Response: resp} + result.Response = resp return } @@ -209,8 +197,8 @@ func (client ZonesClient) DeleteResponder(resp *http.Response) (result ZoneDelet // // resourceGroupName is the name of the resource group. zoneName is the name of the DNS zone (without a terminating // dot). -func (client ZonesClient) Get(resourceGroupName string, zoneName string) (result Zone, err error) { - req, err := client.GetPreparer(resourceGroupName, zoneName) +func (client ZonesClient) Get(ctx context.Context, resourceGroupName string, zoneName string) (result Zone, err error) { + req, err := client.GetPreparer(ctx, resourceGroupName, zoneName) if err != nil { err = autorest.NewErrorWithError(err, "dns.ZonesClient", "Get", nil, "Failure preparing request") return @@ -232,14 +220,14 @@ func (client ZonesClient) Get(resourceGroupName string, zoneName string) (result } // GetPreparer prepares the Get request. -func (client ZonesClient) GetPreparer(resourceGroupName string, zoneName string) (*http.Request, error) { +func (client ZonesClient) GetPreparer(ctx context.Context, resourceGroupName string, zoneName string) (*http.Request, error) { pathParameters := map[string]interface{}{ "resourceGroupName": autorest.Encode("path", resourceGroupName), "subscriptionId": autorest.Encode("path", client.SubscriptionID), "zoneName": autorest.Encode("path", zoneName), } - const APIVersion = "2016-04-01" + const APIVersion = "2017-09-01" queryParameters := map[string]interface{}{ "api-version": APIVersion, } @@ -249,13 +237,14 @@ func (client ZonesClient) GetPreparer(resourceGroupName string, zoneName string) autorest.WithBaseURL(client.BaseURI), autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Network/dnsZones/{zoneName}", pathParameters), autorest.WithQueryParameters(queryParameters)) - return preparer.Prepare(&http.Request{}) + return preparer.Prepare((&http.Request{}).WithContext(ctx)) } // GetSender sends the Get request. The method will close the // http.Response Body if it receives an error. func (client ZonesClient) GetSender(req *http.Request) (*http.Response, error) { - return autorest.SendWithSender(client, req) + return autorest.SendWithSender(client, req, + azure.DoRetryWithRegistration(client.Client)) } // GetResponder handles the response to the Get request. The method always @@ -274,8 +263,9 @@ func (client ZonesClient) GetResponder(resp *http.Response) (result Zone, err er // List lists the DNS zones in all resource groups in a subscription. // // top is the maximum number of DNS zones to return. If not specified, returns up to 100 zones. -func (client ZonesClient) List(top *int32) (result ZoneListResult, err error) { - req, err := client.ListPreparer(top) +func (client ZonesClient) List(ctx context.Context, top *int32) (result ZoneListResultPage, err error) { + result.fn = client.listNextResults + req, err := client.ListPreparer(ctx, top) if err != nil { err = autorest.NewErrorWithError(err, "dns.ZonesClient", "List", nil, "Failure preparing request") return @@ -283,12 +273,12 @@ func (client ZonesClient) List(top *int32) (result ZoneListResult, err error) { resp, err := client.ListSender(req) if err != nil { - result.Response = autorest.Response{Response: resp} + result.zlr.Response = autorest.Response{Response: resp} err = autorest.NewErrorWithError(err, "dns.ZonesClient", "List", resp, "Failure sending request") return } - result, err = client.ListResponder(resp) + result.zlr, err = client.ListResponder(resp) if err != nil { err = autorest.NewErrorWithError(err, "dns.ZonesClient", "List", resp, "Failure responding to request") } @@ -297,12 +287,12 @@ func (client ZonesClient) List(top *int32) (result ZoneListResult, err error) { } // ListPreparer prepares the List request. -func (client ZonesClient) ListPreparer(top *int32) (*http.Request, error) { +func (client ZonesClient) ListPreparer(ctx context.Context, top *int32) (*http.Request, error) { pathParameters := map[string]interface{}{ "subscriptionId": autorest.Encode("path", client.SubscriptionID), } - const APIVersion = "2016-04-01" + const APIVersion = "2017-09-01" queryParameters := map[string]interface{}{ "api-version": APIVersion, } @@ -315,13 +305,14 @@ func (client ZonesClient) ListPreparer(top *int32) (*http.Request, error) { autorest.WithBaseURL(client.BaseURI), autorest.WithPathParameters("/subscriptions/{subscriptionId}/providers/Microsoft.Network/dnszones", pathParameters), autorest.WithQueryParameters(queryParameters)) - return preparer.Prepare(&http.Request{}) + return preparer.Prepare((&http.Request{}).WithContext(ctx)) } // ListSender sends the List request. The method will close the // http.Response Body if it receives an error. func (client ZonesClient) ListSender(req *http.Request) (*http.Response, error) { - return autorest.SendWithSender(client, req) + return autorest.SendWithSender(client, req, + azure.DoRetryWithRegistration(client.Client)) } // ListResponder handles the response to the List request. The method always @@ -337,81 +328,40 @@ func (client ZonesClient) ListResponder(resp *http.Response) (result ZoneListRes return } -// ListNextResults retrieves the next set of results, if any. -func (client ZonesClient) ListNextResults(lastResults ZoneListResult) (result ZoneListResult, err error) { - req, err := lastResults.ZoneListResultPreparer() +// listNextResults retrieves the next set of results, if any. +func (client ZonesClient) listNextResults(lastResults ZoneListResult) (result ZoneListResult, err error) { + req, err := lastResults.zoneListResultPreparer() if err != nil { - return result, autorest.NewErrorWithError(err, "dns.ZonesClient", "List", nil, "Failure preparing next results request") + return result, autorest.NewErrorWithError(err, "dns.ZonesClient", "listNextResults", nil, "Failure preparing next results request") } if req == nil { return } - resp, err := client.ListSender(req) if err != nil { result.Response = autorest.Response{Response: resp} - return result, autorest.NewErrorWithError(err, "dns.ZonesClient", "List", resp, "Failure sending next results request") + return result, autorest.NewErrorWithError(err, "dns.ZonesClient", "listNextResults", resp, "Failure sending next results request") } - result, err = client.ListResponder(resp) if err != nil { - err = autorest.NewErrorWithError(err, "dns.ZonesClient", "List", resp, "Failure responding to next results request") + err = autorest.NewErrorWithError(err, "dns.ZonesClient", "listNextResults", resp, "Failure responding to next results request") } - return } -// ListComplete gets all elements from the list without paging. -func (client ZonesClient) ListComplete(top *int32, cancel <-chan struct{}) (<-chan Zone, <-chan error) { - resultChan := make(chan Zone) - errChan := make(chan error, 1) - go func() { - defer func() { - close(resultChan) - close(errChan) - }() - list, err := client.List(top) - if err != nil { - errChan <- err - return - } - if list.Value != nil { - for _, item := range *list.Value { - select { - case <-cancel: - return - case resultChan <- item: - // Intentionally left blank - } - } - } - for list.NextLink != nil { - list, err = client.ListNextResults(list) - if err != nil { - errChan <- err - return - } - if list.Value != nil { - for _, item := range *list.Value { - select { - case <-cancel: - return - case resultChan <- item: - // Intentionally left blank - } - } - } - } - }() - return resultChan, errChan +// ListComplete enumerates all values, automatically crossing page boundaries as required. +func (client ZonesClient) ListComplete(ctx context.Context, top *int32) (result ZoneListResultIterator, err error) { + result.page, err = client.List(ctx, top) + return } // ListByResourceGroup lists the DNS zones within a resource group. // // resourceGroupName is the name of the resource group. top is the maximum number of record sets to return. If not // specified, returns up to 100 record sets. -func (client ZonesClient) ListByResourceGroup(resourceGroupName string, top *int32) (result ZoneListResult, err error) { - req, err := client.ListByResourceGroupPreparer(resourceGroupName, top) +func (client ZonesClient) ListByResourceGroup(ctx context.Context, resourceGroupName string, top *int32) (result ZoneListResultPage, err error) { + result.fn = client.listByResourceGroupNextResults + req, err := client.ListByResourceGroupPreparer(ctx, resourceGroupName, top) if err != nil { err = autorest.NewErrorWithError(err, "dns.ZonesClient", "ListByResourceGroup", nil, "Failure preparing request") return @@ -419,12 +369,12 @@ func (client ZonesClient) ListByResourceGroup(resourceGroupName string, top *int resp, err := client.ListByResourceGroupSender(req) if err != nil { - result.Response = autorest.Response{Response: resp} + result.zlr.Response = autorest.Response{Response: resp} err = autorest.NewErrorWithError(err, "dns.ZonesClient", "ListByResourceGroup", resp, "Failure sending request") return } - result, err = client.ListByResourceGroupResponder(resp) + result.zlr, err = client.ListByResourceGroupResponder(resp) if err != nil { err = autorest.NewErrorWithError(err, "dns.ZonesClient", "ListByResourceGroup", resp, "Failure responding to request") } @@ -433,13 +383,13 @@ func (client ZonesClient) ListByResourceGroup(resourceGroupName string, top *int } // ListByResourceGroupPreparer prepares the ListByResourceGroup request. -func (client ZonesClient) ListByResourceGroupPreparer(resourceGroupName string, top *int32) (*http.Request, error) { +func (client ZonesClient) ListByResourceGroupPreparer(ctx context.Context, resourceGroupName string, top *int32) (*http.Request, error) { pathParameters := map[string]interface{}{ "resourceGroupName": autorest.Encode("path", resourceGroupName), "subscriptionId": autorest.Encode("path", client.SubscriptionID), } - const APIVersion = "2016-04-01" + const APIVersion = "2017-09-01" queryParameters := map[string]interface{}{ "api-version": APIVersion, } @@ -452,13 +402,14 @@ func (client ZonesClient) ListByResourceGroupPreparer(resourceGroupName string, autorest.WithBaseURL(client.BaseURI), autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Network/dnsZones", pathParameters), autorest.WithQueryParameters(queryParameters)) - return preparer.Prepare(&http.Request{}) + return preparer.Prepare((&http.Request{}).WithContext(ctx)) } // ListByResourceGroupSender sends the ListByResourceGroup request. The method will close the // http.Response Body if it receives an error. func (client ZonesClient) ListByResourceGroupSender(req *http.Request) (*http.Response, error) { - return autorest.SendWithSender(client, req) + return autorest.SendWithSender(client, req, + azure.DoRetryWithRegistration(client.Client)) } // ListByResourceGroupResponder handles the response to the ListByResourceGroup request. The method always @@ -474,71 +425,29 @@ func (client ZonesClient) ListByResourceGroupResponder(resp *http.Response) (res return } -// ListByResourceGroupNextResults retrieves the next set of results, if any. -func (client ZonesClient) ListByResourceGroupNextResults(lastResults ZoneListResult) (result ZoneListResult, err error) { - req, err := lastResults.ZoneListResultPreparer() +// listByResourceGroupNextResults retrieves the next set of results, if any. +func (client ZonesClient) listByResourceGroupNextResults(lastResults ZoneListResult) (result ZoneListResult, err error) { + req, err := lastResults.zoneListResultPreparer() if err != nil { - return result, autorest.NewErrorWithError(err, "dns.ZonesClient", "ListByResourceGroup", nil, "Failure preparing next results request") + return result, autorest.NewErrorWithError(err, "dns.ZonesClient", "listByResourceGroupNextResults", nil, "Failure preparing next results request") } if req == nil { return } - resp, err := client.ListByResourceGroupSender(req) if err != nil { result.Response = autorest.Response{Response: resp} - return result, autorest.NewErrorWithError(err, "dns.ZonesClient", "ListByResourceGroup", resp, "Failure sending next results request") + return result, autorest.NewErrorWithError(err, "dns.ZonesClient", "listByResourceGroupNextResults", resp, "Failure sending next results request") } - result, err = client.ListByResourceGroupResponder(resp) if err != nil { - err = autorest.NewErrorWithError(err, "dns.ZonesClient", "ListByResourceGroup", resp, "Failure responding to next results request") + err = autorest.NewErrorWithError(err, "dns.ZonesClient", "listByResourceGroupNextResults", resp, "Failure responding to next results request") } - return } -// ListByResourceGroupComplete gets all elements from the list without paging. -func (client ZonesClient) ListByResourceGroupComplete(resourceGroupName string, top *int32, cancel <-chan struct{}) (<-chan Zone, <-chan error) { - resultChan := make(chan Zone) - errChan := make(chan error, 1) - go func() { - defer func() { - close(resultChan) - close(errChan) - }() - list, err := client.ListByResourceGroup(resourceGroupName, top) - if err != nil { - errChan <- err - return - } - if list.Value != nil { - for _, item := range *list.Value { - select { - case <-cancel: - return - case resultChan <- item: - // Intentionally left blank - } - } - } - for list.NextLink != nil { - list, err = client.ListByResourceGroupNextResults(list) - if err != nil { - errChan <- err - return - } - if list.Value != nil { - for _, item := range *list.Value { - select { - case <-cancel: - return - case resultChan <- item: - // Intentionally left blank - } - } - } - } - }() - return resultChan, errChan +// ListByResourceGroupComplete enumerates all values, automatically crossing page boundaries as required. +func (client ZonesClient) ListByResourceGroupComplete(ctx context.Context, resourceGroupName string, top *int32) (result ZoneListResultIterator, err error) { + result.page, err = client.ListByResourceGroup(ctx, resourceGroupName, top) + return } diff --git a/vendor/github.com/Azure/azure-sdk-for-go/version/version.go b/vendor/github.com/Azure/azure-sdk-for-go/version/version.go new file mode 100644 index 000000000..2cd4c1b1f --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/version/version.go @@ -0,0 +1,21 @@ +package version + +// Copyright (c) Microsoft and contributors. All rights reserved. +// +// 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. +// +// Code generated by Microsoft (R) AutoRest Code Generator. +// Changes may cause incorrect behavior and will be lost if the code is regenerated. + +// Number contains the semantic version of this SDK. +const Number = "v15.0.1" diff --git a/vendor/github.com/Azure/go-autorest/autorest/adal/config.go b/vendor/github.com/Azure/go-autorest/autorest/adal/config.go index 12375e0e4..f570d540a 100644 --- a/vendor/github.com/Azure/go-autorest/autorest/adal/config.go +++ b/vendor/github.com/Azure/go-autorest/autorest/adal/config.go @@ -1,5 +1,19 @@ 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 ( "fmt" "net/url" @@ -18,8 +32,24 @@ type OAuthConfig struct { DeviceCodeEndpoint url.URL } +// IsZero returns true if the OAuthConfig object is zero-initialized. +func (oac OAuthConfig) IsZero() bool { + return oac == OAuthConfig{} +} + +func validateStringParam(param, name string) error { + if len(param) == 0 { + return fmt.Errorf("parameter '" + name + "' cannot be empty") + } + return nil +} + // NewOAuthConfig returns an OAuthConfig with tenant specific urls func NewOAuthConfig(activeDirectoryEndpoint, tenantID string) (*OAuthConfig, error) { + if err := validateStringParam(activeDirectoryEndpoint, "activeDirectoryEndpoint"); err != nil { + return nil, err + } + // it's legal for tenantID to be empty so don't validate it const activeDirectoryEndpointTemplate = "%s/oauth2/%s?api-version=%s" u, err := url.Parse(activeDirectoryEndpoint) if err != nil { diff --git a/vendor/github.com/Azure/go-autorest/autorest/adal/devicetoken.go b/vendor/github.com/Azure/go-autorest/autorest/adal/devicetoken.go index 6c511f8c8..b38f4c245 100644 --- a/vendor/github.com/Azure/go-autorest/autorest/adal/devicetoken.go +++ b/vendor/github.com/Azure/go-autorest/autorest/adal/devicetoken.go @@ -1,5 +1,19 @@ 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: * scope -> resource, and only allow a single one diff --git a/vendor/github.com/Azure/go-autorest/autorest/adal/msi.go b/vendor/github.com/Azure/go-autorest/autorest/adal/msi.go deleted file mode 100644 index e87911e83..000000000 --- a/vendor/github.com/Azure/go-autorest/autorest/adal/msi.go +++ /dev/null @@ -1,6 +0,0 @@ -// +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" diff --git a/vendor/github.com/Azure/go-autorest/autorest/adal/msi_windows.go b/vendor/github.com/Azure/go-autorest/autorest/adal/msi_windows.go deleted file mode 100644 index 80f800432..000000000 --- a/vendor/github.com/Azure/go-autorest/autorest/adal/msi_windows.go +++ /dev/null @@ -1,11 +0,0 @@ -// +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"}, "/") diff --git a/vendor/github.com/Azure/go-autorest/autorest/adal/persist.go b/vendor/github.com/Azure/go-autorest/autorest/adal/persist.go index 73711c667..9e15f2751 100644 --- a/vendor/github.com/Azure/go-autorest/autorest/adal/persist.go +++ b/vendor/github.com/Azure/go-autorest/autorest/adal/persist.go @@ -1,5 +1,19 @@ 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 ( "encoding/json" "fmt" diff --git a/vendor/github.com/Azure/go-autorest/autorest/adal/sender.go b/vendor/github.com/Azure/go-autorest/autorest/adal/sender.go index 7928c971a..0e5ad14d3 100644 --- a/vendor/github.com/Azure/go-autorest/autorest/adal/sender.go +++ b/vendor/github.com/Azure/go-autorest/autorest/adal/sender.go @@ -1,5 +1,19 @@ 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 ( "net/http" ) diff --git a/vendor/github.com/Azure/go-autorest/autorest/adal/token.go b/vendor/github.com/Azure/go-autorest/autorest/adal/token.go index 2ac8c3c22..b61b3eb8e 100644 --- a/vendor/github.com/Azure/go-autorest/autorest/adal/token.go +++ b/vendor/github.com/Azure/go-autorest/autorest/adal/token.go @@ -1,5 +1,19 @@ 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 ( "crypto/rand" "crypto/rsa" @@ -13,6 +27,7 @@ import ( "net/url" "strconv" "strings" + "sync" "time" "github.com/Azure/go-autorest/autorest/date" @@ -28,11 +43,20 @@ const ( // OAuthGrantTypeClientCredentials is the "grant_type" identifier used in credential flows OAuthGrantTypeClientCredentials = "client_credentials" + // OAuthGrantTypeUserPass is the "grant_type" identifier used in username and password auth flows + OAuthGrantTypeUserPass = "password" + // OAuthGrantTypeRefreshToken is the "grant_type" identifier used in refresh token flows OAuthGrantTypeRefreshToken = "refresh_token" + // OAuthGrantTypeAuthorizationCode is the "grant_type" identifier used in authorization code flows + OAuthGrantTypeAuthorizationCode = "authorization_code" + // metadataHeader is the header required by MSI extension metadataHeader = "Metadata" + + // msiEndpoint is the well known endpoint for getting MSI authentications tokens + msiEndpoint = "http://169.254.169.254/metadata/identity/oauth2/token" ) // OAuthTokenProvider is an interface which should be implemented by an access token retriever @@ -40,6 +64,12 @@ type OAuthTokenProvider interface { OAuthToken() string } +// TokenRefreshError is an interface used by errors returned during token refresh. +type TokenRefreshError interface { + error + Response() *http.Response +} + // Refresher is an interface for token refresh functionality type Refresher interface { Refresh() error @@ -64,6 +94,11 @@ type Token struct { Type string `json:"token_type"` } +// IsZero returns true if the token object is zero-initialized. +func (t Token) IsZero() bool { + return t == Token{} +} + // Expires returns the time.Time when the Token expires. func (t Token) Expires() time.Time { s, err := strconv.Atoi(t.ExpiresOn) @@ -131,6 +166,34 @@ type ServicePrincipalCertificateSecret struct { type ServicePrincipalMSISecret struct { } +// ServicePrincipalUsernamePasswordSecret implements ServicePrincipalSecret for username and password auth. +type ServicePrincipalUsernamePasswordSecret struct { + Username string + Password string +} + +// ServicePrincipalAuthorizationCodeSecret implements ServicePrincipalSecret for authorization code auth. +type ServicePrincipalAuthorizationCodeSecret struct { + ClientSecret string + AuthorizationCode string + RedirectURI string +} + +// SetAuthenticationValues is a method of the interface ServicePrincipalSecret. +func (secret *ServicePrincipalAuthorizationCodeSecret) SetAuthenticationValues(spt *ServicePrincipalToken, v *url.Values) error { + v.Set("code", secret.AuthorizationCode) + v.Set("client_secret", secret.ClientSecret) + v.Set("redirect_uri", secret.RedirectURI) + return nil +} + +// SetAuthenticationValues is a method of the interface ServicePrincipalSecret. +func (secret *ServicePrincipalUsernamePasswordSecret) SetAuthenticationValues(spt *ServicePrincipalToken, v *url.Values) error { + v.Set("username", secret.Username) + v.Set("password", secret.Password) + return nil +} + // SetAuthenticationValues is a method of the interface ServicePrincipalSecret. func (msiSecret *ServicePrincipalMSISecret) SetAuthenticationValues(spt *ServicePrincipalToken, v *url.Values) error { return nil @@ -183,27 +246,47 @@ func (secret *ServicePrincipalCertificateSecret) SetAuthenticationValues(spt *Se // ServicePrincipalToken encapsulates a Token created for a Service Principal. type ServicePrincipalToken struct { - Token - + token Token secret ServicePrincipalSecret oauthConfig OAuthConfig clientID string resource string autoRefresh bool + refreshLock *sync.RWMutex refreshWithin time.Duration sender Sender refreshCallbacks []TokenRefreshCallback } +func validateOAuthConfig(oac OAuthConfig) error { + if oac.IsZero() { + return fmt.Errorf("parameter 'oauthConfig' cannot be zero-initialized") + } + return nil +} + // NewServicePrincipalTokenWithSecret create a ServicePrincipalToken using the supplied ServicePrincipalSecret implementation. func NewServicePrincipalTokenWithSecret(oauthConfig OAuthConfig, id string, resource string, secret ServicePrincipalSecret, callbacks ...TokenRefreshCallback) (*ServicePrincipalToken, error) { + if err := validateOAuthConfig(oauthConfig); err != nil { + return nil, err + } + if err := validateStringParam(id, "id"); err != nil { + return nil, err + } + if err := validateStringParam(resource, "resource"); err != nil { + return nil, err + } + if secret == nil { + return nil, fmt.Errorf("parameter 'secret' cannot be nil") + } spt := &ServicePrincipalToken{ oauthConfig: oauthConfig, secret: secret, clientID: id, resource: resource, autoRefresh: true, + refreshLock: &sync.RWMutex{}, refreshWithin: defaultRefresh, sender: &http.Client{}, refreshCallbacks: callbacks, @@ -213,6 +296,18 @@ func NewServicePrincipalTokenWithSecret(oauthConfig OAuthConfig, id string, reso // NewServicePrincipalTokenFromManualToken creates a ServicePrincipalToken using the supplied token func NewServicePrincipalTokenFromManualToken(oauthConfig OAuthConfig, clientID string, resource string, token Token, callbacks ...TokenRefreshCallback) (*ServicePrincipalToken, error) { + if err := validateOAuthConfig(oauthConfig); err != nil { + return nil, err + } + if err := validateStringParam(clientID, "clientID"); err != nil { + return nil, err + } + if err := validateStringParam(resource, "resource"); err != nil { + return nil, err + } + if token.IsZero() { + return nil, fmt.Errorf("parameter 'token' cannot be zero-initialized") + } spt, err := NewServicePrincipalTokenWithSecret( oauthConfig, clientID, @@ -223,7 +318,7 @@ func NewServicePrincipalTokenFromManualToken(oauthConfig OAuthConfig, clientID s return nil, err } - spt.Token = token + spt.token = token return spt, nil } @@ -231,6 +326,18 @@ func NewServicePrincipalTokenFromManualToken(oauthConfig OAuthConfig, clientID s // NewServicePrincipalToken creates a ServicePrincipalToken from the supplied Service Principal // credentials scoped to the named resource. func NewServicePrincipalToken(oauthConfig OAuthConfig, clientID string, secret string, resource string, callbacks ...TokenRefreshCallback) (*ServicePrincipalToken, error) { + if err := validateOAuthConfig(oauthConfig); err != nil { + return nil, err + } + if err := validateStringParam(clientID, "clientID"); err != nil { + return nil, err + } + if err := validateStringParam(secret, "secret"); err != nil { + return nil, err + } + if err := validateStringParam(resource, "resource"); err != nil { + return nil, err + } return NewServicePrincipalTokenWithSecret( oauthConfig, clientID, @@ -242,8 +349,23 @@ func NewServicePrincipalToken(oauthConfig OAuthConfig, clientID string, secret s ) } -// NewServicePrincipalTokenFromCertificate create a ServicePrincipalToken from the supplied pkcs12 bytes. +// NewServicePrincipalTokenFromCertificate creates a ServicePrincipalToken from the supplied pkcs12 bytes. func NewServicePrincipalTokenFromCertificate(oauthConfig OAuthConfig, clientID string, certificate *x509.Certificate, privateKey *rsa.PrivateKey, resource string, callbacks ...TokenRefreshCallback) (*ServicePrincipalToken, error) { + if err := validateOAuthConfig(oauthConfig); err != nil { + return nil, err + } + if err := validateStringParam(clientID, "clientID"); err != nil { + return nil, err + } + if err := validateStringParam(resource, "resource"); err != nil { + return nil, err + } + if certificate == nil { + return nil, fmt.Errorf("parameter 'certificate' cannot be nil") + } + if privateKey == nil { + return nil, fmt.Errorf("parameter 'privateKey' cannot be nil") + } return NewServicePrincipalTokenWithSecret( oauthConfig, clientID, @@ -256,59 +378,163 @@ func NewServicePrincipalTokenFromCertificate(oauthConfig OAuthConfig, clientID s ) } -// GetMSIVMEndpoint gets the MSI endpoint on Virtual Machines. -func GetMSIVMEndpoint() (string, error) { - return getMSIVMEndpoint(msiPath) +// NewServicePrincipalTokenFromUsernamePassword creates a ServicePrincipalToken from the username and password. +func NewServicePrincipalTokenFromUsernamePassword(oauthConfig OAuthConfig, clientID string, username string, password string, resource string, callbacks ...TokenRefreshCallback) (*ServicePrincipalToken, error) { + if err := validateOAuthConfig(oauthConfig); err != nil { + return nil, err + } + if err := validateStringParam(clientID, "clientID"); err != nil { + return nil, err + } + if err := validateStringParam(username, "username"); err != nil { + return nil, err + } + if err := validateStringParam(password, "password"); err != nil { + return nil, err + } + if err := validateStringParam(resource, "resource"); err != nil { + return nil, err + } + return NewServicePrincipalTokenWithSecret( + oauthConfig, + clientID, + resource, + &ServicePrincipalUsernamePasswordSecret{ + Username: username, + Password: password, + }, + callbacks..., + ) } -func getMSIVMEndpoint(path string) (string, error) { - // Read MSI settings - bytes, err := ioutil.ReadFile(path) - if err != nil { - return "", err +// NewServicePrincipalTokenFromAuthorizationCode creates a ServicePrincipalToken from the +func NewServicePrincipalTokenFromAuthorizationCode(oauthConfig OAuthConfig, clientID string, clientSecret string, authorizationCode string, redirectURI string, resource string, callbacks ...TokenRefreshCallback) (*ServicePrincipalToken, error) { + + if err := validateOAuthConfig(oauthConfig); err != nil { + return nil, err } - msiSettings := struct { - URL string `json:"url"` - }{} - err = json.Unmarshal(bytes, &msiSettings) - if err != nil { - return "", err + if err := validateStringParam(clientID, "clientID"); err != nil { + return nil, err + } + if err := validateStringParam(clientSecret, "clientSecret"); err != nil { + return nil, err + } + if err := validateStringParam(authorizationCode, "authorizationCode"); err != nil { + return nil, err + } + if err := validateStringParam(redirectURI, "redirectURI"); err != nil { + return nil, err + } + if err := validateStringParam(resource, "resource"); err != nil { + return nil, err } - return msiSettings.URL, nil + return NewServicePrincipalTokenWithSecret( + oauthConfig, + clientID, + resource, + &ServicePrincipalAuthorizationCodeSecret{ + ClientSecret: clientSecret, + AuthorizationCode: authorizationCode, + RedirectURI: redirectURI, + }, + callbacks..., + ) +} + +// GetMSIVMEndpoint gets the MSI endpoint on Virtual Machines. +func GetMSIVMEndpoint() (string, error) { + return msiEndpoint, nil } // NewServicePrincipalTokenFromMSI creates a ServicePrincipalToken via the MSI VM Extension. +// It will use the system assigned identity when creating the token. func NewServicePrincipalTokenFromMSI(msiEndpoint, resource string, callbacks ...TokenRefreshCallback) (*ServicePrincipalToken, error) { + return newServicePrincipalTokenFromMSI(msiEndpoint, resource, nil, callbacks...) +} + +// NewServicePrincipalTokenFromMSIWithUserAssignedID creates a ServicePrincipalToken via the MSI VM Extension. +// It will use the specified user assigned identity when creating the token. +func NewServicePrincipalTokenFromMSIWithUserAssignedID(msiEndpoint, resource string, userAssignedID string, callbacks ...TokenRefreshCallback) (*ServicePrincipalToken, error) { + return newServicePrincipalTokenFromMSI(msiEndpoint, resource, &userAssignedID, callbacks...) +} + +func newServicePrincipalTokenFromMSI(msiEndpoint, resource string, userAssignedID *string, callbacks ...TokenRefreshCallback) (*ServicePrincipalToken, error) { + if err := validateStringParam(msiEndpoint, "msiEndpoint"); err != nil { + return nil, err + } + if err := validateStringParam(resource, "resource"); err != nil { + return nil, err + } + if userAssignedID != nil { + if err := validateStringParam(*userAssignedID, "userAssignedID"); err != nil { + return nil, err + } + } // 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 + v := url.Values{} + v.Set("resource", resource) + v.Set("api-version", "2018-02-01") + if userAssignedID != nil { + v.Set("client_id", *userAssignedID) } + msiEndpointURL.RawQuery = v.Encode() spt := &ServicePrincipalToken{ - oauthConfig: *oauthConfig, + oauthConfig: OAuthConfig{ + TokenEndpoint: *msiEndpointURL, + }, secret: &ServicePrincipalMSISecret{}, resource: resource, autoRefresh: true, + refreshLock: &sync.RWMutex{}, refreshWithin: defaultRefresh, sender: &http.Client{}, refreshCallbacks: callbacks, } + if userAssignedID != nil { + spt.clientID = *userAssignedID + } + return spt, nil } +// internal type that implements TokenRefreshError +type tokenRefreshError struct { + message string + resp *http.Response +} + +// Error implements the error interface which is part of the TokenRefreshError interface. +func (tre tokenRefreshError) Error() string { + return tre.message +} + +// Response implements the TokenRefreshError interface, it returns the raw HTTP response from the refresh operation. +func (tre tokenRefreshError) Response() *http.Response { + return tre.resp +} + +func newTokenRefreshError(message string, resp *http.Response) TokenRefreshError { + return tokenRefreshError{message: message, resp: resp} +} + // EnsureFresh will refresh the token if it will expire within the refresh window (as set by -// RefreshWithin) and autoRefresh flag is on. +// RefreshWithin) and autoRefresh flag is on. This method is safe for concurrent use. func (spt *ServicePrincipalToken) EnsureFresh() error { - if spt.autoRefresh && spt.WillExpireIn(spt.refreshWithin) { - return spt.Refresh() + if spt.autoRefresh && spt.token.WillExpireIn(spt.refreshWithin) { + // take the write lock then check to see if the token was already refreshed + spt.refreshLock.Lock() + defer spt.refreshLock.Unlock() + if spt.token.WillExpireIn(spt.refreshWithin) { + return spt.refreshInternal(spt.resource) + } } return nil } @@ -317,7 +543,7 @@ func (spt *ServicePrincipalToken) EnsureFresh() error { func (spt *ServicePrincipalToken) InvokeRefreshCallbacks(token Token) error { if spt.refreshCallbacks != nil { for _, callback := range spt.refreshCallbacks { - err := callback(spt.Token) + err := callback(spt.token) if err != nil { return fmt.Errorf("adal: TokenRefreshCallback handler failed. Error = '%v'", err) } @@ -327,43 +553,74 @@ func (spt *ServicePrincipalToken) InvokeRefreshCallbacks(token Token) error { } // Refresh obtains a fresh token for the Service Principal. +// This method is not safe for concurrent use and should be syncrhonized. func (spt *ServicePrincipalToken) Refresh() error { + spt.refreshLock.Lock() + defer spt.refreshLock.Unlock() return spt.refreshInternal(spt.resource) } // RefreshExchange refreshes the token, but for a different resource. +// This method is not safe for concurrent use and should be syncrhonized. func (spt *ServicePrincipalToken) RefreshExchange(resource string) error { + spt.refreshLock.Lock() + defer spt.refreshLock.Unlock() return spt.refreshInternal(resource) } -func (spt *ServicePrincipalToken) refreshInternal(resource string) error { - v := url.Values{} - v.Set("client_id", spt.clientID) - v.Set("resource", resource) - - if spt.RefreshToken != "" { - v.Set("grant_type", OAuthGrantTypeRefreshToken) - v.Set("refresh_token", spt.RefreshToken) - } else { - v.Set("grant_type", OAuthGrantTypeClientCredentials) - err := spt.secret.SetAuthenticationValues(spt, &v) - if err != nil { - return err - } +func (spt *ServicePrincipalToken) getGrantType() string { + switch spt.secret.(type) { + case *ServicePrincipalUsernamePasswordSecret: + return OAuthGrantTypeUserPass + case *ServicePrincipalAuthorizationCodeSecret: + return OAuthGrantTypeAuthorizationCode + default: + return OAuthGrantTypeClientCredentials } +} - s := v.Encode() - body := ioutil.NopCloser(strings.NewReader(s)) - req, err := http.NewRequest(http.MethodPost, spt.oauthConfig.TokenEndpoint.String(), body) +func isIMDS(u url.URL) bool { + imds, err := url.Parse(msiEndpoint) + if err != nil { + return false + } + return u.Host == imds.Host && u.Path == imds.Path +} + +func (spt *ServicePrincipalToken) refreshInternal(resource string) error { + req, err := http.NewRequest(http.MethodPost, spt.oauthConfig.TokenEndpoint.String(), nil) if err != nil { return fmt.Errorf("adal: Failed to build the refresh request. Error = '%v'", err) } - req.ContentLength = int64(len(s)) - req.Header.Set(contentType, mimeTypeFormPost) + if !isIMDS(spt.oauthConfig.TokenEndpoint) { + v := url.Values{} + v.Set("client_id", spt.clientID) + v.Set("resource", resource) + + if spt.token.RefreshToken != "" { + v.Set("grant_type", OAuthGrantTypeRefreshToken) + v.Set("refresh_token", spt.token.RefreshToken) + } else { + v.Set("grant_type", spt.getGrantType()) + err := spt.secret.SetAuthenticationValues(spt, &v) + if err != nil { + return err + } + } + + s := v.Encode() + body := ioutil.NopCloser(strings.NewReader(s)) + req.ContentLength = int64(len(s)) + req.Header.Set(contentType, mimeTypeFormPost) + req.Body = body + } + if _, ok := spt.secret.(*ServicePrincipalMSISecret); ok { + req.Method = http.MethodGet req.Header.Set(metadataHeader, "true") } + resp, err := spt.sender.Do(req) if err != nil { return fmt.Errorf("adal: Failed to execute the refresh request. Error = '%v'", err) @@ -374,9 +631,9 @@ func (spt *ServicePrincipalToken) refreshInternal(resource string) error { 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 newTokenRefreshError(fmt.Sprintf("adal: Refresh request failed. Status Code = '%d'. Failed reading response body", resp.StatusCode), resp) } - return fmt.Errorf("adal: Refresh request failed. Status Code = '%d'. Response body: %s", resp.StatusCode, string(rb)) + return newTokenRefreshError(fmt.Sprintf("adal: Refresh request failed. Status Code = '%d'. Response body: %s", resp.StatusCode, string(rb)), resp) } if err != nil { @@ -391,7 +648,7 @@ func (spt *ServicePrincipalToken) refreshInternal(resource string) error { return fmt.Errorf("adal: Failed to unmarshal the service principal token during refresh. Error = '%v' JSON = '%s'", err, string(rb)) } - spt.Token = token + spt.token = token return spt.InvokeRefreshCallbacks(token) } @@ -411,3 +668,17 @@ func (spt *ServicePrincipalToken) SetRefreshWithin(d time.Duration) { // 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 Sender) { spt.sender = s } + +// OAuthToken implements the OAuthTokenProvider interface. It returns the current access token. +func (spt *ServicePrincipalToken) OAuthToken() string { + spt.refreshLock.RLock() + defer spt.refreshLock.RUnlock() + return spt.token.OAuthToken() +} + +// Token returns a copy of the current token. +func (spt *ServicePrincipalToken) Token() Token { + spt.refreshLock.RLock() + defer spt.refreshLock.RUnlock() + return spt.token +} diff --git a/vendor/github.com/Azure/go-autorest/autorest/authorization.go b/vendor/github.com/Azure/go-autorest/autorest/authorization.go index 314ed7876..c51eac0a7 100644 --- a/vendor/github.com/Azure/go-autorest/autorest/authorization.go +++ b/vendor/github.com/Azure/go-autorest/autorest/authorization.go @@ -1,5 +1,19 @@ 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 ( "fmt" "net/http" @@ -10,9 +24,12 @@ import ( ) const ( - bearerChallengeHeader = "Www-Authenticate" - bearer = "Bearer" - tenantID = "tenantID" + bearerChallengeHeader = "Www-Authenticate" + bearer = "Bearer" + tenantID = "tenantID" + apiKeyAuthorizerHeader = "Ocp-Apim-Subscription-Key" + bingAPISdkHeader = "X-BingApis-SDK-Client" + golangBingAPISdkHeaderValue = "Go-SDK" ) // Authorizer is the interface that provides a PrepareDecorator used to supply request @@ -30,6 +47,53 @@ func (na NullAuthorizer) WithAuthorization() PrepareDecorator { return WithNothing() } +// APIKeyAuthorizer implements API Key authorization. +type APIKeyAuthorizer struct { + headers map[string]interface{} + queryParameters map[string]interface{} +} + +// NewAPIKeyAuthorizerWithHeaders creates an ApiKeyAuthorizer with headers. +func NewAPIKeyAuthorizerWithHeaders(headers map[string]interface{}) *APIKeyAuthorizer { + return NewAPIKeyAuthorizer(headers, nil) +} + +// NewAPIKeyAuthorizerWithQueryParameters creates an ApiKeyAuthorizer with query parameters. +func NewAPIKeyAuthorizerWithQueryParameters(queryParameters map[string]interface{}) *APIKeyAuthorizer { + return NewAPIKeyAuthorizer(nil, queryParameters) +} + +// NewAPIKeyAuthorizer creates an ApiKeyAuthorizer with headers. +func NewAPIKeyAuthorizer(headers map[string]interface{}, queryParameters map[string]interface{}) *APIKeyAuthorizer { + return &APIKeyAuthorizer{headers: headers, queryParameters: queryParameters} +} + +// WithAuthorization returns a PrepareDecorator that adds an HTTP headers and Query Paramaters +func (aka *APIKeyAuthorizer) WithAuthorization() PrepareDecorator { + return func(p Preparer) Preparer { + return DecoratePreparer(p, WithHeaders(aka.headers), WithQueryParameters(aka.queryParameters)) + } +} + +// CognitiveServicesAuthorizer implements authorization for Cognitive Services. +type CognitiveServicesAuthorizer struct { + subscriptionKey string +} + +// NewCognitiveServicesAuthorizer is +func NewCognitiveServicesAuthorizer(subscriptionKey string) *CognitiveServicesAuthorizer { + return &CognitiveServicesAuthorizer{subscriptionKey: subscriptionKey} +} + +// WithAuthorization is +func (csa *CognitiveServicesAuthorizer) WithAuthorization() PrepareDecorator { + headers := make(map[string]interface{}) + headers[apiKeyAuthorizerHeader] = csa.subscriptionKey + headers[bingAPISdkHeader] = golangBingAPISdkHeaderValue + + return NewAPIKeyAuthorizerWithHeaders(headers).WithAuthorization() +} + // BearerAuthorizer implements the bearer authorization type BearerAuthorizer struct { tokenProvider adal.OAuthTokenProvider @@ -40,10 +104,6 @@ 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. // @@ -51,15 +111,23 @@ func (ba *BearerAuthorizer) withBearerAuthorization() PrepareDecorator { 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) + r, err := p.Prepare(r) + if err == nil { + refresher, ok := ba.tokenProvider.(adal.Refresher) + if ok { + err := refresher.EnsureFresh() + if err != nil { + var resp *http.Response + if tokError, ok := err.(adal.TokenRefreshError); ok { + resp = tokError.Response() + } + return r, NewErrorWithError(err, "azure.BearerAuthorizer", "WithAuthorization", resp, + "Failed to refresh the Token for request to %s", r.URL) + } } + return Prepare(r, WithHeader(headerAuthorization, fmt.Sprintf("Bearer %s", ba.tokenProvider.OAuthToken()))) } - return (ba.withBearerAuthorization()(p)).Prepare(r) + return r, err }) } } @@ -89,25 +157,28 @@ func NewBearerAuthorizerCallback(sender Sender, callback BearerAuthorizerCallbac 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) + r, err := p.Prepare(r) + if err == nil { + // 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"]) + 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 } - return ba.WithAuthorization()(p).Prepare(r) + if bacb.callback != nil { + ba, err := bacb.callback(bc.values[tenantID], bc.values["resource"]) + if err != nil { + return r, err + } + return Prepare(r, ba.WithAuthorization()) + } } } } @@ -165,3 +236,22 @@ func newBearerChallenge(resp *http.Response) (bc bearerChallenge, err error) { return bc, err } + +// EventGridKeyAuthorizer implements authorization for event grid using key authentication. +type EventGridKeyAuthorizer struct { + topicKey string +} + +// NewEventGridKeyAuthorizer creates a new EventGridKeyAuthorizer +// with the specified topic key. +func NewEventGridKeyAuthorizer(topicKey string) EventGridKeyAuthorizer { + return EventGridKeyAuthorizer{topicKey: topicKey} +} + +// WithAuthorization returns a PrepareDecorator that adds the aeg-sas-key authentication header. +func (egta EventGridKeyAuthorizer) WithAuthorization() PrepareDecorator { + headers := map[string]interface{}{ + "aeg-sas-key": egta.topicKey, + } + return NewAPIKeyAuthorizerWithHeaders(headers).WithAuthorization() +} diff --git a/vendor/github.com/Azure/go-autorest/autorest/autorest.go b/vendor/github.com/Azure/go-autorest/autorest/autorest.go index 51f1c4bbc..aafdf021f 100644 --- a/vendor/github.com/Azure/go-autorest/autorest/autorest.go +++ b/vendor/github.com/Azure/go-autorest/autorest/autorest.go @@ -57,7 +57,22 @@ generated clients, see the Client described below. */ 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 ( + "context" "net/http" "time" ) @@ -73,6 +88,9 @@ const ( // ResponseHasStatusCode returns true if the status code in the HTTP Response is in the passed set // and false otherwise. func ResponseHasStatusCode(resp *http.Response, codes ...int) bool { + if resp == nil { + return false + } return containsInt(codes, resp.StatusCode) } @@ -113,3 +131,20 @@ func NewPollingRequest(resp *http.Response, cancel <-chan struct{}) (*http.Reque return req, nil } + +// NewPollingRequestWithContext allocates and returns a new http.Request with the specified context to poll for the passed response. +func NewPollingRequestWithContext(ctx context.Context, resp *http.Response) (*http.Request, error) { + location := GetLocation(resp) + if location == "" { + return nil, NewErrorWithResponse("autorest", "NewPollingRequestWithContext", resp, "Location header missing from response that requires polling") + } + + req, err := Prepare((&http.Request{}).WithContext(ctx), + AsGet(), + WithBaseURL(location)) + if err != nil { + return nil, NewErrorWithError(err, "autorest", "NewPollingRequestWithContext", nil, "Failure creating poll request to %s", location) + } + + return req, nil +} diff --git a/vendor/github.com/Azure/go-autorest/autorest/azure/async.go b/vendor/github.com/Azure/go-autorest/autorest/azure/async.go index 332a8909d..a58e5ef3f 100644 --- a/vendor/github.com/Azure/go-autorest/autorest/azure/async.go +++ b/vendor/github.com/Azure/go-autorest/autorest/azure/async.go @@ -1,7 +1,23 @@ 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 ( "bytes" + "context" + "encoding/json" "fmt" "io/ioutil" "net/http" @@ -23,6 +39,184 @@ const ( operationSucceeded string = "Succeeded" ) +var pollingCodes = [...]int{http.StatusNoContent, http.StatusAccepted, http.StatusCreated, http.StatusOK} + +// Future provides a mechanism to access the status and results of an asynchronous request. +// Since futures are stateful they should be passed by value to avoid race conditions. +type Future struct { + req *http.Request + resp *http.Response + ps pollingState +} + +// NewFuture returns a new Future object initialized with the specified request. +func NewFuture(req *http.Request) Future { + return Future{req: req} +} + +// Response returns the last HTTP response or nil if there isn't one. +func (f Future) Response() *http.Response { + return f.resp +} + +// Status returns the last status message of the operation. +func (f Future) Status() string { + if f.ps.State == "" { + return "Unknown" + } + return f.ps.State +} + +// PollingMethod returns the method used to monitor the status of the asynchronous operation. +func (f Future) PollingMethod() PollingMethodType { + return f.ps.PollingMethod +} + +// Done queries the service to see if the operation has completed. +func (f *Future) Done(sender autorest.Sender) (bool, error) { + // exit early if this future has terminated + if f.ps.hasTerminated() { + return true, f.errorInfo() + } + resp, err := sender.Do(f.req) + f.resp = resp + if err != nil { + return false, err + } + + if !autorest.ResponseHasStatusCode(resp, pollingCodes[:]...) { + // check response body for error content + if resp.Body != nil { + type respErr struct { + ServiceError ServiceError `json:"error"` + } + re := respErr{} + + defer resp.Body.Close() + b, err := ioutil.ReadAll(resp.Body) + if err != nil { + return false, err + } + err = json.Unmarshal(b, &re) + if err != nil { + return false, err + } + return false, re.ServiceError + } + + // try to return something meaningful + return false, ServiceError{ + Code: fmt.Sprintf("%v", resp.StatusCode), + Message: resp.Status, + } + } + + err = updatePollingState(resp, &f.ps) + if err != nil { + return false, err + } + + if f.ps.hasTerminated() { + return true, f.errorInfo() + } + + f.req, err = newPollingRequest(f.ps) + return false, err +} + +// GetPollingDelay returns a duration the application should wait before checking +// the status of the asynchronous request and true; this value is returned from +// the service via the Retry-After response header. If the header wasn't returned +// then the function returns the zero-value time.Duration and false. +func (f Future) GetPollingDelay() (time.Duration, bool) { + if f.resp == nil { + return 0, false + } + + retry := f.resp.Header.Get(autorest.HeaderRetryAfter) + if retry == "" { + return 0, false + } + + d, err := time.ParseDuration(retry + "s") + if err != nil { + panic(err) + } + + return d, true +} + +// WaitForCompletion will return when one of the following conditions is met: the long +// running operation has completed, the provided context is cancelled, or the client's +// polling duration has been exceeded. It will retry failed polling attempts based on +// the retry value defined in the client up to the maximum retry attempts. +func (f Future) WaitForCompletion(ctx context.Context, client autorest.Client) error { + ctx, cancel := context.WithTimeout(ctx, client.PollingDuration) + defer cancel() + + done, err := f.Done(client) + for attempts := 0; !done; done, err = f.Done(client) { + if attempts >= client.RetryAttempts { + return autorest.NewErrorWithError(err, "azure", "WaitForCompletion", f.resp, "the number of retries has been exceeded") + } + // we want delayAttempt to be zero in the non-error case so + // that DelayForBackoff doesn't perform exponential back-off + var delayAttempt int + var delay time.Duration + if err == nil { + // check for Retry-After delay, if not present use the client's polling delay + var ok bool + delay, ok = f.GetPollingDelay() + if !ok { + delay = client.PollingDelay + } + } else { + // there was an error polling for status so perform exponential + // back-off based on the number of attempts using the client's retry + // duration. update attempts after delayAttempt to avoid off-by-one. + delayAttempt = attempts + delay = client.RetryDuration + attempts++ + } + // wait until the delay elapses or the context is cancelled + delayElapsed := autorest.DelayForBackoff(delay, delayAttempt, ctx.Done()) + if !delayElapsed { + return autorest.NewErrorWithError(ctx.Err(), "azure", "WaitForCompletion", f.resp, "context has been cancelled") + } + } + return err +} + +// if the operation failed the polling state will contain +// error information and implements the error interface +func (f *Future) errorInfo() error { + if !f.ps.hasSucceeded() { + return f.ps + } + return nil +} + +// MarshalJSON implements the json.Marshaler interface. +func (f Future) MarshalJSON() ([]byte, error) { + return json.Marshal(&f.ps) +} + +// UnmarshalJSON implements the json.Unmarshaler interface. +func (f *Future) UnmarshalJSON(data []byte) error { + err := json.Unmarshal(data, &f.ps) + if err != nil { + return err + } + f.req, err = newPollingRequest(f.ps) + return err +} + +// PollingURL returns the URL used for retrieving the status of the long-running operation. +// For LROs that use the Location header the final URL value is used to retrieve the result. +func (f Future) PollingURL() string { + return f.ps.URI +} + // DoPollForAsynchronous returns a SendDecorator that polls if the http.Response is for an Azure // long-running operation. It will delay between requests for the duration specified in the // RetryAfter header or, if the header is absent, the passed delay. Polling may be canceled by @@ -34,8 +228,7 @@ func DoPollForAsynchronous(delay time.Duration) autorest.SendDecorator { if err != nil { return resp, err } - pollingCodes := []int{http.StatusAccepted, http.StatusCreated, http.StatusOK} - if !autorest.ResponseHasStatusCode(resp, pollingCodes...) { + if !autorest.ResponseHasStatusCode(resp, pollingCodes[:]...) { return resp, nil } @@ -52,10 +245,11 @@ func DoPollForAsynchronous(delay time.Duration) autorest.SendDecorator { break } - r, err = newPollingRequest(resp, ps) + r, err = newPollingRequest(ps) if err != nil { return resp, err } + r = r.WithContext(resp.Request.Context()) delay = autorest.GetRetryAfter(resp, delay) resp, err = autorest.SendWithSender(s, r, @@ -72,20 +266,15 @@ func getAsyncOperation(resp *http.Response) string { } func hasSucceeded(state string) bool { - return state == operationSucceeded + return strings.EqualFold(state, operationSucceeded) } func hasTerminated(state string) bool { - switch state { - case operationCanceled, operationFailed, operationSucceeded: - return true - default: - return false - } + return strings.EqualFold(state, operationCanceled) || strings.EqualFold(state, operationFailed) || strings.EqualFold(state, operationSucceeded) } func hasFailed(state string) bool { - return state == operationFailed + return strings.EqualFold(state, operationFailed) } type provisioningTracker interface { @@ -143,39 +332,50 @@ func (ps provisioningStatus) hasTerminated() bool { } func (ps provisioningStatus) hasProvisioningError() bool { - return ps.ProvisioningError != ServiceError{} + // code and message are required fields so only check them + return len(ps.ProvisioningError.Code) > 0 || + len(ps.ProvisioningError.Message) > 0 } -type pollingResponseFormat string +// PollingMethodType defines a type used for enumerating polling mechanisms. +type PollingMethodType string const ( - usesOperationResponse pollingResponseFormat = "OperationResponse" - usesProvisioningStatus pollingResponseFormat = "ProvisioningStatus" - formatIsUnknown pollingResponseFormat = "" + // PollingAsyncOperation indicates the polling method uses the Azure-AsyncOperation header. + PollingAsyncOperation PollingMethodType = "AsyncOperation" + + // PollingLocation indicates the polling method uses the Location header. + PollingLocation PollingMethodType = "Location" + + // PollingUnknown indicates an unknown polling method and is the default value. + PollingUnknown PollingMethodType = "" ) type pollingState struct { - responseFormat pollingResponseFormat - uri string - state string - code string - message string + PollingMethod PollingMethodType `json:"pollingMethod"` + URI string `json:"uri"` + State string `json:"state"` + ServiceError *ServiceError `json:"error,omitempty"` } func (ps pollingState) hasSucceeded() bool { - return hasSucceeded(ps.state) + return hasSucceeded(ps.State) } func (ps pollingState) hasTerminated() bool { - return hasTerminated(ps.state) + return hasTerminated(ps.State) } func (ps pollingState) hasFailed() bool { - return hasFailed(ps.state) + return hasFailed(ps.State) } func (ps pollingState) Error() string { - return fmt.Sprintf("Long running operation terminated with status '%s': Code=%q Message=%q", ps.state, ps.code, ps.message) + s := fmt.Sprintf("Long running operation terminated with status '%s'", ps.State) + if ps.ServiceError != nil { + s = fmt.Sprintf("%s: %+v", s, *ps.ServiceError) + } + return s } // updatePollingState maps the operation status -- retrieved from either a provisioningState @@ -190,7 +390,7 @@ func updatePollingState(resp *http.Response, ps *pollingState) error { // -- The first response will always be a provisioningStatus response; only the polling requests, // depending on the header returned, may be something otherwise. var pt provisioningTracker - if ps.responseFormat == usesOperationResponse { + if ps.PollingMethod == PollingAsyncOperation { pt = &operationResource{} } else { pt = &provisioningStatus{} @@ -198,30 +398,30 @@ func updatePollingState(resp *http.Response, ps *pollingState) error { // If this is the first request (that is, the polling response shape is unknown), determine how // to poll and what to expect - if ps.responseFormat == formatIsUnknown { + if ps.PollingMethod == PollingUnknown { req := resp.Request if req == nil { return autorest.NewError("azure", "updatePollingState", "Azure Polling Error - Original HTTP request is missing") } // Prefer the Azure-AsyncOperation header - ps.uri = getAsyncOperation(resp) - if ps.uri != "" { - ps.responseFormat = usesOperationResponse + ps.URI = getAsyncOperation(resp) + if ps.URI != "" { + ps.PollingMethod = PollingAsyncOperation } else { - ps.responseFormat = usesProvisioningStatus + ps.PollingMethod = PollingLocation } // Else, use the Location header - if ps.uri == "" { - ps.uri = autorest.GetLocation(resp) + if ps.URI == "" { + ps.URI = autorest.GetLocation(resp) } // Lastly, requests against an existing resource, use the last request URI - if ps.uri == "" { + if ps.URI == "" { m := strings.ToUpper(req.Method) if m == http.MethodPatch || m == http.MethodPut || m == http.MethodGet { - ps.uri = req.URL.String() + ps.URI = req.URL.String() } } } @@ -242,23 +442,23 @@ func updatePollingState(resp *http.Response, ps *pollingState) error { // -- Unknown states are per-service inprogress states // -- Otherwise, infer state from HTTP status code if pt.hasTerminated() { - ps.state = pt.state() + ps.State = pt.state() } else if pt.state() != "" { - ps.state = operationInProgress + ps.State = operationInProgress } else { switch resp.StatusCode { case http.StatusAccepted: - ps.state = operationInProgress + ps.State = operationInProgress case http.StatusNoContent, http.StatusCreated, http.StatusOK: - ps.state = operationSucceeded + ps.State = operationSucceeded default: - ps.state = operationFailed + ps.State = operationFailed } } - if ps.state == operationInProgress && ps.uri == "" { + if strings.EqualFold(ps.State, operationInProgress) && ps.URI == "" { return autorest.NewError("azure", "updatePollingState", "Azure Polling Error - Unable to obtain polling URI for %s %s", resp.Request.Method, resp.Request.URL) } @@ -267,36 +467,45 @@ func updatePollingState(resp *http.Response, ps *pollingState) error { // -- Response // -- Otherwise, Unknown if ps.hasFailed() { - if ps.responseFormat == usesOperationResponse { - or := pt.(*operationResource) - ps.code = or.OperationError.Code - ps.message = or.OperationError.Message + if or, ok := pt.(*operationResource); ok { + ps.ServiceError = &or.OperationError + } else if p, ok := pt.(*provisioningStatus); ok && p.hasProvisioningError() { + ps.ServiceError = &p.ProvisioningError } else { - p := pt.(*provisioningStatus) - if p.hasProvisioningError() { - ps.code = p.ProvisioningError.Code - ps.message = p.ProvisioningError.Message - } else { - ps.code = "Unknown" - ps.message = "None" + ps.ServiceError = &ServiceError{ + Code: "Unknown", + Message: "None", } } } return nil } -func newPollingRequest(resp *http.Response, ps pollingState) (*http.Request, error) { - req := resp.Request - if req == nil { - return nil, autorest.NewError("azure", "newPollingRequest", "Azure Polling Error - Original HTTP request is missing") - } - - reqPoll, err := autorest.Prepare(&http.Request{Cancel: req.Cancel}, +func newPollingRequest(ps pollingState) (*http.Request, error) { + reqPoll, err := autorest.Prepare(&http.Request{}, autorest.AsGet(), - autorest.WithBaseURL(ps.uri)) + autorest.WithBaseURL(ps.URI)) if err != nil { - return nil, autorest.NewErrorWithError(err, "azure", "newPollingRequest", nil, "Failure creating poll request to %s", ps.uri) + return nil, autorest.NewErrorWithError(err, "azure", "newPollingRequest", nil, "Failure creating poll request to %s", ps.URI) } return reqPoll, nil } + +// AsyncOpIncompleteError is the type that's returned from a future that has not completed. +type AsyncOpIncompleteError struct { + // FutureType is the name of the type composed of a azure.Future. + FutureType string +} + +// Error returns an error message including the originating type name of the error. +func (e AsyncOpIncompleteError) Error() string { + return fmt.Sprintf("%s: asynchronous operation has not completed", e.FutureType) +} + +// NewAsyncOpIncompleteError creates a new AsyncOpIncompleteError with the specified parameters. +func NewAsyncOpIncompleteError(futureType string) AsyncOpIncompleteError { + return AsyncOpIncompleteError{ + FutureType: futureType, + } +} diff --git a/vendor/github.com/Azure/go-autorest/autorest/azure/azure.go b/vendor/github.com/Azure/go-autorest/autorest/azure/azure.go index 3f4d13421..18d029526 100644 --- a/vendor/github.com/Azure/go-autorest/autorest/azure/azure.go +++ b/vendor/github.com/Azure/go-autorest/autorest/azure/azure.go @@ -1,16 +1,29 @@ -/* -Package azure provides Azure-specific implementations used with AutoRest. - -See the included examples for more detail. -*/ +// Package azure provides Azure-specific implementations used with AutoRest. +// See the included examples for more detail. 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 ( "encoding/json" "fmt" "io/ioutil" "net/http" + "regexp" "strconv" + "strings" "github.com/Azure/go-autorest/autorest" ) @@ -29,21 +42,88 @@ const ( ) // ServiceError encapsulates the error response from an Azure service. +// It adhears to the OData v4 specification for error responses. type ServiceError struct { - Code string `json:"code"` - Message string `json:"message"` - Details *[]interface{} `json:"details"` + Code string `json:"code"` + Message string `json:"message"` + Target *string `json:"target"` + Details []map[string]interface{} `json:"details"` + InnerError map[string]interface{} `json:"innererror"` } func (se ServiceError) Error() string { - if se.Details != nil { - d, err := json.Marshal(*(se.Details)) - if err != nil { - return fmt.Sprintf("Code=%q Message=%q Details=%v", se.Code, se.Message, *se.Details) - } - return fmt.Sprintf("Code=%q Message=%q Details=%v", se.Code, se.Message, string(d)) + result := fmt.Sprintf("Code=%q Message=%q", se.Code, se.Message) + + if se.Target != nil { + result += fmt.Sprintf(" Target=%q", *se.Target) } - return fmt.Sprintf("Code=%q Message=%q", se.Code, se.Message) + + if se.Details != nil { + d, err := json.Marshal(se.Details) + if err != nil { + result += fmt.Sprintf(" Details=%v", se.Details) + } + result += fmt.Sprintf(" Details=%v", string(d)) + } + + if se.InnerError != nil { + d, err := json.Marshal(se.InnerError) + if err != nil { + result += fmt.Sprintf(" InnerError=%v", se.InnerError) + } + result += fmt.Sprintf(" InnerError=%v", string(d)) + } + + return result +} + +// UnmarshalJSON implements the json.Unmarshaler interface for the ServiceError type. +func (se *ServiceError) UnmarshalJSON(b []byte) error { + // per the OData v4 spec the details field must be an array of JSON objects. + // unfortunately not all services adhear to the spec and just return a single + // object instead of an array with one object. so we have to perform some + // shenanigans to accommodate both cases. + // http://docs.oasis-open.org/odata/odata-json-format/v4.0/os/odata-json-format-v4.0-os.html#_Toc372793091 + + type serviceError1 struct { + Code string `json:"code"` + Message string `json:"message"` + Target *string `json:"target"` + Details []map[string]interface{} `json:"details"` + InnerError map[string]interface{} `json:"innererror"` + } + + type serviceError2 struct { + Code string `json:"code"` + Message string `json:"message"` + Target *string `json:"target"` + Details map[string]interface{} `json:"details"` + InnerError map[string]interface{} `json:"innererror"` + } + + se1 := serviceError1{} + err := json.Unmarshal(b, &se1) + if err == nil { + se.populate(se1.Code, se1.Message, se1.Target, se1.Details, se1.InnerError) + return nil + } + + se2 := serviceError2{} + err = json.Unmarshal(b, &se2) + if err == nil { + se.populate(se2.Code, se2.Message, se2.Target, nil, se2.InnerError) + se.Details = append(se.Details, se2.Details) + return nil + } + return err +} + +func (se *ServiceError) populate(code, message string, target *string, details []map[string]interface{}, inner map[string]interface{}) { + se.Code = code + se.Message = message + se.Target = target + se.Details = details + se.InnerError = inner } // RequestError describes an error response returned by Azure service. @@ -69,6 +149,41 @@ func IsAzureError(e error) bool { return ok } +// Resource contains details about an Azure resource. +type Resource struct { + SubscriptionID string + ResourceGroup string + Provider string + ResourceType string + ResourceName string +} + +// ParseResourceID parses a resource ID into a ResourceDetails struct. +// See https://docs.microsoft.com/en-us/azure/azure-resource-manager/resource-group-template-functions-resource#return-value-4. +func ParseResourceID(resourceID string) (Resource, error) { + + const resourceIDPatternText = `(?i)subscriptions/(.+)/resourceGroups/(.+)/providers/(.+?)/(.+?)/(.+)` + resourceIDPattern := regexp.MustCompile(resourceIDPatternText) + match := resourceIDPattern.FindStringSubmatch(resourceID) + + if len(match) == 0 { + return Resource{}, fmt.Errorf("parsing failed for %s. Invalid resource Id format", resourceID) + } + + v := strings.Split(match[5], "/") + resourceName := v[len(v)-1] + + result := Resource{ + SubscriptionID: match[1], + ResourceGroup: match[2], + Provider: match[3], + ResourceType: match[4], + ResourceName: resourceName, + } + + return result, nil +} + // NewErrorWithError creates a new Error conforming object from the // passed packageType, method, statusCode of the given resp (UndefinedStatusCode // if resp is nil), message, and original error. message is treated as a format @@ -165,7 +280,13 @@ func WithErrorUnlessStatusCode(codes ...int) autorest.RespondDecorator { if decodeErr != nil { return fmt.Errorf("autorest/azure: error response cannot be parsed: %q error: %v", b.String(), decodeErr) } 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) diff --git a/vendor/github.com/Azure/go-autorest/autorest/azure/environments.go b/vendor/github.com/Azure/go-autorest/autorest/azure/environments.go index 1cf55651f..7e41f7fd9 100644 --- a/vendor/github.com/Azure/go-autorest/autorest/azure/environments.go +++ b/vendor/github.com/Azure/go-autorest/autorest/azure/environments.go @@ -1,10 +1,31 @@ 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 ( + "encoding/json" "fmt" + "io/ioutil" + "os" "strings" ) +// EnvironmentFilepathName captures the name of the environment variable containing the path to the file +// to be used while populating the Azure Environment. +const EnvironmentFilepathName = "AZURE_ENVIRONMENT_FILEPATH" + var environments = map[string]Environment{ "AZURECHINACLOUD": ChinaCloud, "AZUREGERMANCLOUD": GermanCloud, @@ -23,6 +44,8 @@ type Environment struct { GalleryEndpoint string `json:"galleryEndpoint"` KeyVaultEndpoint string `json:"keyVaultEndpoint"` GraphEndpoint string `json:"graphEndpoint"` + ServiceBusEndpoint string `json:"serviceBusEndpoint"` + BatchManagementEndpoint string `json:"batchManagementEndpoint"` StorageEndpointSuffix string `json:"storageEndpointSuffix"` SQLDatabaseDNSSuffix string `json:"sqlDatabaseDNSSuffix"` TrafficManagerDNSSuffix string `json:"trafficManagerDNSSuffix"` @@ -31,6 +54,7 @@ type Environment struct { ServiceManagementVMDNSSuffix string `json:"serviceManagementVMDNSSuffix"` ResourceManagerVMDNSSuffix string `json:"resourceManagerVMDNSSuffix"` ContainerRegistryDNSSuffix string `json:"containerRegistryDNSSuffix"` + TokenAudience string `json:"tokenAudience"` } var ( @@ -45,14 +69,17 @@ var ( GalleryEndpoint: "https://gallery.azure.com/", KeyVaultEndpoint: "https://vault.azure.net/", GraphEndpoint: "https://graph.windows.net/", + ServiceBusEndpoint: "https://servicebus.windows.net/", + BatchManagementEndpoint: "https://batch.core.windows.net/", StorageEndpointSuffix: "core.windows.net", SQLDatabaseDNSSuffix: "database.windows.net", TrafficManagerDNSSuffix: "trafficmanager.net", KeyVaultDNSSuffix: "vault.azure.net", - ServiceBusEndpointSuffix: "servicebus.azure.com", + ServiceBusEndpointSuffix: "servicebus.windows.net", ServiceManagementVMDNSSuffix: "cloudapp.net", ResourceManagerVMDNSSuffix: "cloudapp.azure.com", ContainerRegistryDNSSuffix: "azurecr.io", + TokenAudience: "https://management.azure.com/", } // USGovernmentCloud is the cloud environment for the US Government @@ -62,10 +89,12 @@ var ( PublishSettingsURL: "https://manage.windowsazure.us/publishsettings/index", ServiceManagementEndpoint: "https://management.core.usgovcloudapi.net/", ResourceManagerEndpoint: "https://management.usgovcloudapi.net/", - ActiveDirectoryEndpoint: "https://login.microsoftonline.com/", + ActiveDirectoryEndpoint: "https://login.microsoftonline.us/", GalleryEndpoint: "https://gallery.usgovcloudapi.net/", KeyVaultEndpoint: "https://vault.usgovcloudapi.net/", - GraphEndpoint: "https://graph.usgovcloudapi.net/", + GraphEndpoint: "https://graph.windows.net/", + ServiceBusEndpoint: "https://servicebus.usgovcloudapi.net/", + BatchManagementEndpoint: "https://batch.core.usgovcloudapi.net/", StorageEndpointSuffix: "core.usgovcloudapi.net", SQLDatabaseDNSSuffix: "database.usgovcloudapi.net", TrafficManagerDNSSuffix: "usgovtrafficmanager.net", @@ -74,6 +103,7 @@ var ( ServiceManagementVMDNSSuffix: "usgovcloudapp.net", ResourceManagerVMDNSSuffix: "cloudapp.windowsazure.us", ContainerRegistryDNSSuffix: "azurecr.io", + TokenAudience: "https://management.usgovcloudapi.net/", } // ChinaCloud is the cloud environment operated in China @@ -87,14 +117,17 @@ var ( GalleryEndpoint: "https://gallery.chinacloudapi.cn/", KeyVaultEndpoint: "https://vault.azure.cn/", GraphEndpoint: "https://graph.chinacloudapi.cn/", + ServiceBusEndpoint: "https://servicebus.chinacloudapi.cn/", + BatchManagementEndpoint: "https://batch.chinacloudapi.cn/", StorageEndpointSuffix: "core.chinacloudapi.cn", SQLDatabaseDNSSuffix: "database.chinacloudapi.cn", TrafficManagerDNSSuffix: "trafficmanager.cn", KeyVaultDNSSuffix: "vault.azure.cn", - ServiceBusEndpointSuffix: "servicebus.chinacloudapi.net", + ServiceBusEndpointSuffix: "servicebus.chinacloudapi.cn", ServiceManagementVMDNSSuffix: "chinacloudapp.cn", ResourceManagerVMDNSSuffix: "cloudapp.azure.cn", ContainerRegistryDNSSuffix: "azurecr.io", + TokenAudience: "https://management.chinacloudapi.cn/", } // GermanCloud is the cloud environment operated in Germany @@ -108,6 +141,8 @@ var ( GalleryEndpoint: "https://gallery.cloudapi.de/", KeyVaultEndpoint: "https://vault.microsoftazure.de/", GraphEndpoint: "https://graph.cloudapi.de/", + ServiceBusEndpoint: "https://servicebus.cloudapi.de/", + BatchManagementEndpoint: "https://batch.cloudapi.de/", StorageEndpointSuffix: "core.cloudapi.de", SQLDatabaseDNSSuffix: "database.cloudapi.de", TrafficManagerDNSSuffix: "azuretrafficmanager.de", @@ -116,15 +151,41 @@ var ( ServiceManagementVMDNSSuffix: "azurecloudapp.de", ResourceManagerVMDNSSuffix: "cloudapp.microsoftazure.de", ContainerRegistryDNSSuffix: "azurecr.io", + TokenAudience: "https://management.microsoftazure.de/", } ) -// EnvironmentFromName returns an Environment based on the common name specified +// EnvironmentFromName returns an Environment based on the common name specified. func EnvironmentFromName(name string) (Environment, error) { + // IMPORTANT + // As per @radhikagupta5: + // This is technical debt, fundamentally here because Kubernetes is not currently accepting + // contributions to the providers. Once that is an option, the provider should be updated to + // directly call `EnvironmentFromFile`. Until then, we rely on dispatching Azure Stack environment creation + // from this method based on the name that is provided to us. + if strings.EqualFold(name, "AZURESTACKCLOUD") { + return EnvironmentFromFile(os.Getenv(EnvironmentFilepathName)) + } + name = strings.ToUpper(name) env, ok := environments[name] if !ok { return env, fmt.Errorf("autorest/azure: There is no cloud environment matching the name %q", name) } + return env, nil } + +// EnvironmentFromFile loads an Environment from a configuration file available on disk. +// This function is particularly useful in the Hybrid Cloud model, where one must define their own +// endpoints. +func EnvironmentFromFile(location string) (unmarshaled Environment, err error) { + fileContents, err := ioutil.ReadFile(location) + if err != nil { + return + } + + err = json.Unmarshal(fileContents, &unmarshaled) + + return +} diff --git a/vendor/github.com/Azure/go-autorest/autorest/azure/metadata_environment.go b/vendor/github.com/Azure/go-autorest/autorest/azure/metadata_environment.go new file mode 100644 index 000000000..507f9e95c --- /dev/null +++ b/vendor/github.com/Azure/go-autorest/autorest/azure/metadata_environment.go @@ -0,0 +1,245 @@ +package azure + +import ( + "encoding/json" + "fmt" + "io/ioutil" + "net/http" + "strings" + + "github.com/Azure/go-autorest/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. + +type audience []string + +type authentication struct { + LoginEndpoint string `json:"loginEndpoint"` + Audiences audience `json:"audiences"` +} + +type environmentMetadataInfo struct { + GalleryEndpoint string `json:"galleryEndpoint"` + GraphEndpoint string `json:"graphEndpoint"` + PortalEndpoint string `json:"portalEndpoint"` + Authentication authentication `json:"authentication"` +} + +// EnvironmentProperty represent property names that clients can override +type EnvironmentProperty string + +const ( + // EnvironmentName ... + EnvironmentName EnvironmentProperty = "name" + // EnvironmentManagementPortalURL .. + EnvironmentManagementPortalURL EnvironmentProperty = "managementPortalURL" + // EnvironmentPublishSettingsURL ... + EnvironmentPublishSettingsURL EnvironmentProperty = "publishSettingsURL" + // EnvironmentServiceManagementEndpoint ... + EnvironmentServiceManagementEndpoint EnvironmentProperty = "serviceManagementEndpoint" + // EnvironmentResourceManagerEndpoint ... + EnvironmentResourceManagerEndpoint EnvironmentProperty = "resourceManagerEndpoint" + // EnvironmentActiveDirectoryEndpoint ... + EnvironmentActiveDirectoryEndpoint EnvironmentProperty = "activeDirectoryEndpoint" + // EnvironmentGalleryEndpoint ... + EnvironmentGalleryEndpoint EnvironmentProperty = "galleryEndpoint" + // EnvironmentKeyVaultEndpoint ... + EnvironmentKeyVaultEndpoint EnvironmentProperty = "keyVaultEndpoint" + // EnvironmentGraphEndpoint ... + EnvironmentGraphEndpoint EnvironmentProperty = "graphEndpoint" + // EnvironmentServiceBusEndpoint ... + EnvironmentServiceBusEndpoint EnvironmentProperty = "serviceBusEndpoint" + // EnvironmentBatchManagementEndpoint ... + EnvironmentBatchManagementEndpoint EnvironmentProperty = "batchManagementEndpoint" + // EnvironmentStorageEndpointSuffix ... + EnvironmentStorageEndpointSuffix EnvironmentProperty = "storageEndpointSuffix" + // EnvironmentSQLDatabaseDNSSuffix ... + EnvironmentSQLDatabaseDNSSuffix EnvironmentProperty = "sqlDatabaseDNSSuffix" + // EnvironmentTrafficManagerDNSSuffix ... + EnvironmentTrafficManagerDNSSuffix EnvironmentProperty = "trafficManagerDNSSuffix" + // EnvironmentKeyVaultDNSSuffix ... + EnvironmentKeyVaultDNSSuffix EnvironmentProperty = "keyVaultDNSSuffix" + // EnvironmentServiceBusEndpointSuffix ... + EnvironmentServiceBusEndpointSuffix EnvironmentProperty = "serviceBusEndpointSuffix" + // EnvironmentServiceManagementVMDNSSuffix ... + EnvironmentServiceManagementVMDNSSuffix EnvironmentProperty = "serviceManagementVMDNSSuffix" + // EnvironmentResourceManagerVMDNSSuffix ... + EnvironmentResourceManagerVMDNSSuffix EnvironmentProperty = "resourceManagerVMDNSSuffix" + // EnvironmentContainerRegistryDNSSuffix ... + EnvironmentContainerRegistryDNSSuffix EnvironmentProperty = "containerRegistryDNSSuffix" + // EnvironmentTokenAudience ... + EnvironmentTokenAudience EnvironmentProperty = "tokenAudience" +) + +// OverrideProperty represents property name and value that clients can override +type OverrideProperty struct { + Key EnvironmentProperty + Value string +} + +// EnvironmentFromURL loads an Environment from a URL +// This function is particularly useful in the Hybrid Cloud model, where one may define their own +// endpoints. +func EnvironmentFromURL(resourceManagerEndpoint string, properties ...OverrideProperty) (environment Environment, err error) { + var metadataEnvProperties environmentMetadataInfo + + if resourceManagerEndpoint == "" { + return environment, fmt.Errorf("Metadata resource manager endpoint is empty") + } + + if metadataEnvProperties, err = retrieveMetadataEnvironment(resourceManagerEndpoint); err != nil { + return environment, err + } + + // Give priority to user's override values + overrideProperties(&environment, properties) + + if environment.Name == "" { + environment.Name = "HybridEnvironment" + } + stampDNSSuffix := environment.StorageEndpointSuffix + if stampDNSSuffix == "" { + stampDNSSuffix = strings.TrimSuffix(strings.TrimPrefix(strings.Replace(resourceManagerEndpoint, strings.Split(resourceManagerEndpoint, ".")[0], "", 1), "."), "/") + environment.StorageEndpointSuffix = stampDNSSuffix + } + if environment.KeyVaultDNSSuffix == "" { + environment.KeyVaultDNSSuffix = fmt.Sprintf("%s.%s", "vault", stampDNSSuffix) + } + if environment.KeyVaultEndpoint == "" { + environment.KeyVaultEndpoint = fmt.Sprintf("%s%s", "https://", environment.KeyVaultDNSSuffix) + } + if environment.TokenAudience == "" { + environment.TokenAudience = metadataEnvProperties.Authentication.Audiences[0] + } + if environment.ActiveDirectoryEndpoint == "" { + environment.ActiveDirectoryEndpoint = metadataEnvProperties.Authentication.LoginEndpoint + } + if environment.ResourceManagerEndpoint == "" { + environment.ResourceManagerEndpoint = resourceManagerEndpoint + } + if environment.GalleryEndpoint == "" { + environment.GalleryEndpoint = metadataEnvProperties.GalleryEndpoint + } + if environment.GraphEndpoint == "" { + environment.GraphEndpoint = metadataEnvProperties.GraphEndpoint + } + + return environment, nil +} + +func overrideProperties(environment *Environment, properties []OverrideProperty) { + for _, property := range properties { + switch property.Key { + case EnvironmentName: + { + environment.Name = property.Value + } + case EnvironmentManagementPortalURL: + { + environment.ManagementPortalURL = property.Value + } + case EnvironmentPublishSettingsURL: + { + environment.PublishSettingsURL = property.Value + } + case EnvironmentServiceManagementEndpoint: + { + environment.ServiceManagementEndpoint = property.Value + } + case EnvironmentResourceManagerEndpoint: + { + environment.ResourceManagerEndpoint = property.Value + } + case EnvironmentActiveDirectoryEndpoint: + { + environment.ActiveDirectoryEndpoint = property.Value + } + case EnvironmentGalleryEndpoint: + { + environment.GalleryEndpoint = property.Value + } + case EnvironmentKeyVaultEndpoint: + { + environment.KeyVaultEndpoint = property.Value + } + case EnvironmentGraphEndpoint: + { + environment.GraphEndpoint = property.Value + } + case EnvironmentServiceBusEndpoint: + { + environment.ServiceBusEndpoint = property.Value + } + case EnvironmentBatchManagementEndpoint: + { + environment.BatchManagementEndpoint = property.Value + } + case EnvironmentStorageEndpointSuffix: + { + environment.StorageEndpointSuffix = property.Value + } + case EnvironmentSQLDatabaseDNSSuffix: + { + environment.SQLDatabaseDNSSuffix = property.Value + } + case EnvironmentTrafficManagerDNSSuffix: + { + environment.TrafficManagerDNSSuffix = property.Value + } + case EnvironmentKeyVaultDNSSuffix: + { + environment.KeyVaultDNSSuffix = property.Value + } + case EnvironmentServiceBusEndpointSuffix: + { + environment.ServiceBusEndpointSuffix = property.Value + } + case EnvironmentServiceManagementVMDNSSuffix: + { + environment.ServiceManagementVMDNSSuffix = property.Value + } + case EnvironmentResourceManagerVMDNSSuffix: + { + environment.ResourceManagerVMDNSSuffix = property.Value + } + case EnvironmentContainerRegistryDNSSuffix: + { + environment.ContainerRegistryDNSSuffix = property.Value + } + case EnvironmentTokenAudience: + { + environment.TokenAudience = property.Value + } + } + } +} + +func retrieveMetadataEnvironment(endpoint string) (environment environmentMetadataInfo, err error) { + client := autorest.NewClientWithUserAgent("") + managementEndpoint := fmt.Sprintf("%s%s", strings.TrimSuffix(endpoint, "/"), "/metadata/endpoints?api-version=1.0") + req, _ := http.NewRequest("GET", managementEndpoint, nil) + response, err := client.Do(req) + if err != nil { + return environment, err + } + defer response.Body.Close() + jsonResponse, err := ioutil.ReadAll(response.Body) + if err != nil { + return environment, err + } + err = json.Unmarshal(jsonResponse, &environment) + return environment, err +} diff --git a/vendor/github.com/Azure/go-autorest/autorest/azure/rp.go b/vendor/github.com/Azure/go-autorest/autorest/azure/rp.go new file mode 100644 index 000000000..65ad0afc8 --- /dev/null +++ b/vendor/github.com/Azure/go-autorest/autorest/azure/rp.go @@ -0,0 +1,200 @@ +// 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 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 || client.SkipResourceProviderRegistration { + return resp, err + } + var re RequestError + err = autorest.Respond( + resp, + autorest.ByUnmarshallingJSON(&re), + ) + if err != nil { + return resp, err + } + err = re + + if re.ServiceError != nil && re.ServiceError.Code == "MissingSubscriptionRegistration" { + regErr := register(client, r, re) + if regErr != nil { + return resp, fmt.Errorf("failed auto registering Resource Provider: %s. Original error: %s", regErr, err) + } + } + } + return resp, fmt.Errorf("failed request: %s", err) + }) + } +} + +func getProvider(re RequestError) (string, error) { + if re.ServiceError != nil && len(re.ServiceError.Details) > 0 { + return re.ServiceError.Details[0]["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 = req.WithContext(originalReq.Context()) + + 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 = req.WithContext(originalReq.Context()) + + resp, err := autorest.SendWithSender(client, 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.Context().Done()) + if !delayed && !autorest.DelayForBackoff(client.PollingDelay, 0, originalReq.Context().Done()) { + return originalReq.Context().Err() + } + } + 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 "" +} diff --git a/vendor/github.com/Azure/go-autorest/autorest/client.go b/vendor/github.com/Azure/go-autorest/autorest/client.go index 5f1e72fbe..4e92dcad0 100644 --- a/vendor/github.com/Azure/go-autorest/autorest/client.go +++ b/vendor/github.com/Azure/go-autorest/autorest/client.go @@ -1,5 +1,19 @@ 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" "fmt" @@ -21,6 +35,9 @@ const ( // DefaultRetryAttempts is number of attempts for retry status codes (5xx). DefaultRetryAttempts = 3 + + // DefaultRetryDuration is the duration to wait between retries. + DefaultRetryDuration = 30 * time.Second ) var ( @@ -33,7 +50,8 @@ var ( Version(), ) - statusCodesForRetry = []int{ + // StatusCodesForRetry are a defined group of status code for which the client will retry + StatusCodesForRetry = []int{ http.StatusRequestTimeout, // 408 http.StatusTooManyRequests, // 429 http.StatusInternalServerError, // 500 @@ -148,6 +166,9 @@ type Client struct { UserAgent string Jar http.CookieJar + + // Set to true to skip attempted registration of resource providers (false by default). + SkipResourceProviderRegistration bool } // NewClientWithUserAgent returns an instance of a Client with the UserAgent set to the passed @@ -157,9 +178,10 @@ func NewClientWithUserAgent(ua string) Client { PollingDelay: DefaultPollingDelay, PollingDuration: DefaultPollingDuration, RetryAttempts: DefaultRetryAttempts, - RetryDuration: 30 * time.Second, + RetryDuration: DefaultRetryDuration, UserAgent: defaultUserAgent, } + c.Sender = c.sender() c.AddToUserAgent(ua) return c } @@ -181,16 +203,22 @@ func (c Client) Do(r *http.Request) (*http.Response, error) { r, _ = Prepare(r, WithUserAgent(c.UserAgent)) } + // NOTE: c.WithInspection() must be last in the list so that it can inspect all preceding operations r, err := Prepare(r, - c.WithInspection(), - c.WithAuthorization()) + c.WithAuthorization(), + c.WithInspection()) if err != nil { - return nil, NewErrorWithError(err, "autorest/Client", "Do", nil, "Preparing request failed") + var resp *http.Response + if detErr, ok := err.(DetailedError); ok { + // if the authorization failed (e.g. invalid credentials) there will + // be a response associated with the error, be sure to return it. + resp = detErr.Response + } + return resp, NewErrorWithError(err, "autorest/Client", "Do", nil, "Preparing request failed") } - resp, err := SendWithSender(c.sender(), r, - DoRetryForStatusCodes(c.RetryAttempts, c.RetryDuration, statusCodesForRetry...)) - Respond(resp, - c.ByInspecting()) + + resp, err := SendWithSender(c.sender(), r) + Respond(resp, c.ByInspecting()) return resp, err } diff --git a/vendor/github.com/Azure/go-autorest/autorest/date/date.go b/vendor/github.com/Azure/go-autorest/autorest/date/date.go index 80ca60e9b..c45710656 100644 --- a/vendor/github.com/Azure/go-autorest/autorest/date/date.go +++ b/vendor/github.com/Azure/go-autorest/autorest/date/date.go @@ -5,6 +5,20 @@ time.Time types. And both convert to time.Time through a ToTime method. */ 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 ( "fmt" "time" diff --git a/vendor/github.com/Azure/go-autorest/autorest/date/time.go b/vendor/github.com/Azure/go-autorest/autorest/date/time.go index c1af62963..b453fad04 100644 --- a/vendor/github.com/Azure/go-autorest/autorest/date/time.go +++ b/vendor/github.com/Azure/go-autorest/autorest/date/time.go @@ -1,5 +1,19 @@ 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 ( "regexp" "time" diff --git a/vendor/github.com/Azure/go-autorest/autorest/date/timerfc1123.go b/vendor/github.com/Azure/go-autorest/autorest/date/timerfc1123.go index 11995fb9f..48fb39ba9 100644 --- a/vendor/github.com/Azure/go-autorest/autorest/date/timerfc1123.go +++ b/vendor/github.com/Azure/go-autorest/autorest/date/timerfc1123.go @@ -1,5 +1,19 @@ 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 ( "errors" "time" diff --git a/vendor/github.com/Azure/go-autorest/autorest/date/unixtime.go b/vendor/github.com/Azure/go-autorest/autorest/date/unixtime.go index e085c77ee..7073959b2 100644 --- a/vendor/github.com/Azure/go-autorest/autorest/date/unixtime.go +++ b/vendor/github.com/Azure/go-autorest/autorest/date/unixtime.go @@ -1,5 +1,19 @@ 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 ( "bytes" "encoding/binary" diff --git a/vendor/github.com/Azure/go-autorest/autorest/date/utility.go b/vendor/github.com/Azure/go-autorest/autorest/date/utility.go index 207b1a240..12addf0eb 100644 --- a/vendor/github.com/Azure/go-autorest/autorest/date/utility.go +++ b/vendor/github.com/Azure/go-autorest/autorest/date/utility.go @@ -1,5 +1,19 @@ 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 ( "strings" "time" diff --git a/vendor/github.com/Azure/go-autorest/autorest/error.go b/vendor/github.com/Azure/go-autorest/autorest/error.go index aaef2ac8e..f724f3332 100644 --- a/vendor/github.com/Azure/go-autorest/autorest/error.go +++ b/vendor/github.com/Azure/go-autorest/autorest/error.go @@ -1,5 +1,19 @@ 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 ( "fmt" "net/http" diff --git a/vendor/github.com/Azure/go-autorest/autorest/preparer.go b/vendor/github.com/Azure/go-autorest/autorest/preparer.go index afd114821..6d67bd733 100644 --- a/vendor/github.com/Azure/go-autorest/autorest/preparer.go +++ b/vendor/github.com/Azure/go-autorest/autorest/preparer.go @@ -1,5 +1,19 @@ 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" "encoding/json" @@ -13,8 +27,9 @@ import ( ) const ( - mimeTypeJSON = "application/json" - mimeTypeFormPost = "application/x-www-form-urlencoded" + mimeTypeJSON = "application/json" + mimeTypeOctetStream = "application/octet-stream" + mimeTypeFormPost = "application/x-www-form-urlencoded" headerAuthorization = "Authorization" headerContentType = "Content-Type" @@ -98,6 +113,28 @@ func WithHeader(header string, value string) PrepareDecorator { } } +// WithHeaders returns a PrepareDecorator that sets the specified HTTP headers of the http.Request to +// the passed value. It canonicalizes the passed headers name (via http.CanonicalHeaderKey) before +// adding them. +func WithHeaders(headers map[string]interface{}) PrepareDecorator { + h := ensureValueStrings(headers) + return func(p Preparer) Preparer { + return PreparerFunc(func(r *http.Request) (*http.Request, error) { + r, err := p.Prepare(r) + if err == nil { + if r.Header == nil { + r.Header = make(http.Header) + } + + for name, value := range h { + r.Header.Set(http.CanonicalHeaderKey(name), value) + } + } + return r, err + }) + } +} + // WithBearerAuthorization returns a PrepareDecorator that adds an HTTP Authorization header whose // value is "Bearer " followed by the supplied token. func WithBearerAuthorization(token string) PrepareDecorator { @@ -128,6 +165,11 @@ func AsJSON() PrepareDecorator { return AsContentType(mimeTypeJSON) } +// AsOctetStream returns a PrepareDecorator that adds the "application/octet-stream" Content-Type header. +func AsOctetStream() PrepareDecorator { + return AsContentType(mimeTypeOctetStream) +} + // WithMethod returns a PrepareDecorator that sets the HTTP method of the passed request. The // decorator does not validate that the passed method string is a known HTTP method. func WithMethod(method string) PrepareDecorator { @@ -201,6 +243,11 @@ func WithFormData(v url.Values) PrepareDecorator { r, err := p.Prepare(r) if err == nil { s := v.Encode() + + if r.Header == nil { + r.Header = make(http.Header) + } + r.Header.Set(http.CanonicalHeaderKey(headerContentType), mimeTypeFormPost) r.ContentLength = int64(len(s)) r.Body = ioutil.NopCloser(strings.NewReader(s)) } @@ -416,11 +463,16 @@ func WithQueryParameters(queryParameters map[string]interface{}) PrepareDecorato if r.URL == nil { return r, NewError("autorest", "WithQueryParameters", "Invoked with a nil URL") } + v := r.URL.Query() for key, value := range parameters { - v.Add(key, value) + d, err := url.QueryUnescape(value) + if err != nil { + return r, err + } + v.Add(key, d) } - r.URL.RawQuery = createQuery(v) + r.URL.RawQuery = v.Encode() } return r, err }) diff --git a/vendor/github.com/Azure/go-autorest/autorest/responder.go b/vendor/github.com/Azure/go-autorest/autorest/responder.go index 87f71e585..a908a0adb 100644 --- a/vendor/github.com/Azure/go-autorest/autorest/responder.go +++ b/vendor/github.com/Azure/go-autorest/autorest/responder.go @@ -1,5 +1,19 @@ 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" "encoding/json" diff --git a/vendor/github.com/Azure/go-autorest/autorest/retriablerequest.go b/vendor/github.com/Azure/go-autorest/autorest/retriablerequest.go index 0ab1eb300..fa11dbed7 100644 --- a/vendor/github.com/Azure/go-autorest/autorest/retriablerequest.go +++ b/vendor/github.com/Azure/go-autorest/autorest/retriablerequest.go @@ -1,5 +1,19 @@ 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" diff --git a/vendor/github.com/Azure/go-autorest/autorest/retriablerequest_1.7.go b/vendor/github.com/Azure/go-autorest/autorest/retriablerequest_1.7.go index e28eb2cbd..7143cc61b 100644 --- a/vendor/github.com/Azure/go-autorest/autorest/retriablerequest_1.7.go +++ b/vendor/github.com/Azure/go-autorest/autorest/retriablerequest_1.7.go @@ -1,17 +1,31 @@ // +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 - reset bool + req *http.Request + br *bytes.Reader } // Prepare signals that the request is about to be sent. @@ -19,21 +33,17 @@ 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 { + _, 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() } - // indicates that the request body needs to be reset - rr.reset = true } return err } diff --git a/vendor/github.com/Azure/go-autorest/autorest/retriablerequest_1.8.go b/vendor/github.com/Azure/go-autorest/autorest/retriablerequest_1.8.go index 8c1d1aec8..ae15c6bf9 100644 --- a/vendor/github.com/Azure/go-autorest/autorest/retriablerequest_1.8.go +++ b/vendor/github.com/Azure/go-autorest/autorest/retriablerequest_1.8.go @@ -1,19 +1,33 @@ // +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 - reset bool + req *http.Request + rc io.ReadCloser + br *bytes.Reader } // Prepare signals that the request is about to be sent. @@ -21,16 +35,14 @@ 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.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 @@ -43,8 +55,6 @@ func (rr *RetriableRequest) Prepare() (err error) { // 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 } diff --git a/vendor/github.com/Azure/go-autorest/autorest/sender.go b/vendor/github.com/Azure/go-autorest/autorest/sender.go index 94b029847..b4f762325 100644 --- a/vendor/github.com/Azure/go-autorest/autorest/sender.go +++ b/vendor/github.com/Azure/go-autorest/autorest/sender.go @@ -1,5 +1,19 @@ 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 ( "fmt" "log" @@ -72,7 +86,7 @@ func SendWithSender(s Sender, r *http.Request, decorators ...SendDecorator) (*ht func AfterDelay(d time.Duration) SendDecorator { return func(s Sender) Sender { return SenderFunc(func(r *http.Request) (*http.Response, error) { - if !DelayForBackoff(d, 0, r.Cancel) { + if !DelayForBackoff(d, 0, r.Context().Done()) { return nil, fmt.Errorf("autorest: AfterDelay canceled before full delay") } return s.Do(r) @@ -151,7 +165,7 @@ func DoPollForStatusCodes(duration time.Duration, delay time.Duration, codes ... resp, err = s.Do(r) if err == nil && ResponseHasStatusCode(resp, codes...) { - r, err = NewPollingRequest(resp, r.Cancel) + r, err = NewPollingRequestWithContext(r.Context(), resp) for err == nil && ResponseHasStatusCode(resp, codes...) { Respond(resp, @@ -184,7 +198,9 @@ func DoRetryForAttempts(attempts int, backoff time.Duration) SendDecorator { if err == nil { return resp, err } - DelayForBackoff(backoff, attempt, r.Cancel) + if !DelayForBackoff(backoff, attempt, r.Context().Done()) { + return nil, r.Context().Err() + } } return resp, err }) @@ -201,18 +217,25 @@ func DoRetryForStatusCodes(attempts int, backoff time.Duration, codes ...int) Se rr := NewRetriableRequest(r) // Increment to add the first call (attempts denotes number of retries) attempts++ - for attempt := 0; attempt < attempts; attempt++ { + for attempt := 0; attempt < attempts; { err = rr.Prepare() if err != nil { return resp, err } resp, err = s.Do(rr.Request()) - if err != nil || !ResponseHasStatusCode(resp, codes...) { + // we want to retry if err is not nil (e.g. transient network failure). note that for failed authentication + // resp and err will both have a value, so in this case we don't want to retry as it will never succeed. + if err == nil && !ResponseHasStatusCode(resp, codes...) || IsTokenRefreshError(err) { return resp, err } - delayed := DelayWithRetryAfter(resp, r.Cancel) - if !delayed { - DelayForBackoff(backoff, attempt, r.Cancel) + delayed := DelayWithRetryAfter(resp, r.Context().Done()) + if !delayed && !DelayForBackoff(backoff, attempt, r.Context().Done()) { + return nil, r.Context().Err() + } + // don't count a 429 against the number of attempts + // so that we continue to retry until it succeeds + if resp == nil || resp.StatusCode != http.StatusTooManyRequests { + attempt++ } } return resp, err @@ -223,6 +246,9 @@ func DoRetryForStatusCodes(attempts int, backoff time.Duration, codes ...int) Se // 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 { + if resp == nil { + return false + } retryAfter, _ := strconv.Atoi(resp.Header.Get("Retry-After")) if resp.StatusCode == http.StatusTooManyRequests && retryAfter > 0 { select { @@ -253,7 +279,9 @@ func DoRetryForDuration(d time.Duration, backoff time.Duration) SendDecorator { if err == nil { return resp, err } - DelayForBackoff(backoff, attempt, r.Cancel) + if !DelayForBackoff(backoff, attempt, r.Context().Done()) { + return nil, r.Context().Err() + } } return resp, err }) diff --git a/vendor/github.com/Azure/go-autorest/autorest/to/convert.go b/vendor/github.com/Azure/go-autorest/autorest/to/convert.go index 7b180b866..fdda2ce1a 100644 --- a/vendor/github.com/Azure/go-autorest/autorest/to/convert.go +++ b/vendor/github.com/Azure/go-autorest/autorest/to/convert.go @@ -3,6 +3,20 @@ Package to provides helpers to ease working with pointer values of marshalled st */ package to +// 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. + // String returns a string value for the passed string pointer. It returns the empty string if the // pointer is nil. func String(s *string) string { diff --git a/vendor/github.com/Azure/go-autorest/autorest/utility.go b/vendor/github.com/Azure/go-autorest/autorest/utility.go index 78067148b..afb3e4e16 100644 --- a/vendor/github.com/Azure/go-autorest/autorest/utility.go +++ b/vendor/github.com/Azure/go-autorest/autorest/utility.go @@ -1,15 +1,31 @@ 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" "encoding/json" "encoding/xml" "fmt" "io" + "net/http" "net/url" "reflect" - "sort" "strings" + + "github.com/Azure/go-autorest/autorest/adal" ) // EncodedAs is a series of constants specifying various data encodings @@ -123,13 +139,38 @@ func MapToValues(m map[string]interface{}) url.Values { return v } -// String method converts interface v to string. If interface is a list, it -// joins list elements using separator. -func String(v interface{}, sep ...string) string { - if len(sep) > 0 { - return ensureValueString(strings.Join(v.([]string), sep[0])) +// AsStringSlice method converts interface{} to []string. This expects a +//that the parameter passed to be a slice or array of a type that has the underlying +//type a string. +func AsStringSlice(s interface{}) ([]string, error) { + v := reflect.ValueOf(s) + if v.Kind() != reflect.Slice && v.Kind() != reflect.Array { + return nil, NewError("autorest", "AsStringSlice", "the value's type is not an array.") } - return ensureValueString(v) + stringSlice := make([]string, 0, v.Len()) + + for i := 0; i < v.Len(); i++ { + stringSlice = append(stringSlice, v.Index(i).String()) + } + return stringSlice, nil +} + +// String method converts interface v to string. If interface is a list, it +// joins list elements using the seperator. Note that only sep[0] will be used for +// joining if any separator is specified. +func String(v interface{}, sep ...string) string { + if len(sep) == 0 { + return ensureValueString(v) + } + stringSlice, ok := v.([]string) + if ok == false { + var err error + stringSlice, err = AsStringSlice(v) + if err != nil { + panic(fmt.Sprintf("autorest: Couldn't convert value to a string %s.", err)) + } + } + return ensureValueString(strings.Join(stringSlice, sep[0])) } // Encode method encodes url path and query parameters. @@ -153,26 +194,25 @@ func queryEscape(s string) string { return url.QueryEscape(s) } -// This method is same as Encode() method of "net/url" go package, -// except it does not encode the query parameters because they -// already come encoded. It formats values map in query format (bar=foo&a=b). -func createQuery(v url.Values) string { - var buf bytes.Buffer - keys := make([]string, 0, len(v)) - for k := range v { - keys = append(keys, k) - } - sort.Strings(keys) - for _, k := range keys { - vs := v[k] - prefix := url.QueryEscape(k) + "=" - for _, v := range vs { - if buf.Len() > 0 { - buf.WriteByte('&') - } - buf.WriteString(prefix) - buf.WriteString(v) - } - } - return buf.String() +// ChangeToGet turns the specified http.Request into a GET (it assumes it wasn't). +// This is mainly useful for long-running operations that use the Azure-AsyncOperation +// header, so we change the initial PUT into a GET to retrieve the final result. +func ChangeToGet(req *http.Request) *http.Request { + req.Method = "GET" + req.Body = nil + req.ContentLength = 0 + req.Header.Del("Content-Length") + return req +} + +// IsTokenRefreshError returns true if the specified error implements the TokenRefreshError +// interface. If err is a DetailedError it will walk the chain of Original errors. +func IsTokenRefreshError(err error) bool { + if _, ok := err.(adal.TokenRefreshError); ok { + return true + } + if de, ok := err.(DetailedError); ok { + return IsTokenRefreshError(de.Original) + } + return false } diff --git a/vendor/github.com/Azure/go-autorest/autorest/version.go b/vendor/github.com/Azure/go-autorest/autorest/version.go index a222e8efa..4ad7754ad 100644 --- a/vendor/github.com/Azure/go-autorest/autorest/version.go +++ b/vendor/github.com/Azure/go-autorest/autorest/version.go @@ -1,35 +1,20 @@ package autorest -import ( - "bytes" - "fmt" - "strings" - "sync" -) - -const ( - major = 8 - minor = 0 - patch = 0 - tag = "" -) - -var once sync.Once -var version string +// 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. // Version returns the semantic version (see http://semver.org). func Version() string { - 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 + return "v10.5.0" } diff --git a/vendor/github.com/dgrijalva/jwt-go/ecdsa.go b/vendor/github.com/dgrijalva/jwt-go/ecdsa.go index 2f59a2223..f97738124 100644 --- a/vendor/github.com/dgrijalva/jwt-go/ecdsa.go +++ b/vendor/github.com/dgrijalva/jwt-go/ecdsa.go @@ -14,6 +14,7 @@ var ( ) // Implements the ECDSA family of signing methods signing methods +// Expects *ecdsa.PrivateKey for signing and *ecdsa.PublicKey for verification type SigningMethodECDSA struct { Name string Hash crypto.Hash diff --git a/vendor/github.com/dgrijalva/jwt-go/errors.go b/vendor/github.com/dgrijalva/jwt-go/errors.go index 662df19d4..1c93024aa 100644 --- a/vendor/github.com/dgrijalva/jwt-go/errors.go +++ b/vendor/github.com/dgrijalva/jwt-go/errors.go @@ -51,13 +51,9 @@ func (e ValidationError) Error() string { } else { return "token is invalid" } - return e.Inner.Error() } // No errors func (e *ValidationError) valid() bool { - if e.Errors > 0 { - return false - } - return true + return e.Errors == 0 } diff --git a/vendor/github.com/dgrijalva/jwt-go/hmac.go b/vendor/github.com/dgrijalva/jwt-go/hmac.go index c22991925..addbe5d40 100644 --- a/vendor/github.com/dgrijalva/jwt-go/hmac.go +++ b/vendor/github.com/dgrijalva/jwt-go/hmac.go @@ -7,6 +7,7 @@ import ( ) // Implements the HMAC-SHA family of signing methods signing methods +// Expects key type of []byte for both signing and validation type SigningMethodHMAC struct { Name string Hash crypto.Hash @@ -90,5 +91,5 @@ func (m *SigningMethodHMAC) Sign(signingString string, key interface{}) (string, return EncodeSegment(hasher.Sum(nil)), nil } - return "", ErrInvalidKey + return "", ErrInvalidKeyType } diff --git a/vendor/github.com/dgrijalva/jwt-go/parser.go b/vendor/github.com/dgrijalva/jwt-go/parser.go index 7020c52a1..d6901d9ad 100644 --- a/vendor/github.com/dgrijalva/jwt-go/parser.go +++ b/vendor/github.com/dgrijalva/jwt-go/parser.go @@ -8,8 +8,9 @@ import ( ) type Parser struct { - ValidMethods []string // If populated, only these methods will be considered valid - UseJSONNumber bool // Use JSON Number format in JSON decoder + ValidMethods []string // If populated, only these methods will be considered valid + UseJSONNumber bool // Use JSON Number format in JSON decoder + SkipClaimsValidation bool // Skip claims validation during token parsing } // Parse, validate, and return a token. @@ -20,55 +21,9 @@ func (p *Parser) Parse(tokenString string, keyFunc Keyfunc) (*Token, error) { } func (p *Parser) ParseWithClaims(tokenString string, claims Claims, keyFunc Keyfunc) (*Token, error) { - parts := strings.Split(tokenString, ".") - if len(parts) != 3 { - return nil, NewValidationError("token contains an invalid number of segments", ValidationErrorMalformed) - } - - var err error - token := &Token{Raw: tokenString} - - // parse Header - var headerBytes []byte - if headerBytes, err = DecodeSegment(parts[0]); err != nil { - if strings.HasPrefix(strings.ToLower(tokenString), "bearer ") { - return token, NewValidationError("tokenstring should not contain 'bearer '", ValidationErrorMalformed) - } - return token, &ValidationError{Inner: err, Errors: ValidationErrorMalformed} - } - if err = json.Unmarshal(headerBytes, &token.Header); err != nil { - return token, &ValidationError{Inner: err, Errors: ValidationErrorMalformed} - } - - // parse Claims - var claimBytes []byte - token.Claims = claims - - if claimBytes, err = DecodeSegment(parts[1]); err != nil { - return token, &ValidationError{Inner: err, Errors: ValidationErrorMalformed} - } - dec := json.NewDecoder(bytes.NewBuffer(claimBytes)) - if p.UseJSONNumber { - dec.UseNumber() - } - // JSON Decode. Special case for map type to avoid weird pointer behavior - if c, ok := token.Claims.(MapClaims); ok { - err = dec.Decode(&c) - } else { - err = dec.Decode(&claims) - } - // Handle decode error + token, parts, err := p.ParseUnverified(tokenString, claims) if err != nil { - return token, &ValidationError{Inner: err, Errors: ValidationErrorMalformed} - } - - // Lookup signature method - if method, ok := token.Header["alg"].(string); ok { - if token.Method = GetSigningMethod(method); token.Method == nil { - return token, NewValidationError("signing method (alg) is unavailable.", ValidationErrorUnverifiable) - } - } else { - return token, NewValidationError("signing method (alg) is unspecified.", ValidationErrorUnverifiable) + return token, err } // Verify signing method is in the required set @@ -95,20 +50,25 @@ func (p *Parser) ParseWithClaims(tokenString string, claims Claims, keyFunc Keyf } if key, err = keyFunc(token); err != nil { // keyFunc returned an error + if ve, ok := err.(*ValidationError); ok { + return token, ve + } return token, &ValidationError{Inner: err, Errors: ValidationErrorUnverifiable} } vErr := &ValidationError{} // Validate Claims - if err := token.Claims.Valid(); err != nil { + if !p.SkipClaimsValidation { + if err := token.Claims.Valid(); err != nil { - // If the Claims Valid returned an error, check if it is a validation error, - // If it was another error type, create a ValidationError with a generic ClaimsInvalid flag set - if e, ok := err.(*ValidationError); !ok { - vErr = &ValidationError{Inner: err, Errors: ValidationErrorClaimsInvalid} - } else { - vErr = e + // If the Claims Valid returned an error, check if it is a validation error, + // If it was another error type, create a ValidationError with a generic ClaimsInvalid flag set + if e, ok := err.(*ValidationError); !ok { + vErr = &ValidationError{Inner: err, Errors: ValidationErrorClaimsInvalid} + } else { + vErr = e + } } } @@ -126,3 +86,63 @@ func (p *Parser) ParseWithClaims(tokenString string, claims Claims, keyFunc Keyf return token, vErr } + +// WARNING: Don't use this method unless you know what you're doing +// +// This method parses the token but doesn't validate the signature. It's only +// ever useful in cases where you know the signature is valid (because it has +// been checked previously in the stack) and you want to extract values from +// it. +func (p *Parser) ParseUnverified(tokenString string, claims Claims) (token *Token, parts []string, err error) { + parts = strings.Split(tokenString, ".") + if len(parts) != 3 { + return nil, parts, NewValidationError("token contains an invalid number of segments", ValidationErrorMalformed) + } + + token = &Token{Raw: tokenString} + + // parse Header + var headerBytes []byte + if headerBytes, err = DecodeSegment(parts[0]); err != nil { + if strings.HasPrefix(strings.ToLower(tokenString), "bearer ") { + return token, parts, NewValidationError("tokenstring should not contain 'bearer '", ValidationErrorMalformed) + } + return token, parts, &ValidationError{Inner: err, Errors: ValidationErrorMalformed} + } + if err = json.Unmarshal(headerBytes, &token.Header); err != nil { + return token, parts, &ValidationError{Inner: err, Errors: ValidationErrorMalformed} + } + + // parse Claims + var claimBytes []byte + token.Claims = claims + + if claimBytes, err = DecodeSegment(parts[1]); err != nil { + return token, parts, &ValidationError{Inner: err, Errors: ValidationErrorMalformed} + } + dec := json.NewDecoder(bytes.NewBuffer(claimBytes)) + if p.UseJSONNumber { + dec.UseNumber() + } + // JSON Decode. Special case for map type to avoid weird pointer behavior + if c, ok := token.Claims.(MapClaims); ok { + err = dec.Decode(&c) + } else { + err = dec.Decode(&claims) + } + // Handle decode error + if err != nil { + return token, parts, &ValidationError{Inner: err, Errors: ValidationErrorMalformed} + } + + // Lookup signature method + if method, ok := token.Header["alg"].(string); ok { + if token.Method = GetSigningMethod(method); token.Method == nil { + return token, parts, NewValidationError("signing method (alg) is unavailable.", ValidationErrorUnverifiable) + } + } else { + return token, parts, NewValidationError("signing method (alg) is unspecified.", ValidationErrorUnverifiable) + } + + return token, parts, nil +} diff --git a/vendor/github.com/dgrijalva/jwt-go/rsa.go b/vendor/github.com/dgrijalva/jwt-go/rsa.go index 0ae0b1984..e4caf1ca4 100644 --- a/vendor/github.com/dgrijalva/jwt-go/rsa.go +++ b/vendor/github.com/dgrijalva/jwt-go/rsa.go @@ -7,6 +7,7 @@ import ( ) // Implements the RSA family of signing methods signing methods +// Expects *rsa.PrivateKey for signing and *rsa.PublicKey for validation type SigningMethodRSA struct { Name string Hash crypto.Hash @@ -44,7 +45,7 @@ func (m *SigningMethodRSA) Alg() string { } // Implements the Verify method from SigningMethod -// For this signing method, must be an rsa.PublicKey structure. +// For this signing method, must be an *rsa.PublicKey structure. func (m *SigningMethodRSA) Verify(signingString, signature string, key interface{}) error { var err error @@ -73,7 +74,7 @@ func (m *SigningMethodRSA) Verify(signingString, signature string, key interface } // Implements the Sign method from SigningMethod -// For this signing method, must be an rsa.PrivateKey structure. +// For this signing method, must be an *rsa.PrivateKey structure. func (m *SigningMethodRSA) Sign(signingString string, key interface{}) (string, error) { var rsaKey *rsa.PrivateKey var ok bool diff --git a/vendor/github.com/dgrijalva/jwt-go/rsa_utils.go b/vendor/github.com/dgrijalva/jwt-go/rsa_utils.go index 213a90dbb..a5ababf95 100644 --- a/vendor/github.com/dgrijalva/jwt-go/rsa_utils.go +++ b/vendor/github.com/dgrijalva/jwt-go/rsa_utils.go @@ -39,6 +39,38 @@ func ParseRSAPrivateKeyFromPEM(key []byte) (*rsa.PrivateKey, error) { return pkey, nil } +// Parse PEM encoded PKCS1 or PKCS8 private key protected with password +func ParseRSAPrivateKeyFromPEMWithPassword(key []byte, password string) (*rsa.PrivateKey, error) { + var err error + + // Parse PEM block + var block *pem.Block + if block, _ = pem.Decode(key); block == nil { + return nil, ErrKeyMustBePEMEncoded + } + + var parsedKey interface{} + + var blockDecrypted []byte + if blockDecrypted, err = x509.DecryptPEMBlock(block, []byte(password)); err != nil { + return nil, err + } + + if parsedKey, err = x509.ParsePKCS1PrivateKey(blockDecrypted); err != nil { + if parsedKey, err = x509.ParsePKCS8PrivateKey(blockDecrypted); err != nil { + return nil, err + } + } + + var pkey *rsa.PrivateKey + var ok bool + if pkey, ok = parsedKey.(*rsa.PrivateKey); !ok { + return nil, ErrNotRSAPrivateKey + } + + return pkey, nil +} + // Parse PEM encoded PKCS1 or PKCS8 public key func ParseRSAPublicKeyFromPEM(key []byte) (*rsa.PublicKey, error) { var err error diff --git a/vendor/github.com/xenolf/lego/acmev2/client.go b/vendor/github.com/xenolf/lego/acmev2/client.go index 86e371adc..649c8d9cf 100644 --- a/vendor/github.com/xenolf/lego/acmev2/client.go +++ b/vendor/github.com/xenolf/lego/acmev2/client.go @@ -482,6 +482,7 @@ func (c *Client) createOrderForIdentifiers(domains []string) (orderResource, err orderRes := orderResource{ URL: hdr.Get("Location"), + Domains: domains, orderMessage: response, } return orderRes, nil @@ -590,7 +591,7 @@ func (c *Client) requestCertificateForOrder(order orderResource, bundle bool, pr } // determine certificate name(s) based on the authorization resources - commonName := order.Identifiers[0].Value + commonName := order.Domains[0] var san []string for _, auth := range order.Identifiers { san = append(san, auth.Value) @@ -606,12 +607,7 @@ func (c *Client) requestCertificateForOrder(order orderResource, bundle bool, pr } func (c *Client) requestCertificateForCsr(order orderResource, bundle bool, csr []byte, privateKeyPem []byte) (CertificateResource, error) { - commonName := order.Identifiers[0].Value - - var authURLs []string - for _, auth := range order.Identifiers[1:] { - authURLs = append(authURLs, auth.Value) - } + commonName := order.Domains[0] csrString := base64.RawURLEncoding.EncodeToString(csr) var retOrder orderMessage diff --git a/vendor/github.com/xenolf/lego/acmev2/messages.go b/vendor/github.com/xenolf/lego/acmev2/messages.go index 9fc450e06..a3058dfb8 100644 --- a/vendor/github.com/xenolf/lego/acmev2/messages.go +++ b/vendor/github.com/xenolf/lego/acmev2/messages.go @@ -34,7 +34,8 @@ type accountMessage struct { } type orderResource struct { - URL string `json:"url,omitempty"` + URL string `json:"url,omitempty"` + Domains []string `json:"domains,omitempty"` orderMessage `json:"body,omitempty"` } diff --git a/vendor/github.com/xenolf/lego/providers/dns/azure/azure.go b/vendor/github.com/xenolf/lego/providers/dns/azure/azure.go index 994af9660..c11ca8fc1 100644 --- a/vendor/github.com/xenolf/lego/providers/dns/azure/azure.go +++ b/vendor/github.com/xenolf/lego/providers/dns/azure/azure.go @@ -4,14 +4,13 @@ package azure import ( + "context" "fmt" "os" + "strings" "time" - "github.com/Azure/azure-sdk-for-go/arm/dns" - - "strings" - + "github.com/Azure/azure-sdk-for-go/services/dns/mgmt/2017-09-01/dns" "github.com/Azure/go-autorest/autorest" "github.com/Azure/go-autorest/autorest/adal" "github.com/Azure/go-autorest/autorest/azure" @@ -26,6 +25,8 @@ type DNSProvider struct { subscriptionId string tenantId string resourceGroup string + + context context.Context } // NewDNSProvider returns a DNSProvider instance configured for azure. @@ -53,6 +54,8 @@ func NewDNSProviderCredentials(clientId, clientSecret, subscriptionId, tenantId, subscriptionId: subscriptionId, tenantId: tenantId, resourceGroup: resourceGroup, + // TODO: A timeout can be added here for cancellation purposes. + context: context.Background(), }, nil } @@ -82,7 +85,7 @@ func (c *DNSProvider) Present(domain, token, keyAuth string) error { TxtRecords: &[]dns.TxtRecord{dns.TxtRecord{Value: &[]string{value}}}, }, } - _, err = rsc.CreateOrUpdate(c.resourceGroup, zone, relative, dns.TXT, rec, "", "") + _, err = rsc.CreateOrUpdate(c.context, c.resourceGroup, zone, relative, dns.TXT, rec, "", "") if err != nil { return err @@ -109,7 +112,7 @@ func (c *DNSProvider) CleanUp(domain, token, keyAuth string) error { rsc := dns.NewRecordSetsClient(c.subscriptionId) spt, err := c.newServicePrincipalTokenFromCredentials(azure.PublicCloud.ResourceManagerEndpoint) rsc.Authorizer = autorest.NewBearerAuthorizer(spt) - _, err = rsc.Delete(c.resourceGroup, zone, relative, dns.TXT, "") + _, err = rsc.Delete(c.context, c.resourceGroup, zone, relative, dns.TXT, "") if err != nil { return err } @@ -130,7 +133,7 @@ func (c *DNSProvider) getHostedZoneID(fqdn string) (string, error) { dc := dns.NewZonesClient(c.subscriptionId) dc.Authorizer = autorest.NewBearerAuthorizer(spt) - zone, err := dc.Get(c.resourceGroup, acmev2.UnFqdn(authZone)) + zone, err := dc.Get(c.context, c.resourceGroup, acmev2.UnFqdn(authZone)) if err != nil { return "", err diff --git a/vendor/github.com/xenolf/lego/providers/dns/digitalocean/digitalocean.go b/vendor/github.com/xenolf/lego/providers/dns/digitalocean/digitalocean.go index 6c989b07d..deb0548be 100644 --- a/vendor/github.com/xenolf/lego/providers/dns/digitalocean/digitalocean.go +++ b/vendor/github.com/xenolf/lego/providers/dns/digitalocean/digitalocean.go @@ -72,7 +72,7 @@ func (d *DNSProvider) Present(domain, token, keyAuth string) error { authZone = acmev2.UnFqdn(authZone) reqURL := fmt.Sprintf("%s/v2/domains/%s/records", digitalOceanBaseURL, authZone) - reqData := txtRecordRequest{RecordType: "TXT", Name: fqdn, Data: value, TTL: 60} + reqData := txtRecordRequest{RecordType: "TXT", Name: fqdn, Data: value, TTL: 30} body, err := json.Marshal(reqData) if err != nil { return err @@ -169,5 +169,5 @@ var digitalOceanBaseURL = "https://api.digitalocean.com" // Timeout returns the timeout and interval to use when checking for DNS // propagation. Adjusting here to cope with spikes in propagation times. func (d *DNSProvider) Timeout() (timeout, interval time.Duration) { - return 90 * time.Second, 5 * time.Second + return 60 * time.Second, 5 * time.Second }