-
Notifications
You must be signed in to change notification settings - Fork 43
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #213 from hashicorp/billenracc
commonids: add commonid for BillingAccountCustomerId
- Loading branch information
Showing
2 changed files
with
332 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,117 @@ | ||
// Copyright (c) HashiCorp, Inc. | ||
// SPDX-License-Identifier: MPL-2.0 | ||
|
||
package commonids | ||
|
||
import ( | ||
"fmt" | ||
"strings" | ||
|
||
"github.com/hashicorp/go-azure-helpers/resourcemanager/resourceids" | ||
) | ||
|
||
var _ resourceids.ResourceId = &BillingAccountCustomerId{} | ||
|
||
// BillingAccountCustomerId is a struct representing the Resource ID for a Billing Account Customer | ||
type BillingAccountCustomerId struct { | ||
BillingAccountName string | ||
CustomerName string | ||
} | ||
|
||
// NewBillingAccountCustomerID returns a new BillingAccountCustomerId struct | ||
func NewBillingAccountCustomerID(billingAccountName string, customerName string) BillingAccountCustomerId { | ||
return BillingAccountCustomerId{ | ||
BillingAccountName: billingAccountName, | ||
CustomerName: customerName, | ||
} | ||
} | ||
|
||
// ParseBillingAccountCustomerID parses 'input' into a BillingAccountCustomerId | ||
func ParseBillingAccountCustomerID(input string) (*BillingAccountCustomerId, error) { | ||
parser := resourceids.NewParserFromResourceIdType(&BillingAccountCustomerId{}) | ||
parsed, err := parser.Parse(input, false) | ||
if err != nil { | ||
return nil, fmt.Errorf("parsing %q: %+v", input, err) | ||
} | ||
|
||
id := BillingAccountCustomerId{} | ||
if err = id.FromParseResult(*parsed); err != nil { | ||
return nil, err | ||
} | ||
|
||
return &id, nil | ||
} | ||
|
||
// ParseBillingAccountCustomerIDInsensitively parses 'input' case-insensitively into a BillingAccountCustomerId | ||
// note: this method should only be used for API response data and not user input | ||
func ParseBillingAccountCustomerIDInsensitively(input string) (*BillingAccountCustomerId, error) { | ||
parser := resourceids.NewParserFromResourceIdType(&BillingAccountCustomerId{}) | ||
parsed, err := parser.Parse(input, true) | ||
if err != nil { | ||
return nil, fmt.Errorf("parsing %q: %+v", input, err) | ||
} | ||
|
||
id := BillingAccountCustomerId{} | ||
if err = id.FromParseResult(*parsed); err != nil { | ||
return nil, err | ||
} | ||
|
||
return &id, nil | ||
} | ||
|
||
func (id *BillingAccountCustomerId) FromParseResult(input resourceids.ParseResult) error { | ||
|
||
var ok bool | ||
|
||
if id.BillingAccountName, ok = input.Parsed["billingAccountName"]; !ok { | ||
return resourceids.NewSegmentNotSpecifiedError(id, "billingAccountName", input) | ||
} | ||
|
||
if id.CustomerName, ok = input.Parsed["customerName"]; !ok { | ||
return resourceids.NewSegmentNotSpecifiedError(id, "customerName", input) | ||
} | ||
|
||
return nil | ||
} | ||
|
||
// ValidateBillingAccountCustomerID checks that 'input' can be parsed as a Billing Account Customer ID | ||
func ValidateBillingAccountCustomerID(input interface{}, key string) (warnings []string, errors []error) { | ||
v, ok := input.(string) | ||
if !ok { | ||
errors = append(errors, fmt.Errorf("expected %q to be a string", key)) | ||
return | ||
} | ||
|
||
if _, err := ParseBillingAccountCustomerID(v); err != nil { | ||
errors = append(errors, err) | ||
} | ||
|
||
return | ||
} | ||
|
||
// ID returns the formatted Billing Account Customer ID | ||
func (id BillingAccountCustomerId) ID() string { | ||
fmtString := "/providers/Microsoft.Billing/billingAccounts/%s/customers/%s" | ||
return fmt.Sprintf(fmtString, id.BillingAccountName, id.CustomerName) | ||
} | ||
|
||
// Segments returns a slice of Resource ID Segments which comprise this Billing Account Customer ID | ||
func (id BillingAccountCustomerId) Segments() []resourceids.Segment { | ||
return []resourceids.Segment{ | ||
resourceids.StaticSegment("providers", "providers", "providers"), | ||
resourceids.ResourceProviderSegment("resourceProvider", "Microsoft.Billing", "Microsoft.Billing"), | ||
resourceids.StaticSegment("billingAccounts", "billingAccounts", "billingAccounts"), | ||
resourceids.UserSpecifiedSegment("billingAccountName", "billingAccountValue"), | ||
resourceids.StaticSegment("customers", "customers", "customers"), | ||
resourceids.UserSpecifiedSegment("customerName", "customerValue"), | ||
} | ||
} | ||
|
||
// String returns a human-readable description of this Billing Account Customer ID | ||
func (id BillingAccountCustomerId) String() string { | ||
components := []string{ | ||
fmt.Sprintf("Billing Account Name: %q", id.BillingAccountName), | ||
fmt.Sprintf("Customer Name: %q", id.CustomerName), | ||
} | ||
return fmt.Sprintf("Billing Account Customer (%s)", strings.Join(components, "\n")) | ||
} |
215 changes: 215 additions & 0 deletions
215
resourcemanager/commonids/billing_account_customer_test.go
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,215 @@ | ||
// Copyright (c) HashiCorp, Inc. | ||
// SPDX-License-Identifier: MPL-2.0 | ||
|
||
package commonids | ||
|
||
import "testing" | ||
|
||
func TestNewBillingAccountCustomerID(t *testing.T) { | ||
id := NewBillingAccountCustomerID("billingAccountNameValue", "customerNameValue") | ||
|
||
if id.BillingAccountName != "billingAccountNameValue" { | ||
t.Fatalf("Expected %q but got %q for Segment 'BillingAccountName'", "billingAccountNameValue", id.BillingAccountName) | ||
} | ||
|
||
if id.CustomerName != "customerNameValue" { | ||
t.Fatalf("Expected %q but got %q for Segment 'CustomerName'", "customerNameValue", id.CustomerName) | ||
} | ||
|
||
} | ||
|
||
func TestFormatBillingAccountCustomerID(t *testing.T) { | ||
actual := NewBillingAccountCustomerID("billingAccountNameValue", "customerNameValue").ID() | ||
expected := "/providers/Microsoft.Billing/billingAccounts/billingAccountNameValue/customers/customerNameValue" | ||
if actual != expected { | ||
t.Fatalf("Expected the Formatted ID to be %q but got %q", expected, actual) | ||
} | ||
} | ||
|
||
func TestParseBillingAccountCustomerID(t *testing.T) { | ||
testData := []struct { | ||
Input string | ||
Error bool | ||
Expected *BillingAccountCustomerId | ||
}{ | ||
{ | ||
// Incomplete URI | ||
Input: "", | ||
Error: true, | ||
}, | ||
{ | ||
// Incomplete URI | ||
Input: "/providers", | ||
Error: true, | ||
}, | ||
{ | ||
// Incomplete URI | ||
Input: "/providers/Microsoft.Billing", | ||
Error: true, | ||
}, | ||
{ | ||
// Incomplete URI | ||
Input: "/providers/Microsoft.Billing/billingAccounts", | ||
Error: true, | ||
}, | ||
{ | ||
// Incomplete URI | ||
Input: "/providers/Microsoft.Billing/billingAccounts/billingAccountNameValue", | ||
Error: true, | ||
}, | ||
{ | ||
// Valid URI | ||
Input: "/providers/Microsoft.Billing/billingAccounts/billingAccountNameValue/customers/customerNameValue", | ||
Expected: &BillingAccountCustomerId{ | ||
BillingAccountName: "billingAccountNameValue", | ||
CustomerName: "customerNameValue", | ||
}, | ||
}, | ||
{ | ||
// Invalid (Valid Uri with Extra segment) | ||
Input: "/providers/Microsoft.Billing/billingAccounts/billingAccountNameValue/customers/customerNameValue/extra", | ||
Error: true, | ||
}, | ||
} | ||
for _, v := range testData { | ||
t.Logf("[DEBUG] Testing %q", v.Input) | ||
|
||
actual, err := ParseBillingAccountCustomerID(v.Input) | ||
if err != nil { | ||
if v.Error { | ||
continue | ||
} | ||
|
||
t.Fatalf("Expect a value but got an error: %+v", err) | ||
} | ||
if v.Error { | ||
t.Fatal("Expect an error but didn't get one") | ||
} | ||
|
||
if actual.BillingAccountName != v.Expected.BillingAccountName { | ||
t.Fatalf("Expected %q but got %q for BillingAccountName", v.Expected.BillingAccountName, actual.BillingAccountName) | ||
} | ||
|
||
if actual.CustomerName != v.Expected.CustomerName { | ||
t.Fatalf("Expected %q but got %q for CustomerName", v.Expected.CustomerName, actual.CustomerName) | ||
} | ||
} | ||
} | ||
|
||
func TestParseBillingAccountCustomerIDInsensitively(t *testing.T) { | ||
testData := []struct { | ||
Input string | ||
Error bool | ||
Expected *BillingAccountCustomerId | ||
}{ | ||
{ | ||
// Incomplete URI | ||
Input: "", | ||
Error: true, | ||
}, | ||
{ | ||
// Incomplete URI | ||
Input: "/providers", | ||
Error: true, | ||
}, | ||
{ | ||
// Incomplete URI (Insensitively) | ||
Input: "/pRoVideRs", | ||
Error: true, | ||
}, | ||
{ | ||
// Incomplete URI | ||
Input: "/providers/Microsoft.Billing", | ||
Error: true, | ||
}, | ||
{ | ||
// Incomplete URI (Insensitively) | ||
Input: "/ProvIders/MicroSOFT.biLLing", | ||
Error: true, | ||
}, | ||
{ | ||
// Incomplete URI | ||
Input: "/providers/Microsoft.Billing/billingAccounts", | ||
Error: true, | ||
}, | ||
{ | ||
// Incomplete URI (Insensitively) | ||
Input: "/pRoVideRs/MiCrOsOfT.biLLing/BillInGAccouNts", | ||
Error: true, | ||
}, | ||
{ | ||
// Incomplete URI | ||
Input: "/providers/Microsoft.Billing/billingAccounts/billingAccountNameValue", | ||
Error: true, | ||
}, | ||
{ | ||
// Incomplete URI (Insensitively) | ||
Input: "/pRoVideRs/MiCrOsOfT.biLLing/BillInGAccouNts/BillingAcCOUNTNameValue", | ||
Error: true, | ||
}, | ||
{ | ||
// Valid URI | ||
Input: "/providers/Microsoft.Billing/billingAccounts/billingAccountNameValue/customers/customerNameValue", | ||
Expected: &BillingAccountCustomerId{ | ||
BillingAccountName: "billingAccountNameValue", | ||
CustomerName: "customerNameValue", | ||
}, | ||
}, | ||
{ | ||
// Valid URI (Insensitively) | ||
Input: "/ProvIdErs/MIcroSoft.Billing/billingACcOunts/billingAccOuntNameVaLue/Customers/CustomerNaMevALue", | ||
Expected: &BillingAccountCustomerId{ | ||
BillingAccountName: "billingAccOuntNameVaLue", | ||
CustomerName: "CustomerNaMevALue", | ||
}, | ||
}, | ||
{ | ||
// Invalid (Valid Uri with Extra segment) | ||
Input: "/providers/Microsoft.Billing/billingAccounts/billingAccountNameValue/customers/customerNameValue/extra", | ||
Error: true, | ||
}, | ||
{ | ||
// Invalid (Valid Uri with Extra segment) | ||
Input: "/ProvIdErs/MIcroSoft.Billing/billingACcOunts/billingAccOuntNameVaLue/Customers/CustomerNaMevAlue/exTra", | ||
Error: true, | ||
}, | ||
} | ||
for _, v := range testData { | ||
t.Logf("[DEBUG] Testing %q", v.Input) | ||
|
||
actual, err := ParseBillingAccountCustomerIDInsensitively(v.Input) | ||
if err != nil { | ||
if v.Error { | ||
continue | ||
} | ||
|
||
t.Fatalf("Expect a value but got an error: %+v", err) | ||
} | ||
if v.Error { | ||
t.Fatal("Expect an error but didn't get one") | ||
} | ||
|
||
if actual.BillingAccountName != v.Expected.BillingAccountName { | ||
t.Fatalf("Expected %q but got %q for BillingAccountName", v.Expected.BillingAccountName, actual.BillingAccountName) | ||
} | ||
|
||
if actual.CustomerName != v.Expected.CustomerName { | ||
t.Fatalf("Expected %q but got %q for CustomerName", v.Expected.CustomerName, actual.CustomerName) | ||
} | ||
} | ||
} | ||
|
||
func TestSegmentsForBillingAccountCustomerId(t *testing.T) { | ||
segments := BillingAccountCustomerId{}.Segments() | ||
if len(segments) == 0 { | ||
t.Fatalf("BillingAccountCustomerId has no segments") | ||
} | ||
|
||
uniqueNames := make(map[string]struct{}, 0) | ||
for _, segment := range segments { | ||
uniqueNames[segment.Name] = struct{}{} | ||
} | ||
if len(uniqueNames) != len(segments) { | ||
t.Fatalf("Expected the Segments to be unique but got %q unique segments and %d total segments", len(uniqueNames), len(segments)) | ||
} | ||
} |