Skip to content

Commit

Permalink
client/resourcemanager: handling self-referenced LROs
Browse files Browse the repository at this point in the history
Some LROs return a 201 with the Location header as a self-reference, polling on that URI returns a 200 OK with
no provisioningState or status field to poll on - as such we need to special-case to handle this.

Fixes an issue in `Automation` @ `2022-08-08` in `DSCNodeConfiguration` / `CreateOrUpdate`
  • Loading branch information
tombuildsstuff committed Aug 2, 2023
1 parent 91dd68f commit 09753b0
Showing 1 changed file with 22 additions and 1 deletion.
23 changes: 22 additions & 1 deletion sdk/client/resourcemanager/poller.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ package resourcemanager
import (
"fmt"
"net/http"
"net/url"
"strings"

"github.com/hashicorp/go-azure-sdk/sdk/client"
Expand All @@ -17,11 +18,14 @@ func PollerFromResponse(response *client.Response, client *Client) (poller polle
return pollers.Poller{}, fmt.Errorf("no HTTP Response was returned")
}

originalRequestUri := response.Request.URL.String()

// If this is a LRO we should either have a 201/202 with a Polling URI header
isLroStatus := response.StatusCode == http.StatusCreated || response.StatusCode == http.StatusAccepted
methodIsDelete := strings.EqualFold(response.Request.Method, "DELETE")
lroPollingUri := pollingUriForLongRunningOperation(response)
if isLroStatus && lroPollingUri != "" && !methodIsDelete {
lroIsSelfReference := isLROSelfReference(lroPollingUri, originalRequestUri)
if isLroStatus && lroPollingUri != "" && !methodIsDelete && !lroIsSelfReference {
lro, lroErr := longRunningOperationPollerFromResponse(response, client.Client)
if lroErr != nil {
err = lroErr
Expand Down Expand Up @@ -63,3 +67,20 @@ func PollerFromResponse(response *client.Response, client *Client) (poller polle

return pollers.Poller{}, fmt.Errorf("no applicable pollers were found for the response")
}

func isLROSelfReference(lroPollingUri, originalRequestUri string) bool {
// Some APIs return a LRO URI of themselves, meaning that we should be checking a 200 OK is returned rather
// than polling as usual. Automation@2022-08-08 - DSCNodeConfiguration CreateOrUpdate is one such example.
first, err := url.Parse(lroPollingUri)
if err != nil {
return false
}
second, err := url.Parse(originalRequestUri)
if err != nil {
return false
}

// The Query String can be a different API version / options and in some cases the Host
// is returned with `:443` - so the path should be sufficient as a check.
return strings.EqualFold(first.Path, second.Path)
}

0 comments on commit 09753b0

Please sign in to comment.