From 90c1f9c5bd5e93400d2f9a6a0d9c10149253dec8 Mon Sep 17 00:00:00 2001 From: kt Date: Thu, 24 Jan 2019 00:37:44 -0800 Subject: [PATCH 1/2] azuread_service_principal: add tags property --- azuread/data_application.go | 2 -- azuread/resource_service_principal.go | 40 ++++++++++++++++++--- azuread/resource_service_principal_test.go | 42 ++++++++++++++++++++-- 3 files changed, 76 insertions(+), 8 deletions(-) diff --git a/azuread/data_application.go b/azuread/data_application.go index 5e8c0026b..7cd80d9cc 100644 --- a/azuread/data_application.go +++ b/azuread/data_application.go @@ -100,7 +100,6 @@ func dataApplicationRead(d *schema.ResourceData, meta interface{}) error { filter := fmt.Sprintf("displayName eq '%s'", name) resp, err := client.ListComplete(ctx, filter) - if err != nil { return fmt.Errorf("Error listing Azure AD Applications: %+v", err) } @@ -118,7 +117,6 @@ func dataApplicationRead(d *schema.ResourceData, meta interface{}) error { if app == nil { return fmt.Errorf("Couldn't locate an Azure AD Application with a name of %q", name) } - application = *app } diff --git a/azuread/resource_service_principal.go b/azuread/resource_service_principal.go index 299d80fd7..a1c2cbe48 100644 --- a/azuread/resource_service_principal.go +++ b/azuread/resource_service_principal.go @@ -4,6 +4,8 @@ import ( "fmt" "log" + "github.com/terraform-providers/terraform-provider-azuread/azuread/helpers/tf" + "github.com/terraform-providers/terraform-provider-azuread/azuread/helpers/validate" "github.com/hashicorp/go-azure-helpers/response" @@ -33,6 +35,16 @@ func resourceServicePrincipal() *schema.Resource { ValidateFunc: validate.UUID, }, + "tags": { + Type: schema.TypeSet, + Optional: true, + Set: schema.HashString, + ForceNew: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "display_name": { Type: schema.TypeString, Computed: true, @@ -53,18 +65,28 @@ func resourceServicePrincipalCreate(d *schema.ResourceData, meta interface{}) er // given there's no way to change it - we'll just default this to true AccountEnabled: p.Bool(true), } + if v, ok := d.GetOk("tags"); ok { + properties.Tags = tf.ExpandStringArrayPtr(v.(*schema.Set).List()) + } - app, err := client.Create(ctx, properties) + sp, err := client.Create(ctx, properties) if err != nil { - return fmt.Errorf("Error creating Service Principal %q: %+v", applicationId, err) + return fmt.Errorf("Error creating Service Principal for application %q: %+v", applicationId, err) + } + + if sp.ObjectID == nil { + return fmt.Errorf("Create returned a nil object id for application %q", applicationId) } + objectId := *sp.ObjectID - objectId := *app.ObjectID resp, err := client.Get(ctx, objectId) if err != nil { - return fmt.Errorf("Error retrieving Service Principal ID %q: %+v", objectId, err) + return fmt.Errorf("Error retrieving Service Principal with ID %q: %+v", objectId, err) } + if resp.ObjectID == nil { + return fmt.Errorf("Get returned a nil object ID for %q", objectId) + } d.SetId(*resp.ObjectID) return resourceServicePrincipalRead(d, meta) @@ -75,6 +97,7 @@ func resourceServicePrincipalRead(d *schema.ResourceData, meta interface{}) erro ctx := meta.(*ArmClient).StopContext objectId := d.Id() + app, err := client.Get(ctx, objectId) if err != nil { if ar.ResponseWasNotFound(app.Response) { @@ -88,6 +111,15 @@ func resourceServicePrincipalRead(d *schema.ResourceData, meta interface{}) erro d.Set("application_id", app.AppID) d.Set("display_name", app.DisplayName) + // tags doesn't exist as a property, so extract it + if iTags, ok := app.AdditionalProperties["tags"]; ok { + if tags, ok := iTags.([]interface{}); ok { + if err := d.Set("tags", tf.ExpandStringArrayPtr(tags)); err != nil { + return fmt.Errorf("Error setting `tags`: %+v", err) + } + } + } + return nil } diff --git a/azuread/resource_service_principal_test.go b/azuread/resource_service_principal_test.go index febaebdf9..18e31db61 100644 --- a/azuread/resource_service_principal_test.go +++ b/azuread/resource_service_principal_test.go @@ -14,7 +14,6 @@ import ( func TestAccAzureADServicePrincipal_basic(t *testing.T) { resourceName := "azuread_service_principal.test" id := uuid.New().String() - config := testAccADServicePrincipal_basic(id) resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, @@ -22,7 +21,7 @@ func TestAccAzureADServicePrincipal_basic(t *testing.T) { CheckDestroy: testCheckADServicePrincipalDestroy, Steps: []resource.TestStep{ { - Config: config, + Config: testAccADServicePrincipal_basic(id), Check: resource.ComposeTestCheckFunc( testCheckADServicePrincipalExists(resourceName), resource.TestCheckResourceAttrSet(resourceName, "display_name"), @@ -38,6 +37,31 @@ func TestAccAzureADServicePrincipal_basic(t *testing.T) { }) } +func TestAccAzureADServicePrincipal_complete(t *testing.T) { + resourceName := "azuread_service_principal.test" + id := uuid.New().String() + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckADServicePrincipalDestroy, + Steps: []resource.TestStep{ + { + Config: testAccADServicePrincipal_complete(id), + Check: resource.ComposeTestCheckFunc( + testCheckADServicePrincipalExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "tags.#", "3"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + func testCheckADServicePrincipalExists(name string) resource.TestCheckFunc { return func(s *terraform.State) error { rs, ok := s.RootModule().Resources[name] @@ -95,3 +119,17 @@ resource "azuread_service_principal" "test" { } `, id) } + +func testAccADServicePrincipal_complete(id string) string { + return fmt.Sprintf(` +resource "azuread_application" "test" { + name = "acctestspa%s" +} + +resource "azuread_service_principal" "test" { + application_id = "${azuread_application.test.application_id}" + + tags = ["test", "multiple", "CapitalS"] +} +`, id) +} From 3fd18aacd0b31a876a812714bf3f7d4b374033e1 Mon Sep 17 00:00:00 2001 From: kt Date: Thu, 24 Jan 2019 17:37:31 -0800 Subject: [PATCH 2/2] added documentation --- website/docs/r/service_principal.html.markdown | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/website/docs/r/service_principal.html.markdown b/website/docs/r/service_principal.html.markdown index 3f70dd33c..f1f08e21f 100644 --- a/website/docs/r/service_principal.html.markdown +++ b/website/docs/r/service_principal.html.markdown @@ -27,6 +27,8 @@ resource "azuread_application" "test" { resource "azuread_service_principal" "test" { application_id = "${azuread_application.test.application_id}" + + tags = ["example", "tags", "here"] } ``` @@ -36,6 +38,8 @@ The following arguments are supported: * `application_id` - (Required) The ID of the Azure AD Application for which to create a Service Principal. +* `tags` - (Optional) A list of tags to apply to the Service Principal. + ## Attributes Reference The following attributes are exported: