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

New resource & data source 'azuread_group' #14

Merged
merged 9 commits into from
Jan 22, 2019
Merged
4 changes: 4 additions & 0 deletions azuread/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ type ArmClient struct {

// azure AD clients
applicationsClient graphrbac.ApplicationsClient
groupsClient graphrbac.GroupsClient
servicePrincipalsClient graphrbac.ServicePrincipalsClient
}

Expand Down Expand Up @@ -73,6 +74,9 @@ func (c *ArmClient) registerGraphRBACClients(endpoint, tenantID string, authoriz
c.applicationsClient = graphrbac.NewApplicationsClientWithBaseURI(endpoint, tenantID)
configureClient(&c.applicationsClient.Client, authorizer)

c.groupsClient = graphrbac.NewGroupsClientWithBaseURI(endpoint, tenantID)
configureClient(&c.groupsClient.Client, authorizer)

c.servicePrincipalsClient = graphrbac.NewServicePrincipalsClientWithBaseURI(endpoint, tenantID)
configureClient(&c.servicePrincipalsClient.Client, authorizer)
}
Expand Down
98 changes: 98 additions & 0 deletions azuread/data_source_group.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
package azuread

import (
"fmt"
"log"
"strings"

"github.com/Azure/azure-sdk-for-go/services/graphrbac/1.6/graphrbac"
"github.com/hashicorp/terraform/helper/schema"
"github.com/terraform-providers/terraform-provider-azuread/azuread/helpers/ar"
"github.com/terraform-providers/terraform-provider-azuread/azuread/helpers/validate"
)

func dataGroup() *schema.Resource {
return &schema.Resource{
Read: dataSourceActiveDirectoryGroupRead,
Importer: &schema.ResourceImporter{
State: schema.ImportStatePassthrough,
},

Schema: map[string]*schema.Schema{
"name": {
Type: schema.TypeString,
Optional: true,
Computed: true,
ConflictsWith: []string{"object_id"},
ValidateFunc: validate.NoEmptyStrings,
},

"object_id": {
Type: schema.TypeString,
Optional: true,
Computed: true,
ConflictsWith: []string{"name"},
ValidateFunc: validate.UUID,
},
},
}
}

func dataSourceActiveDirectoryGroupRead(d *schema.ResourceData, meta interface{}) error {
client := meta.(*ArmClient).groupsClient
ctx := meta.(*ArmClient).StopContext

var adgroup graphrbac.ADGroup
var groupObj *graphrbac.ADGroup

if oId, ok := d.GetOk("object_id"); ok {
// use the object_id to find the Azure AD group

objectId := oId.(string)
resp, err := client.Get(ctx, objectId)
if err != nil {
if ar.ResponseWasNotFound(resp.Response) {
return fmt.Errorf("Error: AzureAD Group with ID %q was not found", objectId)
}

return fmt.Errorf("Error making Read request on AzureAD Group with ID %q: %+v", objectId, err)
}

adgroup = resp

} else {

// use the name to find the Azure AD group
name := d.Get("name").(string)
filter := fmt.Sprintf("displayName eq '%s'", name)
log.Printf("[DEBUG] [data_source_azuread_group] Using filter %q", filter)
tiwood marked this conversation as resolved.
Show resolved Hide resolved

resp, err := client.ListComplete(ctx, filter)
if err != nil {
return fmt.Errorf("Error listing Azure AD groups: %+v", err)
}

for _, v := range *resp.Response().Value {
if v.DisplayName != nil {
tiwood marked this conversation as resolved.
Show resolved Hide resolved
if strings.EqualFold(*v.DisplayName, name) {
tiwood marked this conversation as resolved.
Show resolved Hide resolved
log.Printf("[DEBUG] [data_source_azuread_group] %q (API result) matches %q (given value). The group has the objectId: %q", *v.DisplayName, name, *v.ObjectID)
tiwood marked this conversation as resolved.
Show resolved Hide resolved
groupObj = &v
break
} else {
log.Printf("[DEBUG] [data_source_azuread_group] %q (API result) does not match %q (given value)", *v.DisplayName, name)
tiwood marked this conversation as resolved.
Show resolved Hide resolved
}
}
}
if groupObj == nil {
return fmt.Errorf("Couldn't locate a Azure AD group with a name of %q", name)
}

adgroup = *groupObj
}

d.SetId(*adgroup.ObjectID)
d.Set("object_id", adgroup.ObjectID)
d.Set("name", adgroup.DisplayName)

return nil
}
85 changes: 85 additions & 0 deletions azuread/data_source_group_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
package azuread

import (
"fmt"
"testing"

"github.com/hashicorp/go-uuid"
"github.com/hashicorp/terraform/helper/resource"
)

