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: azurerm_azuread_application #1269

Merged
merged 5 commits into from
Jul 11, 2018
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
8 changes: 8 additions & 0 deletions azurerm/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,7 @@ type ArmClient struct {
// Authentication
roleAssignmentsClient authorization.RoleAssignmentsClient
roleDefinitionsClient authorization.RoleDefinitionsClient
applicationsClient graphrbac.ApplicationsClient
servicePrincipalsClient graphrbac.ServicePrincipalsClient

// CDN
Expand Down Expand Up @@ -462,6 +463,13 @@ func (c *ArmClient) registerAuthentication(endpoint, graphEndpoint, subscription
definitionsClient.SkipResourceProviderRegistration = c.skipProviderRegistration
c.roleDefinitionsClient = definitionsClient

applicationsClient := graphrbac.NewApplicationsClientWithBaseURI(graphEndpoint, tenantId)
setUserAgent(&applicationsClient.Client)
applicationsClient.Authorizer = graphAuth
applicationsClient.Sender = sender
applicationsClient.SkipResourceProviderRegistration = c.skipProviderRegistration
c.applicationsClient = applicationsClient

servicePrincipalsClient := graphrbac.NewServicePrincipalsClientWithBaseURI(graphEndpoint, tenantId)
setUserAgent(&servicePrincipalsClient.Client)
servicePrincipalsClient.Authorizer = graphAuth
Expand Down
54 changes: 54 additions & 0 deletions azurerm/import_arm_azuread_application_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
package azurerm

import (
"testing"

"github.com/google/uuid"
"github.com/hashicorp/terraform/helper/resource"
)

func TestAccAzureRMActiveDirectoryApplication_importBasic(t *testing.T) {
resourceName := "azurerm_azuread_application.test"

id := uuid.New().String()
config := testAccAzureRMActiveDirectoryApplication_basic(id)

resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testCheckAzureRMActiveDirectoryApplicationDestroy,
Steps: []resource.TestStep{
{
Config: config,
},
{
ResourceName: resourceName,
ImportState: true,
ImportStateVerify: true,
},
},
})
}

func TestAccAzureRMActiveDirectoryApplication_importComplete(t *testing.T) {
resourceName := "azurerm_azuread_application.test"

id := uuid.New().String()
config := testAccAzureRMActiveDirectoryApplication_complete(id)

resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testCheckAzureRMActiveDirectoryApplicationDestroy,
Steps: []resource.TestStep{
{
Config: config,
},
{
ResourceName: resourceName,
ImportState: true,
ImportStateVerify: true,
},
},
})
}
1 change: 1 addition & 0 deletions azurerm/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,7 @@ func Provider() terraform.ResourceProvider {
},

ResourcesMap: map[string]*schema.Resource{
"azurerm_azuread_application": resourceArmActiveDirectoryApplication(),
"azurerm_application_gateway": resourceArmApplicationGateway(),
"azurerm_application_insights": resourceArmApplicationInsights(),
"azurerm_application_security_group": resourceArmApplicationSecurityGroup(),
Expand Down
255 changes: 255 additions & 0 deletions azurerm/resource_arm_azuread_application.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,255 @@
package azurerm

import (
"fmt"
"log"

"github.com/Azure/azure-sdk-for-go/services/graphrbac/1.6/graphrbac"
"github.com/hashicorp/terraform/helper/schema"
"github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils"
)

func resourceArmActiveDirectoryApplication() *schema.Resource {
return &schema.Resource{
Create: resourceArmActiveDirectoryApplicationCreate,
Read: resourceArmActiveDirectoryApplicationRead,
Update: resourceArmActiveDirectoryApplicationUpdate,
Delete: resourceArmActiveDirectoryApplicationDelete,
Importer: &schema.ResourceImporter{
State: schema.ImportStatePassthrough,
},

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

"homepage": {
Type: schema.TypeString,
Optional: true,
Computed: true,
},

"identifier_uris": {
Type: schema.TypeList,
Optional: true,
Computed: true,
MinItems: 1,
Elem: &schema.Schema{
Type: schema.TypeString,
},
},

"reply_urls": {
Type: schema.TypeList,
Optional: true,
Computed: true,
Elem: &schema.Schema{
Type: schema.TypeString,
},
},

"available_to_other_tenants": {
Type: schema.TypeBool,
Optional: true,
},

"oauth2_allow_implicit_flow": {
Type: schema.TypeBool,
Optional: true,
},

"application_id": {
Type: schema.TypeString,
Computed: true,
},
},
}
}

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

name := d.Get("name").(string)
availableToOtherTenants := d.Get("available_to_other_tenants").(bool)

