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

azuread_group: add mail_enabled and security_enabled attributes #393

Merged
merged 2 commits into from
Feb 8, 2021
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.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 12 additions & 8 deletions docs/data-sources/group.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,26 +12,30 @@ Gets information about an Azure Active Directory group.

```hcl
data "azuread_group" "example" {
display_name = "A-AD-Group"
display_name = "MyGroupName"
security_enabled = true
}
```

## Argument Reference

The following arguments are supported:

* `display_name` - (Optional) The splay name of the Group within Azure Active Directory.
* `object_id` - (Optional) Specifies the Object ID of the Group within Azure Active Directory.
* `display_name` - (Optional) The display name for the Group.
* `mail_enabled` - (Optional) Whether the group is mail-enabled.
* `object_id` - (Optional) Specifies the Object ID of the Group.
* `security_enabled` - (Optional) Whether the group is a security group.

~> **NOTE:** One of `display_name` or `object_id` must be specified.

## Attributes Reference

The following attributes are exported:

* `description` - The description of the AD Group.
* `display_name` - The name of the Azure AD Group.
* `description` - The optional description of the Group.
* `display_name` - The display name for the Group.
* `id` - The Object ID of the Azure AD Group.
* `members` - The Object IDs of the Azure AD Group members.
* `owners` - The Object IDs of the Azure AD Group owners.

* `mail_enabled` - Whether the group is mail-enabled.
* `members` - The Object IDs of the Group members.
* `owners` - The Object IDs of the Group owners.
* `security_enabled` - Whether the group is a security group.
4 changes: 4 additions & 0 deletions docs/resources/group.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,11 @@ The following arguments are supported:

In addition to all arguments above, the following attributes are exported:

* `mail_enabled` - Whether the group is mail-enabled.
* `object_id` - The Object ID of the Group.
* `security_enabled` - Whether the group is a security group.

~> **NOTE:** Due to API limitations, this resource only supports the creation of security-only groups.

## Import

Expand Down
10 changes: 9 additions & 1 deletion internal/helpers/aadgraph/group.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,17 @@ import (
"github.com/terraform-providers/terraform-provider-azuread/internal/utils"
)

