Skip to content

Commit

Permalink
Allow Disabling Service Accounts (#5169) (#10033)
Browse files Browse the repository at this point in the history
* allow disabling service accounts

Co-authored-by: upodroid <cy@borg.dev>

* fix typos

* revert warning change

Signed-off-by: Modular Magician <magic-modules@google.com>
  • Loading branch information
modular-magician authored Sep 8, 2021
1 parent f860da3 commit 7065d34
Show file tree
Hide file tree
Showing 4 changed files with 110 additions and 0 deletions.
3 changes: 3 additions & 0 deletions .changelog/5169.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
```release-note:enhancement
iam: added `disabled` field to `google_service_account` resource
```
34 changes: 34 additions & 0 deletions google/resource_google_service_account.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,12 @@ func resourceGoogleServiceAccount() *schema.Resource {
Optional: true,
Description: `The display name for the service account. Can be updated without creating a new resource.`,
},
"disabled": {
Type: schema.TypeBool,
Optional: true,
Default: false,
Description: `Whether the service account is disabled. Defaults to false`,
},
"description": {
Type: schema.TypeString,
Optional: true,
Expand Down Expand Up @@ -146,6 +152,9 @@ func resourceGoogleServiceAccountRead(d *schema.ResourceData, meta interface{})
if err := d.Set("description", sa.Description); err != nil {
return fmt.Errorf("Error setting description: %s", err)
}
if err := d.Set("disabled", sa.Disabled); err != nil {
return fmt.Errorf("Error setting disabled: %s", err)
}
return nil
}

Expand Down Expand Up @@ -181,6 +190,31 @@ func resourceGoogleServiceAccountUpdate(d *schema.ResourceData, meta interface{}
if d.HasChange("display_name") {
updateMask = append(updateMask, "display_name")
}

// We want to skip the Patch Call below if only the disabled field has been changed
if d.HasChange("disabled") && !d.Get("disabled").(bool) {
_, err = config.NewIamClient(userAgent).Projects.ServiceAccounts.Enable(d.Id(),
&iam.EnableServiceAccountRequest{}).Do()
if err != nil {
return err
}

if len(updateMask) == 0 {
return nil
}

} else if d.HasChange("disabled") && d.Get("disabled").(bool) {
_, err = config.NewIamClient(userAgent).Projects.ServiceAccounts.Disable(d.Id(),
&iam.DisableServiceAccountRequest{}).Do()
if err != nil {
return err
}

if len(updateMask) == 0 {
return nil
}
}

_, err = config.NewIamClient(userAgent).Projects.ServiceAccounts.Patch(d.Id(),
&iam.PatchServiceAccountRequest{
UpdateMask: strings.Join(updateMask, ","),
Expand Down
70 changes: 70 additions & 0 deletions google/resource_google_service_account_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,65 @@ func TestAccServiceAccount_basic(t *testing.T) {
})
}

func TestAccServiceAccount_Disabled(t *testing.T) {
t.Parallel()

accountId := "a" + randString(t, 10)
uniqueId := ""
displayName := "Terraform Test"
desc := "test description"
project := getTestProjectFromEnv()
expectedEmail := fmt.Sprintf("%s@%s.iam.gserviceaccount.com", accountId, project)
vcrTest(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
Steps: []resource.TestStep{
// The first step creates a basic service account
{
Config: testAccServiceAccountBasic(accountId, displayName, desc),
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttr(
"google_service_account.acceptance", "project", project),
),
},
{
ResourceName: "google_service_account.acceptance",
ImportStateId: fmt.Sprintf("projects/%s/serviceAccounts/%s", project, expectedEmail),
ImportState: true,
ImportStateVerify: true,
},
// The second step disables the service account
{
Config: testAccServiceAccountDisabled(accountId, displayName, desc, true),
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttr(
"google_service_account.acceptance", "project", project),
testAccStoreServiceAccountUniqueId(&uniqueId),
),
},
{
ResourceName: "google_service_account.acceptance",
ImportState: true,
ImportStateVerify: true,
},
// The third step enables the disabled service account
{
Config: testAccServiceAccountDisabled(accountId, displayName, desc, false),
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttr(
"google_service_account.acceptance", "project", project),
testAccStoreServiceAccountUniqueId(&uniqueId),
),
},
{
ResourceName: "google_service_account.acceptance",
ImportState: true,
ImportStateVerify: true,
},
},
})
}

func testAccStoreServiceAccountUniqueId(uniqueId *string) resource.TestCheckFunc {
return func(s *terraform.State) error {
*uniqueId = s.RootModule().Resources["google_service_account.acceptance"].Primary.Attributes["unique_id"]
Expand Down Expand Up @@ -111,3 +170,14 @@ resource "google_service_account" "acceptance" {
}
`, project, account, name)
}

func testAccServiceAccountDisabled(account, name, desc string, disabled bool) string {
return fmt.Sprintf(`
resource "google_service_account" "acceptance" {
account_id = "%v"
display_name = "%v"
description = "%v"
disabled = "%t"
}
`, account, name, desc, disabled)
}
3 changes: 3 additions & 0 deletions website/docs/r/google_service_account.html.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,9 @@ The following arguments are supported:
* `description` - (Optional) A text description of the service account.
Must be less than or equal to 256 UTF-8 bytes.

* `disabled` - (Optional) Whether a service account is disabled or not. Defaults to `false`. This field has no effect during creation.
Must be set after creation to disable a service account.

* `project` - (Optional) The ID of the project that the service account will be created in.
Defaults to the provider project configuration.

Expand Down

0 comments on commit 7065d34

Please sign in to comment.