github.com/mohanarpit/terraform@v0.6.16-0.20160909104007-291f29853544/builtin/providers/azurerm/resourceid.go (about) 1 package azurerm 2 3 import ( 4 "fmt" 5 "net/url" 6 "strings" 7 ) 8 9 // ResourceID represents a parsed long-form Azure Resource Manager ID 10 // with the Subscription ID, Resource Group and the Provider as top- 11 // level fields, and other key-value pairs available via a map in the 12 // Path field. 13 type ResourceID struct { 14 SubscriptionID string 15 ResourceGroup string 16 Provider string 17 Path map[string]string 18 } 19 20 // parseAzureResourceID converts a long-form Azure Resource Manager ID 21 // into a ResourceID. We make assumptions about the structure of URLs, 22 // which is obviously not good, but the best thing available given the 23 // SDK. 24 func parseAzureResourceID(id string) (*ResourceID, error) { 25 idURL, err := url.ParseRequestURI(id) 26 if err != nil { 27 return nil, fmt.Errorf("Cannot parse Azure Id: %s", err) 28 } 29 30 path := idURL.Path 31 32 path = strings.TrimSpace(path) 33 if strings.HasPrefix(path, "/") { 34 path = path[1:] 35 } 36 37 if strings.HasSuffix(path, "/") { 38 path = path[:len(path)-1] 39 } 40 41 components := strings.Split(path, "/") 42 43 // We should have an even number of key-value pairs. 44 if len(components)%2 != 0 { 45 return nil, fmt.Errorf("The number of path segments is not divisible by 2 in %q", path) 46 } 47 48 // Put the constituent key-value pairs into a map 49 componentMap := make(map[string]string, len(components)/2) 50 for current := 0; current < len(components); current += 2 { 51 key := components[current] 52 value := components[current+1] 53 54 componentMap[key] = value 55 } 56 57 // Build up a ResourceID from the map 58 idObj := &ResourceID{} 59 idObj.Path = componentMap 60 61 if subscription, ok := componentMap["subscriptions"]; ok { 62 idObj.SubscriptionID = subscription 63 delete(componentMap, "subscriptions") 64 } else { 65 return nil, fmt.Errorf("No subscription ID found in: %q", path) 66 } 67 68 if resourceGroup, ok := componentMap["resourceGroups"]; ok { 69 idObj.ResourceGroup = resourceGroup 70 delete(componentMap, "resourceGroups") 71 } else { 72 // Some Azure APIs are weird and provide things in lower case... 73 // However it's not clear whether the casing of other elements in the URI 74 // matter, so we explicitly look for that case here. 75 if resourceGroup, ok := componentMap["resourcegroups"]; ok { 76 idObj.ResourceGroup = resourceGroup 77 delete(componentMap, "resourcegroups") 78 } else { 79 return nil, fmt.Errorf("No resource group name found in: %q", path) 80 } 81 } 82 83 // It is OK not to have a provider in the case of a resource group 84 if provider, ok := componentMap["providers"]; ok { 85 idObj.Provider = provider 86 delete(componentMap, "providers") 87 } 88 89 return idObj, nil 90 }