properties := graphrbac.ApplicationCreateParameters{
DisplayName: &name,
Homepage: expandAzureRmActiveDirectoryApplicationHomepage(d, name),
IdentifierUris: expandAzureRmActiveDirectoryApplicationIdentifierUris(d),
ReplyUrls: expandAzureRmActiveDirectoryApplicationReplyUrls(d),
AvailableToOtherTenants: utils.Bool(availableToOtherTenants),
}

if v, ok := d.GetOk("oauth2_allow_implicit_flow"); ok {
properties.Oauth2AllowImplicitFlow = utils.Bool(v.(bool))
}

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

d.SetId(*app.ObjectID)

return resourceArmActiveDirectoryApplicationRead(d, meta)
}

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

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

var properties graphrbac.ApplicationUpdateParameters

if d.HasChange("name") {
properties.DisplayName = &name
}

if d.HasChange("homepage") {
properties.Homepage = expandAzureRmActiveDirectoryApplicationHomepage(d, name)
}

if d.HasChange("identifier_uris") {
properties.IdentifierUris = expandAzureRmActiveDirectoryApplicationIdentifierUris(d)
}

if d.HasChange("reply_urls") {
properties.ReplyUrls = expandAzureRmActiveDirectoryApplicationReplyUrls(d)
}

if d.HasChange("available_to_other_tenants") {
availableToOtherTenants := d.Get("available_to_other_tenants").(bool)
properties.AvailableToOtherTenants = utils.Bool(availableToOtherTenants)
}

if d.HasChange("oauth2_allow_implicit_flow") {
oauth := d.Get("oauth2_allow_implicit_flow").(bool)
properties.Oauth2AllowImplicitFlow = utils.Bool(oauth)
}

_, err := client.Patch(ctx, d.Id(), properties)
if err != nil {
return fmt.Errorf("Error patching Azure AD Application with ID %q: %+v", d.Id(), err)
}

return resourceArmActiveDirectoryApplicationRead(d, meta)
}

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

resp, err := client.Get(ctx, d.Id())
if err != nil {
if utils.ResponseWasNotFound(resp.Response) {
log.Printf("[DEBUG] Azure AD Application with ID %q was not found - removing from state", d.Id())
d.SetId("")
return nil
}

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

d.Set("name", resp.DisplayName)
d.Set("application_id", resp.AppID)
d.Set("homepage", resp.Homepage)
d.Set("available_to_other_tenants", resp.AvailableToOtherTenants)
d.Set("oauth2_allow_implicit_flow", resp.Oauth2AllowImplicitFlow)

identifierUris := flattenAzureADApplicationIdentifierUris(resp.IdentifierUris)
if err := d.Set("identifier_uris", identifierUris); err != nil {
return fmt.Errorf("Error setting`identifier_uris`: %+v", err)
}

replyUrls := flattenAzureADApplicationReplyUrls(resp.ReplyUrls)
if err := d.Set("reply_urls", replyUrls); err != nil {
return fmt.Errorf("Error setting`reply_urls`: %+v", err)
}

return nil
}

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

// in order to delete an application which is available to other tenants, we first have to disable this setting
availableToOtherTenants := d.Get("available_to_other_tenants").(bool)
if availableToOtherTenants {
log.Printf("[DEBUG] Azure AD Application is available to other tenants - disabling that feature before deleting.")
properties := graphrbac.ApplicationUpdateParameters{
AvailableToOtherTenants: utils.Bool(false),
}
_, err := client.Patch(ctx, d.Id(), properties)
if err != nil {
return fmt.Errorf("Error patching Azure AD Application with ID %q: %+v", d.Id(), err)
}
}

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

return nil
}

func expandAzureRmActiveDirectoryApplicationHomepage(d *schema.ResourceData, name string) *string {
if v, ok := d.GetOk("homepage"); ok {
return utils.String(v.(string))
}

return utils.String(fmt.Sprintf("http://%s", name))
}

func expandAzureRmActiveDirectoryApplicationIdentifierUris(d *schema.ResourceData) *[]string {
identifierUris := d.Get("identifier_uris").([]interface{})
identifiers := make([]string, 0)

for _, id := range identifierUris {
identifiers = append(identifiers, id.(string))
}

return &identifiers
}

func expandAzureRmActiveDirectoryApplicationReplyUrls(d *schema.ResourceData) *[]string {
replyUrls := d.Get("reply_urls").([]interface{})
urls := make([]string, 0)

for _, url := range replyUrls {
urls = append(urls, url.(string))
}

return &urls
}

func flattenAzureADApplicationIdentifierUris(input *[]string) []string {
output := make([]string, 0)

if input != nil {
for _, v := range *input {
output = append(output, v)
}
}

return output
}

func flattenAzureADApplicationReplyUrls(input *[]string) []string {
output := make([]string, 0)

if input != nil {
for _, v := range *input {
output = append(output, v)
}
}

return output
}
Loading