From 34c6aed906254cc31587c58b5d3706055316c35e Mon Sep 17 00:00:00 2001 From: xuwu1 Date: Thu, 21 Mar 2024 13:45:24 +0800 Subject: [PATCH] resourceid parser support data plane host segment --- resourcemanager/resourceids/errors.go | 5 +++ resourcemanager/resourceids/interface.go | 12 +++++++ resourcemanager/resourceids/parse.go | 21 ++++++++++- resourcemanager/resourceids/parse_test.go | 44 +++++++++++++++++++++++ 4 files changed, 81 insertions(+), 1 deletion(-) diff --git a/resourcemanager/resourceids/errors.go b/resourcemanager/resourceids/errors.go index 2b01ce7a..8cd5bfea 100644 --- a/resourcemanager/resourceids/errors.go +++ b/resourcemanager/resourceids/errors.go @@ -98,6 +98,11 @@ func descriptionForSpecifiedSegment(segment Segment) (*string, error) { msg := fmt.Sprintf("should be the user specified value for this %s [for example %q]", name, segment.ExampleValue) return &msg, nil } + case DataPlaneHostSegmentType: + { + msg := fmt.Sprintf("should be the data plane host for this %s [for example %q]", segment.Name, segment.ExampleValue) + return &msg, nil + } } return nil, fmt.Errorf("internal-error: the Segment Type %q was not implemented for Segment %q", string(segment.Type), segment.Name) diff --git a/resourcemanager/resourceids/interface.go b/resourcemanager/resourceids/interface.go index 084ecc63..35b5f2c4 100644 --- a/resourcemanager/resourceids/interface.go +++ b/resourcemanager/resourceids/interface.go @@ -63,6 +63,9 @@ const ( // UserSpecifiedSegmentType specifies that this Segment is User-Specifiable UserSpecifiedSegmentType SegmentType = "UserSpecified" + + // DataPlaneHostSegmentType sepcifies that this Segment is a Data Plane Host + DataPlaneHostSegmentType SegmentType = "DataPlaneHost" ) // ConstantSegment is a helper which returns a Segment for a Constant @@ -130,3 +133,12 @@ func UserSpecifiedSegment(name, exampleValue string) Segment { ExampleValue: exampleValue, } } + +// DataPlaneHostSegment is a helper which returns a Segment for a Data Plane Host +func DataPlaneHostSegment(name, exampleValue string) Segment { + return Segment{ + Name: name, + Type: DataPlaneHostSegmentType, + ExampleValue: exampleValue, + } +} diff --git a/resourcemanager/resourceids/parse.go b/resourcemanager/resourceids/parse.go index f3d97426..1a47843f 100644 --- a/resourcemanager/resourceids/parse.go +++ b/resourcemanager/resourceids/parse.go @@ -5,6 +5,7 @@ package resourceids import ( "fmt" + "net/url" "regexp" "strings" ) @@ -100,6 +101,10 @@ func (p Parser) Parse(input string, insensitively bool) (*ParseResult, error) { } switch segment.Type { + case DataPlaneHostSegmentType: + if i != 0 { + return nil, fmt.Errorf("internal error: data plane host segment %q is not at the start of the Resource ID", segment.Name) + } case ConstantSegmentType: { if segment.PossibleValues == nil { @@ -155,8 +160,22 @@ func (p Parser) Parse(input string, insensitively bool) (*ParseResult, error) { uri = fmt.Sprintf("fakestart/%s", uri) } + var domain string + if p.segments[0].Type == DataPlaneHostSegmentType { + if u, err := url.Parse(uri); err != nil { + return nil, fmt.Errorf("parsing data plane host segment: %+v", err) + } else { + domain = fmt.Sprintf("%s://%s", u.Scheme, u.Host) + uri = u.Path + } + } + uri = strings.TrimPrefix(uri, "/") split := strings.Split(uri, "/") + if domain != "" { + split = append([]string{domain}, split...) + } + segmentCount := len(split) if segmentCount < len(p.segments) { return nil, NewNumberOfSegmentsDidntMatchError(p.resourceId, parseResult) @@ -270,7 +289,7 @@ func (p Parser) parseSegment(segment Segment, rawValue string, insensitively boo return nil, fmt.Errorf("internal error: scope segments aren't supported unless at the start or the end") } - case ResourceGroupSegmentType, SubscriptionIdSegmentType, UserSpecifiedSegmentType: + case ResourceGroupSegmentType, SubscriptionIdSegmentType, UserSpecifiedSegmentType, DataPlaneHostSegmentType: { return &rawValue, nil } diff --git a/resourcemanager/resourceids/parse_test.go b/resourcemanager/resourceids/parse_test.go index 20e1aead..7f71678c 100644 --- a/resourcemanager/resourceids/parse_test.go +++ b/resourcemanager/resourceids/parse_test.go @@ -1016,6 +1016,50 @@ func TestParseIdContainingJustAScope(t *testing.T) { } } +func TestParseIdDataPlane(t *testing.T) { + segments := []resourceids.Segment{ + resourceids.DataPlaneHostSegment("domainName", "domainValue"), + resourceids.StaticSegment("staticExample", "example", "example"), + resourceids.UserSpecifiedSegment("fooName", "fooValue"), + resourceids.UserSpecifiedSegment("barName", "barValue"), + } + testData := []struct { + name string + input string + expected *resourceids.ParseResult + insensitive bool + }{ + { + name: "empty", + input: "", + insensitive: false, + }, + { + name: "with https", + input: "https://example.com/example/foo/bar", + insensitive: false, + expected: &resourceids.ParseResult{ + Parsed: map[string]string{ + "domainName": "https://example.com", + "staticExample": "example", + "fooName": "foo", + "barName": "bar", + }, + RawInput: "https://example.com/example/foo/bar", + }, + }, + } + for _, test := range testData { + t.Logf("Test %q..", test.name) + rid := fakeIdParser{ + segments, + } + parser := resourceids.NewParserFromResourceIdType(rid) + actual, err := parser.Parse(test.input, test.insensitive) + validateResult(t, actual, test.expected, err) + } +} + var _ resourceids.ResourceId = fakeIdParser{} type fakeIdParser struct {