Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
azurerm_role_assignment
- fix race condition in read after create (#…
- Loading branch information
1 parent
1a1fa48
commit 9f834a6
Showing
4 changed files
with
324 additions
and
34 deletions.
There are no files selected for viewing
90 changes: 90 additions & 0 deletions
90
azurerm/internal/services/authorization/parse/role_assignment.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,90 @@ | ||
package parse | ||
|
||
import ( | ||
"fmt" | ||
"strings" | ||
|
||
"github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" | ||
) | ||
|
||
type RoleAssignmentId struct { | ||
SubscriptionID string | ||
ResourceGroup string | ||
ManagementGroup string | ||
Name string | ||
} | ||
|
||
func NewRoleAssignmentID(subscriptionId, resourceGroup, managementGroup, name string) (*RoleAssignmentId, error) { | ||
if subscriptionId == "" && resourceGroup == "" && managementGroup == "" { | ||
return nil, fmt.Errorf("one of subscriptionId, resourceGroup, or managementGroup must be provided") | ||
} | ||
|
||
if managementGroup != "" { | ||
if subscriptionId != "" || resourceGroup != "" { | ||
return nil, fmt.Errorf("cannot provide subscriptionId or resourceGroup when managementGroup is provided") | ||
} | ||
} | ||
|
||
if resourceGroup != "" { | ||
if subscriptionId == "" { | ||
return nil, fmt.Errorf("subscriptionId must not be empty when resourceGroup is provided") | ||
} | ||
} | ||
|
||
return &RoleAssignmentId{ | ||
SubscriptionID: subscriptionId, | ||
ResourceGroup: resourceGroup, | ||
ManagementGroup: managementGroup, | ||
Name: name, | ||
}, nil | ||
} | ||
|
||
func (id RoleAssignmentId) ID() string { | ||
if id.ManagementGroup != "" { | ||
fmtString := "/providers/Microsoft.Management/managementGroups/%s/providers/Microsoft.Authorization/roleAssignments/%s" | ||
return fmt.Sprintf(fmtString, id.ManagementGroup, id.Name) | ||
} | ||
|
||
if id.ResourceGroup != "" { | ||
fmtString := "/subscriptions/%s/resourceGroups/%s/providers/Microsoft.Authorization/roleAssignments/%s" | ||
return fmt.Sprintf(fmtString, id.SubscriptionID, id.ResourceGroup, id.Name) | ||
} | ||
|
||
fmtString := "/subscriptions/%s/providers/Microsoft.Authorization/roleAssignments/%s" | ||
return fmt.Sprintf(fmtString, id.SubscriptionID, id.Name) | ||
} | ||
|
||
func RoleAssignmentID(input string) (*RoleAssignmentId, error) { | ||
if len(input) == 0 { | ||
return nil, fmt.Errorf("Role Assignment ID is empty string") | ||
} | ||
|
||
roleAssignmentId := RoleAssignmentId{} | ||
|
||
switch { | ||
case strings.HasPrefix(input, "/subscriptions/"): | ||
id, err := azure.ParseAzureResourceID(input) | ||
if err != nil { | ||
return nil, fmt.Errorf("could not parse %q as Azure resource ID", input) | ||
} | ||
roleAssignmentId.SubscriptionID = id.SubscriptionID | ||
roleAssignmentId.ResourceGroup = id.ResourceGroup | ||
if roleAssignmentId.Name, err = id.PopSegment("roleAssignments"); err != nil { | ||
return nil, err | ||
} | ||
case strings.HasPrefix(input, "/providers/Microsoft.Management/"): | ||
idParts := strings.Split(input, "/providers/Microsoft.Authorization/roleAssignments/") | ||
if len(idParts) != 2 { | ||
return nil, fmt.Errorf("could not parse Role Assignment ID %q for Management Group", input) | ||
} | ||
if idParts[1] == "" { | ||
return nil, fmt.Errorf("ID was missing a value for the roleAssignments element") | ||
} | ||
roleAssignmentId.Name = idParts[1] | ||
roleAssignmentId.ManagementGroup = strings.TrimPrefix(idParts[0], "/providers/Microsoft.Management/managementGroups/") | ||
default: | ||
return nil, fmt.Errorf("could not parse Role Assignment ID %q", input) | ||
} | ||
|
||
return &roleAssignmentId, nil | ||
} |
188 changes: 188 additions & 0 deletions
188
azurerm/internal/services/authorization/parse/role_assignment_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,188 @@ | ||
package parse | ||
|
||
import ( | ||
"testing" | ||
|
||
"github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/resourceid" | ||
) | ||
|
||
var _ resourceid.Formatter = RoleAssignmentId{} | ||
|
||
func TestRoleAssignmentIDFormatter(t *testing.T) { | ||
testData := []struct { | ||
SubscriptionId string | ||
ResourceGroup string | ||
ManagementGroup string | ||
Name string | ||
Expected string | ||
}{ | ||
{ | ||
SubscriptionId: "", | ||
ResourceGroup: "", | ||
ManagementGroup: "", | ||
Name: "23456781-2349-8764-5631-234567890121", | ||
}, | ||
{ | ||
SubscriptionId: "12345678-1234-9876-4563-123456789012", | ||
ResourceGroup: "group1", | ||
ManagementGroup: "managementGroup1", | ||
Name: "23456781-2349-8764-5631-234567890121", | ||
}, | ||
{ | ||
SubscriptionId: "12345678-1234-9876-4563-123456789012", | ||
ResourceGroup: "", | ||
ManagementGroup: "managementGroup1", | ||
Name: "23456781-2349-8764-5631-234567890121", | ||
}, | ||
{ | ||
SubscriptionId: "12345678-1234-9876-4563-123456789012", | ||
ResourceGroup: "", | ||
ManagementGroup: "", | ||
Name: "23456781-2349-8764-5631-234567890121", | ||
Expected: "/subscriptions/12345678-1234-9876-4563-123456789012/providers/Microsoft.Authorization/roleAssignments/23456781-2349-8764-5631-234567890121", | ||
}, | ||
{ | ||
SubscriptionId: "12345678-1234-9876-4563-123456789012", | ||
ResourceGroup: "group1", | ||
ManagementGroup: "", | ||
Name: "23456781-2349-8764-5631-234567890121", | ||
Expected: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/group1/providers/Microsoft.Authorization/roleAssignments/23456781-2349-8764-5631-234567890121", | ||
}, | ||
{ | ||
SubscriptionId: "", | ||
ResourceGroup: "", | ||
ManagementGroup: "12345678-1234-9876-4563-123456789012", | ||
Name: "23456781-2349-8764-5631-234567890121", | ||
Expected: "/providers/Microsoft.Management/managementGroups/12345678-1234-9876-4563-123456789012/providers/Microsoft.Authorization/roleAssignments/23456781-2349-8764-5631-234567890121", | ||
}, | ||
} | ||
for _, v := range testData { | ||
t.Logf("testing %+v", v) | ||
actual, err := NewRoleAssignmentID(v.SubscriptionId, v.ResourceGroup, v.ManagementGroup, v.Name) | ||
if err != nil { | ||
if v.Expected == "" { | ||
continue | ||
} | ||
} | ||
actualId := actual.ID() | ||
if actualId != v.Expected { | ||
t.Fatalf("expected %q, got %q", v.Expected, actualId) | ||
} | ||
} | ||
} | ||
|
||
func TestRoleAssignmentID(t *testing.T) { | ||
testData := []struct { | ||
Input string | ||
Error bool | ||
Expected *RoleAssignmentId | ||
}{ | ||
{ | ||
// empty | ||
Input: "", | ||
Error: true, | ||
}, | ||
|
||
{ | ||
// missing SubscriptionId | ||
Input: "/", | ||
Error: true, | ||
}, | ||
|
||
{ | ||
// just subscription | ||
Input: "/subscriptions/12345678-1234-9876-4563-123456789012/", | ||
Error: true, | ||
}, | ||
|
||
{ | ||
// missing ResourceGroup value | ||
Input: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/", | ||
Error: true, | ||
}, | ||
|
||
{ | ||
// missing Management Group value | ||
Input: "/providers/Microsoft.Management/managementGroups/", | ||
Error: true, | ||
}, | ||
|
||
{ | ||
// missing Role Assignment value at Subscription Scope | ||
Input: "/subscriptions/12345678-1234-9876-4563-123456789012/providers/Microsoft.Authorization/roleAssignments/", | ||
Error: true, | ||
}, | ||
|
||
{ | ||
// missing Role Assignment value at Management Group scope | ||
Input: "/providers/Microsoft.Management/managementGroups/managementGroup1/providers/Microsoft.Authorization/roleAssignments/", | ||
Error: true, | ||
}, | ||
|
||
{ | ||
// valid at subscription scope | ||
Input: "/subscriptions/12345678-1234-9876-4563-123456789012/providers/Microsoft.Authorization/roleAssignments/23456781-2349-8764-5631-234567890121", | ||
Expected: &RoleAssignmentId{ | ||
SubscriptionID: "12345678-1234-9876-4563-123456789012", | ||
ResourceGroup: "", | ||
ManagementGroup: "", | ||
Name: "23456781-2349-8764-5631-234567890121", | ||
}, | ||
}, | ||
|
||
{ | ||
// valid at resource group scope | ||
Input: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/group1/providers/Microsoft.Authorization/roleAssignments/23456781-2349-8764-5631-234567890121", | ||
Expected: &RoleAssignmentId{ | ||
SubscriptionID: "12345678-1234-9876-4563-123456789012", | ||
ResourceGroup: "group1", | ||
ManagementGroup: "", | ||
Name: "23456781-2349-8764-5631-234567890121", | ||
}, | ||
}, | ||
|
||
{ | ||
// valid at management group scope | ||
Input: "/providers/Microsoft.Management/managementGroups/managementGroup1/providers/Microsoft.Authorization/roleAssignments/23456781-2349-8764-5631-234567890121", | ||
Expected: &RoleAssignmentId{ | ||
SubscriptionID: "", | ||
ResourceGroup: "", | ||
ManagementGroup: "managementGroup1", | ||
Name: "23456781-2349-8764-5631-234567890121", | ||
}, | ||
}, | ||
} | ||
|
||
for _, v := range testData { | ||
t.Logf("[DEBUG] Testing %q", v.Input) | ||
|
||
actual, err := RoleAssignmentID(v.Input) | ||
if err != nil { | ||
if v.Error { | ||
continue | ||
} | ||
|
||
t.Fatalf("expected a value but got an error: %+v", err) | ||
} | ||
|
||
if v.Error { | ||
t.Fatal("Expect an error but didn't get one") | ||
} | ||
|
||
if actual.Name != v.Expected.Name { | ||
t.Fatalf("Expected %q but got %q for Role Assignment Name", v.Expected.Name, actual.Name) | ||
} | ||
|
||
if actual.SubscriptionID != v.Expected.SubscriptionID { | ||
t.Fatalf("Expected %q but got %q for Role Assignment Name", v.Expected.SubscriptionID, actual.SubscriptionID) | ||
} | ||
|
||
if actual.ResourceGroup != v.Expected.ResourceGroup { | ||
t.Fatalf("Expected %q but got %q for Role Assignment Name", v.Expected.ResourceGroup, actual.ResourceGroup) | ||
} | ||
|
||
if actual.ManagementGroup != v.Expected.ManagementGroup { | ||
t.Fatalf("Expected %q but got %q for Role Assignment Name", v.Expected.ManagementGroup, actual.ManagementGroup) | ||
} | ||
} | ||
} |
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
Oops, something went wrong.