-
Notifications
You must be signed in to change notification settings - Fork 264
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Browse files
Browse the repository at this point in the history
Signed-off-by: Modular Magician <magic-modules@google.com>
- Loading branch information
1 parent
953dec2
commit 492a719
Showing
7 changed files
with
355 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
```release-note:new-resource | ||
`google_billing_subaccount` | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,157 @@ | ||
package google | ||
|
||
import ( | ||
"fmt" | ||
"strings" | ||
"time" | ||
|
||
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" | ||
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" | ||
"google.golang.org/api/cloudbilling/v1" | ||
) | ||
|
||
func resourceBillingSubaccount() *schema.Resource { | ||
return &schema.Resource{ | ||
Create: resourceBillingSubaccountCreate, | ||
Read: resourceBillingSubaccountRead, | ||
Delete: resourceBillingSubaccountDelete, | ||
Update: resourceBillingSubaccountUpdate, | ||
|
||
Importer: &schema.ResourceImporter{ | ||
State: schema.ImportStatePassthrough, | ||
}, | ||
|
||
Schema: map[string]*schema.Schema{ | ||
"display_name": { | ||
Type: schema.TypeString, | ||
Required: true, | ||
}, | ||
"master_billing_account": { | ||
Type: schema.TypeString, | ||
Required: true, | ||
ForceNew: true, | ||
DiffSuppressFunc: compareSelfLinkOrResourceName, | ||
}, | ||
"deletion_policy": { | ||
Type: schema.TypeString, | ||
Optional: true, | ||
Default: "", | ||
ValidateFunc: validation.StringInSlice([]string{"RENAME_ON_DESTROY", ""}, false), | ||
}, | ||
"billing_account_id": { | ||
Type: schema.TypeString, | ||
Computed: true, | ||
}, | ||
"name": { | ||
Type: schema.TypeString, | ||
Computed: true, | ||
}, | ||
"open": { | ||
Type: schema.TypeBool, | ||
Computed: true, | ||
}, | ||
}, | ||
} | ||
} | ||
|
||
func resourceBillingSubaccountCreate(d *schema.ResourceData, meta interface{}) error { | ||
config := meta.(*Config) | ||
userAgent, err := generateUserAgentString(d, config.userAgent) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
displayName := d.Get("display_name").(string) | ||
masterBillingAccount := d.Get("master_billing_account").(string) | ||
|
||
billingAccount := &cloudbilling.BillingAccount{ | ||
DisplayName: displayName, | ||
MasterBillingAccount: canonicalBillingAccountName(masterBillingAccount), | ||
} | ||
|
||
res, err := config.NewBillingClient(userAgent).BillingAccounts.Create(billingAccount).Do() | ||
if err != nil { | ||
return fmt.Errorf("Error creating billing subaccount '%s' in master account '%s': %s", displayName, masterBillingAccount, err) | ||
} | ||
|
||
d.SetId(res.Name) | ||
|
||
return resourceBillingSubaccountRead(d, meta) | ||
} | ||
|
||
func resourceBillingSubaccountRead(d *schema.ResourceData, meta interface{}) error { | ||
config := meta.(*Config) | ||
userAgent, err := generateUserAgentString(d, config.userAgent) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
id := d.Id() | ||
|
||
billingAccount, err := config.NewBillingClient(userAgent).BillingAccounts.Get(d.Id()).Do() | ||
if err != nil { | ||
return handleNotFoundError(err, d, fmt.Sprintf("Billing Subaccount Not Found : %s", id)) | ||
} | ||
|
||
if err := d.Set("name", billingAccount.Name); err != nil { | ||
return fmt.Errorf("Error setting name: %s", err) | ||
} | ||
if err := d.Set("display_name", billingAccount.DisplayName); err != nil { | ||
return fmt.Errorf("Error setting display_na,e: %s", err) | ||
} | ||
if err := d.Set("open", billingAccount.Open); err != nil { | ||
return fmt.Errorf("Error setting open: %s", err) | ||
} | ||
if err := d.Set("master_billing_account", billingAccount.MasterBillingAccount); err != nil { | ||
return fmt.Errorf("Error setting master_billing_account: %s", err) | ||
} | ||
if err := d.Set("billing_account_id", strings.TrimPrefix(d.Get("name").(string), "billingAccounts/")); err != nil { | ||
return fmt.Errorf("Error setting billing_account_id: %s", err) | ||
} | ||
|
||
return nil | ||
} | ||
|
||
func resourceBillingSubaccountUpdate(d *schema.ResourceData, meta interface{}) error { | ||
config := meta.(*Config) | ||
userAgent, err := generateUserAgentString(d, config.userAgent) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
if ok := d.HasChange("display_name"); ok { | ||
billingAccount := &cloudbilling.BillingAccount{ | ||
DisplayName: d.Get("display_name").(string), | ||
} | ||
_, err := config.NewBillingClient(userAgent).BillingAccounts.Patch(d.Id(), billingAccount).UpdateMask("display_name").Do() | ||
if err != nil { | ||
return handleNotFoundError(err, d, fmt.Sprintf("Error updating billing account : %s", d.Id())) | ||
} | ||
} | ||
return resourceBillingSubaccountRead(d, meta) | ||
} | ||
|
||
func resourceBillingSubaccountDelete(d *schema.ResourceData, meta interface{}) error { | ||
config := meta.(*Config) | ||
userAgent, err := generateUserAgentString(d, config.userAgent) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
deletionPolicy := d.Get("deletion_policy").(string) | ||
|
||
if deletionPolicy == "RENAME_ON_DESTROY" { | ||
t := time.Now() | ||
billingAccount := &cloudbilling.BillingAccount{ | ||
DisplayName: "Terraform Destroyed " + t.Format("20060102150405"), | ||
} | ||
_, err := config.NewBillingClient(userAgent).BillingAccounts.Patch(d.Id(), billingAccount).UpdateMask("display_name").Do() | ||
if err != nil { | ||
return handleNotFoundError(err, d, fmt.Sprintf("Error updating billing account : %s", d.Id())) | ||
} | ||
} | ||
|
||
d.SetId("") | ||
|
||
return nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,131 @@ | ||
package google | ||
|
||
import ( | ||
"fmt" | ||
"strings" | ||
"testing" | ||
|
||
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" | ||
"github.com/hashicorp/terraform-plugin-sdk/v2/terraform" | ||
) | ||
|
||
func TestAccBillingSubaccount_renameOnDestroy(t *testing.T) { | ||
t.Parallel() | ||
|
||
masterBilling := getTestMasterBillingAccountFromEnv(t) | ||
resource.Test(t, resource.TestCase{ | ||
PreCheck: func() { testAccPreCheck(t) }, | ||
Providers: testAccProviders, | ||
CheckDestroy: testAccCheckGoogleBillingSubaccountRenameOnDestroy, | ||
Steps: []resource.TestStep{ | ||
{ | ||
// Test Billing Subaccount creation | ||
Config: testAccBillingSubccount_renameOnDestroy(masterBilling), | ||
Check: testAccCheckGoogleBillingSubaccountExists("subaccount_with_rename_on_destroy"), | ||
}, | ||
}, | ||
}) | ||
} | ||
|
||
func TestAccBillingSubaccount_basic(t *testing.T) { | ||
t.Parallel() | ||
|
||
masterBilling := getTestMasterBillingAccountFromEnv(t) | ||
resource.Test(t, resource.TestCase{ | ||
PreCheck: func() { testAccPreCheck(t) }, | ||
Providers: testAccProviders, | ||
Steps: []resource.TestStep{ | ||
{ | ||
// Test Billing Subaccount creation | ||
Config: testAccBillingSubccount_basic(masterBilling), | ||
Check: testAccCheckGoogleBillingSubaccountExists("subaccount"), | ||
}, | ||
{ | ||
ResourceName: "google_billing_subaccount.subaccount", | ||
ImportState: true, | ||
ImportStateVerify: true, | ||
ImportStateVerifyIgnore: []string{"deletion_policy"}, | ||
}, | ||
{ | ||
// Test Billing Subaccount update | ||
Config: testAccBillingSubccount_update(masterBilling), | ||
Check: testAccCheckGoogleBillingSubaccountExists("subaccount"), | ||
}, | ||
{ | ||
ResourceName: "google_billing_subaccount.subaccount", | ||
ImportState: true, | ||
ImportStateVerify: true, | ||
ImportStateVerifyIgnore: []string{"deletion_policy"}, | ||
}, | ||
}, | ||
}) | ||
} | ||
|
||
func testAccBillingSubccount_basic(masterBillingAccountId string) string { | ||
return fmt.Sprintf(` | ||
resource "google_billing_subaccount" "subaccount" { | ||
display_name = "Test Billing Subaccount" | ||
master_billing_account = "%s" | ||
} | ||
`, masterBillingAccountId) | ||
} | ||
|
||
func testAccBillingSubccount_update(masterBillingAccountId string) string { | ||
return fmt.Sprintf(` | ||
resource "google_billing_subaccount" "subaccount" { | ||
display_name = "Rename Test Billing Subaccount" | ||
master_billing_account = "%s" | ||
} | ||
`, masterBillingAccountId) | ||
} | ||
|
||
func testAccBillingSubccount_renameOnDestroy(masterBillingAccountId string) string { | ||
return fmt.Sprintf(` | ||
resource "google_billing_subaccount" "subaccount_with_rename_on_destroy" { | ||
display_name = "Test Billing Subaccount (Rename on Destroy)" | ||
master_billing_account = "%s" | ||
deletion_policy = "RENAME_ON_DESTROY" | ||
} | ||
`, masterBillingAccountId) | ||
} | ||
|
||
func testAccCheckGoogleBillingSubaccountExists(bindingResourceName string) resource.TestCheckFunc { | ||
return func(s *terraform.State) error { | ||
subaccount, ok := s.RootModule().Resources["google_billing_subaccount."+bindingResourceName] | ||
if !ok { | ||
return fmt.Errorf("Not found: %s", bindingResourceName) | ||
} | ||
|
||
config := testAccProvider.Meta().(*Config) | ||
_, err := config.NewBillingClient(config.userAgent).BillingAccounts.Get(subaccount.Primary.ID).Do() | ||
if err != nil { | ||
return err | ||
} | ||
|
||
return nil | ||
} | ||
} | ||
|
||
func testAccCheckGoogleBillingSubaccountRenameOnDestroy(s *terraform.State) error { | ||
for name, rs := range s.RootModule().Resources { | ||
if rs.Type != "google_billing_subaccount" { | ||
continue | ||
} | ||
if strings.HasPrefix(name, "data.") { | ||
continue | ||
} | ||
|
||
config := testAccProvider.Meta().(*Config) | ||
|
||
res, err := config.NewBillingClient(config.userAgent).BillingAccounts.Get(rs.Primary.ID).Do() | ||
if err != nil { | ||
return err | ||
} | ||
|
||
if !strings.HasPrefix(res.DisplayName, "Terraform Destroyed") { | ||
return fmt.Errorf("Billing account %s was not renamed on destroy", rs.Primary.ID) | ||
} | ||
} | ||
|
||
return nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
--- | ||
subcategory: "Cloud Platform" | ||
layout: "google" | ||
page_title: "Google: google_billing_subaccount" | ||
sidebar_current: "docs-google-billing-subaccount" | ||
description: |- | ||
Allows management of a Google Cloud Billing Subaccount. | ||
--- | ||
|
||
# google\_billing\_subaccount | ||
|
||
Allows creation and management of a Google Cloud Billing Subaccount. | ||
|
||
!> **WARNING:** Deleting this Terraform resource will not delete or close the billing subaccount. | ||
|
||
```hcl | ||
resource "google_billing_subaccount" "subaccount" { | ||
display_name = "My Billing Account" | ||
master_billing_account = "012345-567890-ABCDEF" | ||
} | ||
``` | ||
|
||
## Argument Reference | ||
|
||
* `display_name` (Required) - The display name of the billing account. | ||
|
||
* `master_billing_account` (Required) - The name of the master billing account that the subaccount | ||
will be created under in the form `{billing_account_id}` or `billingAccounts/{billing_account_id}`. | ||
|
||
* `deletion_policy` (Optional) - If set to "RENAME_ON_DESTROY" the billing account display_name | ||
will be changed to "Terraform Destroyed" along with a timestamp. If set to "" this will not occur. | ||
Default is "". | ||
|
||
## Attributes Reference | ||
|
||
The following additional attributes are exported: | ||
|
||
* `open` - `true` if the billing account is open, `false` if the billing account is closed. | ||
|
||
* `name` - The resource name of the billing account in the form `billingAccounts/{billing_account_id}`. | ||
|
||
* `billing_account_id` - The billing account id. | ||
|
||
## Import | ||
|
||
Billing Subaccounts can be imported using any of these accepted formats: | ||
|
||
``` | ||
$ terraform import google_billing_subaccount.default billingAccounts/{billing_account_id} | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters