Skip to content

Commit

Permalink
Update data source azurerm_management_group - support get data sour…
Browse files Browse the repository at this point in the history
…ce of mgmt group by using `display_name` (#6845)

Fixes #6757
  • Loading branch information
ArcturusZhang committed Jun 17, 2020
1 parent 02626df commit c969611
Show file tree
Hide file tree
Showing 3 changed files with 93 additions and 13 deletions.
@@ -1,6 +1,7 @@
package managementgroup

import (
"context"
"fmt"
"time"

Expand All @@ -25,22 +26,24 @@ func dataSourceArmManagementGroup() *schema.Resource {
Type: schema.TypeString,
Optional: true,
Computed: true,
ExactlyOneOf: []string{"name", "group_id"},
ExactlyOneOf: []string{"name", "group_id", "display_name"},
Deprecated: "Deprecated in favour of `name`",
ValidateFunc: validate.ManagementGroupName,
},

"name": {
Type: schema.TypeString,
Optional: true, // TODO -- change back to required after the deprecation
Computed: true, // TODO -- remove computed after the deprecation
ExactlyOneOf: []string{"name", "group_id"},
Optional: true,
Computed: true,
ExactlyOneOf: []string{"name", "group_id", "display_name"},
ValidateFunc: validate.ManagementGroupName,
},

"display_name": {
Type: schema.TypeString,
Computed: true,
Type: schema.TypeString,
Optional: true,
Computed: true,
ExactlyOneOf: []string{"name", "group_id", "display_name"},
},

"parent_management_group_id": {
Expand Down Expand Up @@ -70,15 +73,25 @@ func dataSourceArmManagementGroupRead(d *schema.ResourceData, meta interface{})
if v, ok := d.GetOk("group_id"); ok {
groupName = v.(string)
}
displayName := d.Get("display_name").(string)

// one of displayName and groupName must be non-empty, this is guaranteed by schema
// if the user is retrieving the mgmt group by display name, use the list api to get the group name first
var err error
if displayName != "" {
groupName, err = getManagementGroupNameByDisplayName(ctx, client, displayName)
if err != nil {
return fmt.Errorf("Error reading Management Group (Display Name %q): %+v", displayName, err)
}
}
recurse := true
resp, err := client.Get(ctx, groupName, "children", &recurse, "", managementGroupCacheControl)
if err != nil {
if utils.ResponseWasForbidden(resp.Response) {
return fmt.Errorf("Management Group %q was not found", groupName)
}

return fmt.Errorf("Error reading Management Group %q: %+v", d.Id(), err)
return fmt.Errorf("Error reading Management Group %q: %+v", groupName, err)
}

if resp.ID == nil {
Expand Down Expand Up @@ -112,6 +125,37 @@ func dataSourceArmManagementGroupRead(d *schema.ResourceData, meta interface{})
return nil
}

func getManagementGroupNameByDisplayName(ctx context.Context, client *managementgroups.Client, displayName string) (string, error) {
iterator, err := client.ListComplete(ctx, managementGroupCacheControl, "")
if err != nil {
return "", fmt.Errorf("Error listing Management Groups: %+v", err)
}

var results []string
for iterator.NotDone() {
group := iterator.Value()
if group.DisplayName != nil && *group.DisplayName == displayName && group.Name != nil && *group.Name != "" {
results = append(results, *group.Name)
}

if err := iterator.NextWithContext(ctx); err != nil {
return "", fmt.Errorf("Error listing Management Groups: %+v", err)
}
}

// we found none
if len(results) == 0 {
return "", fmt.Errorf("Management Group (Display Name %q) was not found", displayName)
}

// we found more than one
if len(results) > 1 {
return "", fmt.Errorf("expected a single Management Group with the Display Name %q but expected one", displayName)
}

return results[0], nil
}

func flattenArmManagementGroupDataSourceSubscriptionIds(input *[]managementgroups.ChildInfo) (*schema.Set, error) {
subscriptionIds := &schema.Set{F: schema.HashString}
if input == nil {
Expand Down
Expand Up @@ -8,15 +8,15 @@ import (
"github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/acceptance"
)

func TestAccDataSourceArmManagementGroup_basic(t *testing.T) {
func TestAccDataSourceArmManagementGroup_basicByName(t *testing.T) {
data := acceptance.BuildTestData(t, "data.azurerm_management_group", "test")

resource.ParallelTest(t, resource.TestCase{
PreCheck: func() { acceptance.PreCheck(t) },
Providers: acceptance.SupportedProviders,
Steps: []resource.TestStep{
{
Config: testAccDataSourceArmManagementGroup_basic(data),
Config: testAccDataSourceArmManagementGroup_basicByName(data),
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttr(data.ResourceName, "display_name", fmt.Sprintf("acctestmg-%d", data.RandomInteger)),
resource.TestCheckResourceAttr(data.ResourceName, "subscription_ids.#", "0"),
Expand All @@ -26,7 +26,25 @@ func TestAccDataSourceArmManagementGroup_basic(t *testing.T) {
})
}

func testAccDataSourceArmManagementGroup_basic(data acceptance.TestData) string {
func TestAccDataSourceArmManagementGroup_basicByDisplayName(t *testing.T) {
data := acceptance.BuildTestData(t, "data.azurerm_management_group", "test")

resource.ParallelTest(t, resource.TestCase{
PreCheck: func() { acceptance.PreCheck(t) },
Providers: acceptance.SupportedProviders,
Steps: []resource.TestStep{
{
Config: testAccDataSourceArmManagementGroup_basicByDisplayName(data),
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttr(data.ResourceName, "display_name", fmt.Sprintf("acctest Management Group %d", data.RandomInteger)),
resource.TestCheckResourceAttr(data.ResourceName, "subscription_ids.#", "0"),
),
},
},
})
}

func testAccDataSourceArmManagementGroup_basicByName(data acceptance.TestData) string {
return fmt.Sprintf(`
provider "azurerm" {
features {}
Expand All @@ -41,3 +59,19 @@ data "azurerm_management_group" "test" {
}
`, data.RandomInteger)
}

func testAccDataSourceArmManagementGroup_basicByDisplayName(data acceptance.TestData) string {
return fmt.Sprintf(`
provider "azurerm" {
features {}
}
resource "azurerm_management_group" "test" {
display_name = "acctest Management Group %d"
}
data "azurerm_management_group" "test" {
display_name = azurerm_management_group.test.display_name
}
`, data.RandomInteger)
}
8 changes: 5 additions & 3 deletions website/docs/d/management_group.html.markdown
Expand Up @@ -32,17 +32,19 @@ The following arguments are supported:

~> **NOTE:** The field `group_id` has been deprecated in favour of `name`.

* `display_name` - Specifies the display name of this Management Group.

~> **NOTE** Whilst multiple management groups may share the same display name, when filtering Terraform expects a single management group to be found with this name.

## Attributes Reference

The following attributes are exported:

* `id` - The ID of the Management Group.

* `display_name` - A friendly name for the Management Group.

* `parent_management_group_id` - The ID of any Parent Management Group.

* `subscription_ids` - A list of Subscription ID's which are assigned to the Management Group.
* `subscription_ids` - A list of Subscription IDs which are assigned to the Management Group.

## Timeouts

Expand Down

0 comments on commit c969611

Please sign in to comment.