Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update data source azurerm_management_group - support get data source of mgmt group by using display_name #6845

Merged
merged 6 commits into from Jun 17, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
@@ -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"),
tombuildsstuff marked this conversation as resolved.
Show resolved Hide resolved
),
},
},
})
}

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