From c88c7d68469a1fc9842c4e696b624aaa8b106115 Mon Sep 17 00:00:00 2001 From: jackofallops Date: Thu, 11 Jul 2024 13:28:11 +0100 Subject: [PATCH] bump go-azure-helpers to v0.70.0 --- go.mod | 2 +- go.sum | 4 +- .../resourcemanager/recaser/recase.go | 148 +++++++++++++++--- .../resourcemanager/recaser/registration.go | 9 ++ vendor/modules.txt | 2 +- 5 files changed, 138 insertions(+), 27 deletions(-) diff --git a/go.mod b/go.mod index c3261aecc544..5f78a1193856 100644 --- a/go.mod +++ b/go.mod @@ -16,7 +16,7 @@ require ( github.com/golang-jwt/jwt/v4 v4.5.0 github.com/google/go-cmp v0.5.9 github.com/google/uuid v1.4.0 - github.com/hashicorp/go-azure-helpers v0.69.0 + github.com/hashicorp/go-azure-helpers v0.70.0 github.com/hashicorp/go-azure-sdk/resource-manager v0.20240710.1114656 github.com/hashicorp/go-azure-sdk/sdk v0.20240710.1114656 github.com/hashicorp/go-hclog v1.6.3 diff --git a/go.sum b/go.sum index 16b775ded7c3..90c0949e90b3 100644 --- a/go.sum +++ b/go.sum @@ -93,8 +93,8 @@ github.com/hashicorp/errwrap v0.0.0-20180715044906-d6c0cd880357/go.mod h1:YH+1FK github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY2I= github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= -github.com/hashicorp/go-azure-helpers v0.69.0 h1:JwUWXyDgyr6OafU4CgSvrbEP1wcMjfz4gxRQciDQkBQ= -github.com/hashicorp/go-azure-helpers v0.69.0/go.mod h1:BmbF4JDYXK5sEmFeU5hcn8Br21uElcqLfdQxjatwQKw= +github.com/hashicorp/go-azure-helpers v0.70.0 h1:3wvA/KLT1utHkgiz6hR426/wl+61Eg144/ba5dE39k8= +github.com/hashicorp/go-azure-helpers v0.70.0/go.mod h1:BmbF4JDYXK5sEmFeU5hcn8Br21uElcqLfdQxjatwQKw= github.com/hashicorp/go-azure-sdk/resource-manager v0.20240710.1114656 h1:EZTyc4S2bLGEx7Gt+gOJK0vV0yYHU9uEmLxS0YChZaE= github.com/hashicorp/go-azure-sdk/resource-manager v0.20240710.1114656/go.mod h1:ZUzLYEsuQbr2GicguIijul0QmU3JpVeFpb9P6/vxl68= github.com/hashicorp/go-azure-sdk/sdk v0.20240710.1114656 h1:3X/byyOACW0GO+K4p418BY4CsFnSUlrrME/FW8EooJk= diff --git a/vendor/github.com/hashicorp/go-azure-helpers/resourcemanager/recaser/recase.go b/vendor/github.com/hashicorp/go-azure-helpers/resourcemanager/recaser/recase.go index 28c64fa3397f..3e8b9a54212a 100644 --- a/vendor/github.com/hashicorp/go-azure-helpers/resourcemanager/recaser/recase.go +++ b/vendor/github.com/hashicorp/go-azure-helpers/resourcemanager/recaser/recase.go @@ -5,9 +5,11 @@ package recaser import ( "fmt" + "reflect" "regexp" "strings" + "github.com/hashicorp/go-azure-helpers/lang/pointer" "github.com/hashicorp/go-azure-helpers/resourcemanager/resourceids" ) @@ -17,38 +19,89 @@ func ReCase(input string) string { } // reCaseWithIds tries to determine the type of Resource ID defined in `input` to be able to re-case it based on an input list of Resource IDs +// this is a "best-effort" function and can return the input unmodified. Functionality of this method is intended to be +// limited to resource IDs that have been registered with the package via the RegisterResourceId() function at init. +// However, some common static segments are corrected even when a corresponding ID type is not present. func reCaseWithIds(input string, ids map[string]resourceids.ResourceId) string { + result, err := reCaseKnownId(input, ids) + if err == nil { + return pointer.From(result) + } + output := input - recased := false + // if we didn't find a matching id then re-case these known segments for best effort + segmentsToFix := []string{ + "/subscriptions/", + "/resourceGroups/", + "/managementGroups/", + "/tenants/", + } + + for _, segment := range segmentsToFix { + output = fixSegment(output, segment) + } + + return output +} + +// ReCaseKnownId attempts to correct the casing on the static segments of an Azure resourceId. Functionality of this +// method is intended to be limited to resource IDs that have been registered with the package via the +// RegisterResourceId() function at init. +func ReCaseKnownId(input string) (*string, error) { + return reCaseKnownId(input, knownResourceIds) +} + +func reCaseKnownId(input string, ids map[string]resourceids.ResourceId) (*string, error) { + output := input + parsed := false key, ok := buildInputKey(input) if ok { id := ids[*key] if id != nil { - output, recased = parseId(id, input) + var parseError error + output, parseError = parseId(id, input) + if parseError != nil { + return &output, fmt.Errorf("fixing case for ID '%s': %+v", input, parseError) + } + parsed = true + } else { + for _, v := range PotentialScopeValues() { + trimmedKey := strings.TrimPrefix(*key, v) + if id = knownResourceIds[trimmedKey]; id != nil { + var parseError error + output, parseError = parseId(id, input) + if parseError != nil { + return &output, fmt.Errorf("fixing case for ID '%s': %+v", input, parseError) + } else { + parsed = true + break + } + } + // We have some cases where an erroneous trailing '/' causes problems. These may be data errors in specs, or API responses. + // Either way, we can try and compensate for it. + if id = knownResourceIds[strings.TrimPrefix(*key, strings.TrimSuffix(v, "/"))]; id != nil { + var parseError error + output, parseError = parseId(id, input) + if parseError != nil { + return &output, fmt.Errorf("fixing case for ID '%s': %+v", input, parseError) + } else { + parsed = true + break + } + } + } } } - // if we can't find a matching id recase these known segments - if !recased { - - segmentsToFix := []string{ - "/subscriptions/", - "/resourceGroups/", - "/managementGroups/", - "/tenants/", - } - - for _, segment := range segmentsToFix { - output = fixSegment(output, segment) - } + if !parsed { + return &output, fmt.Errorf("could not determine ID type for '%s', or ID type not supported", input) } - - return output + return &output, nil } // parseId uses the specified ResourceId to parse the input and returns the id string with correct casing -func parseId(id resourceids.ResourceId, input string) (string, bool) { +func parseId(id resourceids.ResourceId, input string) (string, error) { // we need to take a local copy of id to work against else we're mutating the original localId := id @@ -56,15 +109,19 @@ func parseId(id resourceids.ResourceId, input string) (string, bool) { parser := resourceids.NewParserFromResourceIdType(localId) parsed, err := parser.Parse(input, true) if err != nil { - return input, false + return input, err + } + + if scope := parsed.Parsed["scope"]; scope != "" { + parsed.Parsed["scope"] = reCaseWithIds(scope, knownResourceIds) } if err = id.FromParseResult(*parsed); err != nil { - return input, false + return input, err } input = id.ID() - return input, true + return input, err } // fixSegment searches the input id string for a specified segment case-insensitively @@ -81,9 +138,13 @@ func fixSegment(input, segment string) string { // so it can be used as a key to extract the correct id from knownResourceIds func buildInputKey(input string) (*string, bool) { - // don't attempt to build a key if this isn't a standard resource id + // Attempt to determine if this is just missing a leading slash and prepend it if it seems to be if !strings.HasPrefix(input, "/") { - return nil, false + if len(input) == 0 || !strings.Contains(input, "/") { + return nil, false + } + + input = "/" + input } output := "" @@ -111,3 +172,44 @@ func buildInputKey(input string) (*string, bool) { output = strings.ToLower(output) return &output, true } + +// PotentialScopeValues returns a list of possible ScopeSegment values from all registered ID types +// This is a best effort process, limited to scope targets that are prefixed with '/subscriptions/' or '/providers/' +func PotentialScopeValues() []string { + result := make([]string, 0) + for k := range knownResourceIds { + if strings.HasPrefix(k, "/subscriptions/") || strings.HasPrefix(k, "/providers/") { + result = append(result, k) + } + } + + return result +} + +// ResourceIdTypeFromResourceId takes a Azure Resource ID as a string and attempts to return the corresponding +// resourceids.ResourceId type. If a matching resourceId is not found in the supported/registered resourceId types then +// a `nil` value is returned. +func ResourceIdTypeFromResourceId(input string) resourceids.ResourceId { + key, ok := buildInputKey(input) + if ok { + id := knownResourceIds[*key] + if id != nil { + result := reflect.New(reflect.TypeOf(id).Elem()) + return result.Interface().(resourceids.ResourceId) + } else { + for _, v := range PotentialScopeValues() { + trimmedKey := strings.TrimPrefix(*key, v) + if id = knownResourceIds[trimmedKey]; id != nil { + result := reflect.New(reflect.TypeOf(id).Elem()) + return result.Interface().(resourceids.ResourceId) + } + if id = knownResourceIds[strings.TrimPrefix(*key, strings.TrimSuffix(v, "/"))]; id != nil { + result := reflect.New(reflect.TypeOf(id).Elem()) + return result.Interface().(resourceids.ResourceId) + } + } + } + } + + return nil +} diff --git a/vendor/github.com/hashicorp/go-azure-helpers/resourcemanager/recaser/registration.go b/vendor/github.com/hashicorp/go-azure-helpers/resourcemanager/recaser/registration.go index 77f23a27e800..0f563b330e33 100644 --- a/vendor/github.com/hashicorp/go-azure-helpers/resourcemanager/recaser/registration.go +++ b/vendor/github.com/hashicorp/go-azure-helpers/resourcemanager/recaser/registration.go @@ -13,6 +13,15 @@ import ( var knownResourceIds = make(map[string]resourceids.ResourceId) +// KnownResourceIds returns the map of resource IDs that have been registered by each API imported via the +// RegisterResourceId function. This is the case for all APIs generated via the Pandora project via init(). +// The keys for the map are the lower-cased ID strings with the user-specified segments +// stripped out, leaving the path intact. Example: +// "/subscriptions//resourceGroups//providers/Microsoft.BotService/botServices/" +func KnownResourceIds() map[string]resourceids.ResourceId { + return knownResourceIds +} + var resourceIdsWriteLock = &sync.Mutex{} func init() { diff --git a/vendor/modules.txt b/vendor/modules.txt index 3f062b783357..7a34769715e2 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -131,7 +131,7 @@ github.com/google/uuid # github.com/hashicorp/errwrap v1.1.0 ## explicit github.com/hashicorp/errwrap -# github.com/hashicorp/go-azure-helpers v0.69.0 +# github.com/hashicorp/go-azure-helpers v0.70.0 ## explicit; go 1.21 github.com/hashicorp/go-azure-helpers/eventhub github.com/hashicorp/go-azure-helpers/lang/dates