diff --git a/docs/data-sources/groups.md b/docs/data-sources/groups.md index 55db6bdaf6..7f21b29d9c 100644 --- a/docs/data-sources/groups.md +++ b/docs/data-sources/groups.md @@ -16,20 +16,29 @@ When authenticated with a user principal, this data source does not require any ## Example Usage +*Look up by group name* ```terraform data "azuread_groups" "groups" { display_names = ["group-a", "group-b"] } ``` +*Look up all groups* +```terraform +data "azuread_groups" "allGroups" { + return_all = true +} +``` + ## Argument Reference The following arguments are supported: * `display_names` - (Optional) The display names of the groups. * `object_ids` - (Optional) The object IDs of the groups. +* `return_all` - (Optional) A flag to denote if all groups should be fetched and returned. -~> One of `display_names` or `object_ids` should be specified. Either of these _may_ be specified as an empty list, in which case no results will be returned. +~> One of `display_names`, `object_ids` or `return_all` should be specified. Either of the first two _may_ be specified as an empty list, in which case no results will be returned. ## Attributes Reference diff --git a/internal/services/groups/groups_data_source.go b/internal/services/groups/groups_data_source.go index 95a6c9d8f7..1c461fe00c 100644 --- a/internal/services/groups/groups_data_source.go +++ b/internal/services/groups/groups_data_source.go @@ -34,7 +34,7 @@ func groupsDataSource() *schema.Resource { Type: schema.TypeList, Optional: true, Computed: true, - ExactlyOneOf: []string{"display_names", "object_ids"}, + ExactlyOneOf: []string{"display_names", "object_ids", "return_all"}, Elem: &schema.Schema{ Type: schema.TypeString, ValidateDiagFunc: validate.UUID, @@ -46,12 +46,19 @@ func groupsDataSource() *schema.Resource { Type: schema.TypeList, Optional: true, Computed: true, - ExactlyOneOf: []string{"display_names", "object_ids"}, + ExactlyOneOf: []string{"display_names", "object_ids", "return_all"}, Elem: &schema.Schema{ Type: schema.TypeString, ValidateDiagFunc: validate.NoEmptyStrings, }, }, + + "return_all": { + Description: "Retrieve all groups with no filter", + Type: schema.TypeBool, + Optional: true, + ExactlyOneOf: []string{"display_names", "object_ids", "return_all"}, + }, }, } } @@ -62,13 +69,27 @@ func groupsDataSourceRead(ctx context.Context, d *schema.ResourceData, meta inte var groups []msgraph.Group var expectedCount int + var returnAll = d.Get("return_all").(bool) var displayNames []interface{} if v, ok := d.GetOk("display_names"); ok { displayNames = v.([]interface{}) } - if len(displayNames) > 0 { + if returnAll { + result, _, err := client.List(ctx, odata.Query{}) + if err != nil { + return tf.ErrorDiagF(err, "Could not retrieve groups") + } + if result == nil { + return tf.ErrorDiagF(errors.New("API returned nil result"), "Bad API Response") + } + if len(*result) == 0 { + return tf.ErrorDiagPathF(err, "return_all", "No groups found") + } + + groups = append(groups, *result...) + } else if len(displayNames) > 0 { expectedCount = len(displayNames) for _, v := range displayNames { displayName := v.(string) @@ -105,7 +126,7 @@ func groupsDataSourceRead(ctx context.Context, d *schema.ResourceData, meta inte } } - if len(groups) != expectedCount { + if !returnAll && len(groups) != expectedCount { return tf.ErrorDiagF(fmt.Errorf("Expected: %d, Actual: %d", expectedCount, len(groups)), "Unexpected number of groups returned") } diff --git a/internal/services/groups/groups_data_source_test.go b/internal/services/groups/groups_data_source_test.go index 3401b1d94e..722d5e8cc3 100644 --- a/internal/services/groups/groups_data_source_test.go +++ b/internal/services/groups/groups_data_source_test.go @@ -56,6 +56,20 @@ func TestAccGroupsDataSource_noNames(t *testing.T) { }) } +func TestAccGroupsDataSource_returnAll(t *testing.T) { + data := acceptance.BuildTestData(t, "data.azuread_groups", "test") + + data.DataSourceTest(t, []resource.TestStep{ + { + Config: GroupsDataSource{}.returnAll(), + Check: resource.ComposeTestCheckFunc( + check.That(data.ResourceName).Key("display_names.#").Exists(), + check.That(data.ResourceName).Key("object_ids.#").Exists(), + ), + }, + }) +} + func (GroupsDataSource) template(data acceptance.TestData) string { return fmt.Sprintf(` resource "azuread_group" "testA" { @@ -99,3 +113,11 @@ data "azuread_groups" "test" { } ` } + +func (GroupsDataSource) returnAll() string { + return ` +data "azuread_groups" "test" { + return_all = true +} +` +}