mirror of
https://github.com/opentofu/opentofu.git
synced 2025-01-07 14:44:11 -06:00
c3ce8b81ef
When parsing resource IDs (probably incorrectly since they are URIs and should therefore be opaque), we need to look for "resourcegroups" in addition to "resourceGroups" because the Azure CDN resources return that in their URIs. Unfortunately the casing semantics of the rest of the string are not clear, so downcasing the entire URI is probably best avoided. This is a fix for a single case.
91 lines
2.5 KiB
Go
91 lines
2.5 KiB
Go
package azurerm
|
|
|
|
import (
|
|
"fmt"
|
|
"net/url"
|
|
"strings"
|
|
)
|
|
|
|
// ResourceID represents a parsed long-form Azure Resource Manager ID
|
|
// with the Subscription ID, Resource Group and the Provider as top-
|
|
// level fields, and other key-value pairs available via a map in the
|
|
// Path field.
|
|
type ResourceID struct {
|
|
SubscriptionID string
|
|
ResourceGroup string
|
|
Provider string
|
|
Path map[string]string
|
|
}
|
|
|
|
// parseAzureResourceID converts a long-form Azure Resource Manager ID
|
|
// into a ResourceID. We make assumptions about the structure of URLs,
|
|
// which is obviously not good, but the best thing available given the
|
|
// SDK.
|
|
func parseAzureResourceID(id string) (*ResourceID, error) {
|
|
idURL, err := url.ParseRequestURI(id)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("Cannot parse Azure Id: %s", err)
|
|
}
|
|
|
|
path := idURL.Path
|
|
|
|
path = strings.TrimSpace(path)
|
|
if strings.HasPrefix(path, "/") {
|
|
path = path[1:]
|
|
}
|
|
|
|
if strings.HasSuffix(path, "/") {
|
|
path = path[:len(path)-1]
|
|
}
|
|
|
|
components := strings.Split(path, "/")
|
|
|
|
// We should have an even number of key-value pairs.
|
|
if len(components)%2 != 0 {
|
|
return nil, fmt.Errorf("The number of path segments is not divisible by 2 in %q", path)
|
|
}
|
|
|
|
// Put the constituent key-value pairs into a map
|
|
componentMap := make(map[string]string, len(components)/2)
|
|
for current := 0; current < len(components); current += 2 {
|
|
key := components[current]
|
|
value := components[current+1]
|
|
|
|
componentMap[key] = value
|
|
}
|
|
|
|
// Build up a ResourceID from the map
|
|
idObj := &ResourceID{}
|
|
idObj.Path = componentMap
|
|
|
|
if subscription, ok := componentMap["subscriptions"]; ok {
|
|
idObj.SubscriptionID = subscription
|
|
delete(componentMap, "subscriptions")
|
|
} else {
|
|
return nil, fmt.Errorf("No subscription ID found in: %q", path)
|
|
}
|
|
|
|
if resourceGroup, ok := componentMap["resourceGroups"]; ok {
|
|
idObj.ResourceGroup = resourceGroup
|
|
delete(componentMap, "resourceGroups")
|
|
} else {
|
|
// Some Azure APIs are weird and provide things in lower case...
|
|
// However it's not clear whether the casing of other elements in the URI
|
|
// matter, so we explicitly look for that case here.
|
|
if resourceGroup, ok := componentMap["resourcegroups"]; ok {
|
|
idObj.ResourceGroup = resourceGroup
|
|
delete(componentMap, "resourcegroups")
|
|
} else {
|
|
return nil, fmt.Errorf("No resource group name found in: %q", path)
|
|
}
|
|
}
|
|
|
|
// It is OK not to have a provider in the case of a resource group
|
|
if provider, ok := componentMap["providers"]; ok {
|
|
idObj.Provider = provider
|
|
delete(componentMap, "providers")
|
|
}
|
|
|
|
return idObj, nil
|
|
}
|