func GroupGetByDisplayName(ctx context.Context, client *graphrbac.GroupsClient, displayName string) (*graphrbac.ADGroup, error) {
func GroupGetByDisplayName(ctx context.Context, client *graphrbac.GroupsClient, displayName string, mailEnabled *bool, securityEnabled *bool) (*graphrbac.ADGroup, error) {
filter := fmt.Sprintf("displayName eq '%s'", displayName)

if mailEnabled != nil {
filter = fmt.Sprintf("%s and mailEnabled eq %t", filter, *mailEnabled)
}

if securityEnabled != nil {
filter = fmt.Sprintf("%s and securityEnabled eq %t", filter, *securityEnabled)
}

resp, err := client.ListComplete(ctx, filter)
if err != nil {
return nil, fmt.Errorf("listing Groups for filter %q: %+v", filter, err)
Expand Down
55 changes: 53 additions & 2 deletions internal/services/groups/group_data_source.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ package groups
import (
"context"
"errors"
"fmt"
"strings"

"github.com/Azure/azure-sdk-for-go/services/graphrbac/1.6/graphrbac"
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
Expand Down Expand Up @@ -54,6 +56,18 @@ func groupDataSource() *schema.Resource {
ValidateDiagFunc: validate.NoEmptyStrings,
},

"mail_enabled": {
Type: schema.TypeBool,
Optional: true,
Computed: true,
},

"security_enabled": {
Type: schema.TypeBool,
Optional: true,
Computed: true,
},

"members": {
Type: schema.TypeList,
Computed: true,
Expand Down Expand Up @@ -81,6 +95,14 @@ func groupDataSourceRead(ctx context.Context, d *schema.ResourceData, meta inter
name = v.(string)
}

var mailEnabled, securityEnabled *bool
if v, exists := d.GetOkExists("mail_enabled"); exists { //nolint:SA1019
mailEnabled = utils.Bool(v.(bool))
}
if v, exists := d.GetOkExists("security_enabled"); exists { //nolint:SA1019
securityEnabled = utils.Bool(v.(bool))
}

if objectId, ok := d.Get("object_id").(string); ok && objectId != "" {
resp, err := client.Get(ctx, objectId)
if err != nil {
Expand All @@ -91,11 +113,38 @@ func groupDataSourceRead(ctx context.Context, d *schema.ResourceData, meta inter
return tf.ErrorDiagF(err, "Retrieving group with object ID: %q", objectId)
}

if mailEnabled != nil && (resp.MailEnabled == nil || *resp.MailEnabled != *mailEnabled) {
var actual string
if resp.MailEnabled == nil {
actual = "nil"
} else {
actual = fmt.Sprintf("%t", *resp.MailEnabled)
}
return tf.ErrorDiagPathF(nil, "mail_enabled", "Group with object ID %q does not have the specified mail_enabled setting (expected: %t, actual: %s)", objectId, *mailEnabled, actual)
}

if securityEnabled != nil && (resp.SecurityEnabled == nil || *resp.SecurityEnabled != *securityEnabled) {
var actual string
if resp.SecurityEnabled == nil {
actual = "nil"
} else {
actual = fmt.Sprintf("%t", *resp.SecurityEnabled)
}
return tf.ErrorDiagPathF(nil, "security_enabled", "Group with object ID %q does not have the specified security_enabled setting (expected: %t, actual: %s)", objectId, *securityEnabled, actual)
}

group = resp
} else if name != "" {
g, err := aadgraph.GroupGetByDisplayName(ctx, client, name)
g, err := aadgraph.GroupGetByDisplayName(ctx, client, name, mailEnabled, securityEnabled)
if err != nil {
return tf.ErrorDiagPathF(err, "name", "No group found with display name: %q", name)
params := []string{fmt.Sprintf("display_name: %q", name)}
if mailEnabled != nil {
params = append(params, fmt.Sprintf("mail_enabled: %t", *mailEnabled))
}
if securityEnabled != nil {
params = append(params, fmt.Sprintf("security_enabled: %t", *securityEnabled))
}
return tf.ErrorDiagPathF(err, "name", "No group found matching specified parameters (%s)", strings.Join(params, ", "))
}
group = *g
}
Expand All @@ -109,6 +158,8 @@ func groupDataSourceRead(ctx context.Context, d *schema.ResourceData, meta inter
tf.Set(d, "object_id", group.ObjectID)
tf.Set(d, "display_name", group.DisplayName)
tf.Set(d, "name", group.DisplayName)
tf.Set(d, "mail_enabled", group.MailEnabled)
tf.Set(d, "security_enabled", group.SecurityEnabled)

description := ""
if v, ok := group.AdditionalProperties["description"]; ok {
Expand Down
49 changes: 49 additions & 0 deletions internal/services/groups/group_data_source_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,18 @@ func TestAccGroupDataSource_byName(t *testing.T) {
},
})
}
func TestAccGroupDataSource_byNameWithSecurity(t *testing.T) {
data := acceptance.BuildTestData(t, "data.azuread_group", "test")

data.DataSourceTest(t, []resource.TestStep{
{
Config: GroupDataSource{}.nameSecurity(data),
Check: resource.ComposeTestCheckFunc(
check.That(data.ResourceName).Key("name").HasValue(fmt.Sprintf("acctestGroup-%d", data.RandomInteger)),
),
},
})
}

func TestAccGroupDataSource_byNameDeprecated(t *testing.T) {
data := acceptance.BuildTestData(t, "data.azuread_group", "test")
Expand Down Expand Up @@ -64,6 +76,19 @@ func TestAccGroupDataSource_byObjectId(t *testing.T) {
})
}

func TestAccGroupDataSource_byObjectIdWithSecurity(t *testing.T) {
data := acceptance.BuildTestData(t, "data.azuread_group", "test")

data.DataSourceTest(t, []resource.TestStep{
{
Config: GroupDataSource{}.objectIdSecurity(data),
Check: resource.ComposeTestCheckFunc(
check.That(data.ResourceName).Key("name").HasValue(fmt.Sprintf("acctestGroup-%d", data.RandomInteger)),
),
},
})
}

func TestAccGroupDataSource_members(t *testing.T) {
data := acceptance.BuildTestData(t, "data.azuread_group", "test")

Expand Down Expand Up @@ -112,6 +137,18 @@ data "azuread_group" "test" {
`, GroupResource{}.basic(data))
}

func (GroupDataSource) nameSecurity(data acceptance.TestData) string {
return fmt.Sprintf(`
%[1]s

data "azuread_group" "test" {
display_name = azuread_group.test.name
mail_enabled = false
security_enabled = true
}
`, GroupResource{}.basic(data))
}

func (GroupDataSource) caseInsensitiveName(data acceptance.TestData) string {
return fmt.Sprintf(`
%[1]s
Expand All @@ -131,6 +168,18 @@ data "azuread_group" "test" {
`, GroupResource{}.basic(data))
}

func (GroupDataSource) objectIdSecurity(data acceptance.TestData) string {
return fmt.Sprintf(`
%[1]s

data "azuread_group" "test" {
object_id = azuread_group.test.object_id
mail_enabled = false
security_enabled = true
}
`, GroupResource{}.basic(data))
}

func (GroupDataSource) members(data acceptance.TestData) string {
return fmt.Sprintf(`
%[1]s
Expand Down
13 changes: 13 additions & 0 deletions internal/services/groups/group_resource.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,11 @@ func groupResource() *schema.Resource {
Optional: true,
},

"mail_enabled": {
Type: schema.TypeBool,
Computed: true,
},

"members": {
Type: schema.TypeSet,
Optional: true,
Expand All @@ -84,11 +89,17 @@ func groupResource() *schema.Resource {
Type: schema.TypeString,
Computed: true,
},

"prevent_duplicate_names": {
Type: schema.TypeBool,
Optional: true,
Default: false,
},

"security_enabled": {
Type: schema.TypeBool,
Computed: true,
},
},
}
}
Expand Down Expand Up @@ -196,6 +207,8 @@ func groupResourceRead(ctx context.Context, d *schema.ResourceData, meta interfa
tf.Set(d, "object_id", resp.ObjectID)
tf.Set(d, "display_name", resp.DisplayName)
tf.Set(d, "name", resp.DisplayName)
tf.Set(d, "mail_enabled", resp.MailEnabled)
tf.Set(d, "security_enabled", resp.SecurityEnabled)

description := ""
if v, ok := resp.AdditionalProperties["description"]; ok {
Expand Down
2 changes: 1 addition & 1 deletion internal/services/groups/groups_data_source.go
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ func groupsDataSourceRead(ctx context.Context, d *schema.ResourceData, meta inte
if len(names) > 0 {
expectedCount = len(names)
for _, name := range names {
g, err := aadgraph.GroupGetByDisplayName(ctx, client, name.(string))
g, err := aadgraph.GroupGetByDisplayName(ctx, client, name.(string), nil, nil)
if err != nil {
return tf.ErrorDiagPathF(err, "name", "No group found with display name: %q", name)
}
Expand Down