func TestAccDataSourceAzureADGroup_byObjectId(t *testing.T) {
dataSourceName := "data.azuread_group.test"
id, err := uuid.GenerateUUID()
if err != nil {
t.Fatal(err)
}
config := testAccDataSourceAzureADGroup_objectId(id)

resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testCheckAzureADGroupDestroy,
Steps: []resource.TestStep{
{
Config: testAccAzureADGroup(id),
},
{
Config: config,
Check: resource.ComposeTestCheckFunc(
testCheckAzureADGroupExists(dataSourceName),
resource.TestCheckResourceAttr(dataSourceName, "name", fmt.Sprintf("acctest%s", id)),
),
},
},
})
}

func TestAccDataSourceAzureADGroup_byName(t *testing.T) {
dataSourceName := "data.azuread_group.test"
id, err := uuid.GenerateUUID()
if err != nil {
t.Fatal(err)
}
config := testAccDataSourceAzureADGroup_name(id)

resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testCheckAzureADGroupDestroy,
Steps: []resource.TestStep{
{
Config: testAccAzureADGroup(id),
},
{
Config: config,
Check: resource.ComposeTestCheckFunc(
testCheckAzureADGroupExists(dataSourceName),
resource.TestCheckResourceAttr(dataSourceName, "name", fmt.Sprintf("acctest%s", id)),
),
},
},
})
}

func testAccDataSourceAzureADGroup_objectId(id string) string {
template := testAccAzureADGroup(id)
return fmt.Sprintf(`
%s

data "azuread_group" "test" {
object_id = "${azuread_group.test.id}"
}
`, template)
}

func testAccDataSourceAzureADGroup_name(id string) string {
template := testAccAzureADGroup(id)
return fmt.Sprintf(`
%s

data "azuread_group" "test" {
name = "${azuread_group.test.name}"
}
`, template)
}
2 changes: 2 additions & 0 deletions azuread/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -75,11 +75,13 @@ func Provider() terraform.ResourceProvider {

DataSourcesMap: map[string]*schema.Resource{
"azuread_application": dataApplication(),
"azuread_group": dataGroup(),
"azuread_service_principal": dataServicePrincipal(),
},

ResourcesMap: map[string]*schema.Resource{
"azuread_application": resourceApplication(),
"azuread_group": resourceGroup(),
"azuread_service_principal": resourceServicePrincipal(),
"azuread_service_principal_password": resourceServicePrincipalPassword(),
},
Expand Down
88 changes: 88 additions & 0 deletions azuread/resource_group.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
package azuread

import (
"fmt"
"log"

"github.com/Azure/azure-sdk-for-go/services/graphrbac/1.6/graphrbac"
"github.com/hashicorp/terraform/helper/schema"
"github.com/hashicorp/terraform/helper/validation"
"github.com/terraform-providers/terraform-provider-azuread/azuread/helpers/ar"
"github.com/terraform-providers/terraform-provider-azuread/azuread/helpers/p"
)

func resourceGroup() *schema.Resource {
return &schema.Resource{
Create: resourceGroupCreate,
Read: resourceGroupRead,
Delete: resourceGroupDelete,
Importer: &schema.ResourceImporter{
State: schema.ImportStatePassthrough,
},

Schema: map[string]*schema.Schema{
"name": {
Type: schema.TypeString,
Required: true,
ForceNew: true,
ValidateFunc: validation.NoZeroValues,
},
},
}
}

func resourceGroupCreate(d *schema.ResourceData, meta interface{}) error {
client := meta.(*ArmClient).groupsClient
ctx := meta.(*ArmClient).StopContext

name := d.Get("name").(string)

properties := graphrbac.GroupCreateParameters{
DisplayName: &name,
MailEnabled: p.Bool(false), //we're defaulting to false, as the API currently only supports the creation of non-mail enabled security groups.
MailNickname: &name,
SecurityEnabled: p.Bool(true), //we're defaulting to true, as the API currently only supports the creation of non-mail enabled security groups.
}

group, err := client.Create(ctx, properties)
if err != nil {
return err
}

d.SetId(*group.ObjectID)

return resourceGroupRead(d, meta)
}

func resourceGroupRead(d *schema.ResourceData, meta interface{}) error {
client := meta.(*ArmClient).groupsClient
ctx := meta.(*ArmClient).StopContext

resp, err := client.Get(ctx, d.Id())
if err != nil {
if ar.ResponseWasNotFound(resp.Response) {
log.Printf("[DEBUG] [resource_azuread_group] Azure AD group with id %q was not found - removing from state", d.Id())
tiwood marked this conversation as resolved.
Show resolved Hide resolved
d.SetId("")
return nil
}

return fmt.Errorf("Error retrieving Azure AD Group with ID %q: %+v", d.Id(), err)
}

d.Set("name", resp.DisplayName)

return nil
}

func resourceGroupDelete(d *schema.ResourceData, meta interface{}) error {
client := meta.(*ArmClient).groupsClient
ctx := meta.(*ArmClient).StopContext

if resp, err := client.Delete(ctx, d.Id()); err != nil {
if !ar.ResponseWasNotFound(resp) {
return fmt.Errorf("Error Deleting Azure AD Group with ID %q: %+v", d.Id(), err)
}
}

return nil
}
Loading