Skip to content

Commit

Permalink
Resource for managing logging buckets (#3400) (#6227)
Browse files Browse the repository at this point in the history
Signed-off-by: Modular Magician <[email protected]>
  • Loading branch information
modular-magician authored Apr 28, 2020
1 parent 6649452 commit 45d08c0
Show file tree
Hide file tree
Showing 13 changed files with 812 additions and 0 deletions.
12 changes: 12 additions & 0 deletions .changelog/3400.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
```release-note:new-resource
`google_logging_folder_bucket_config`
```
```release-note:new-resource
`google_logging_project_bucket_config`
```
```release-note:new-resource
`google_logging_organization_bucket_config`
```
```release-note:new-resource
`google_logging_billing_account_bucket_config`
```
4 changes: 4 additions & 0 deletions google/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -787,12 +787,16 @@ func ResourceMapWithErrors() (map[string]*schema.Resource, error) {
"google_healthcare_hl7_v2_store_iam_policy": ResourceIamPolicy(IamHealthcareHl7V2StoreSchema, NewHealthcareHl7V2StoreIamUpdater, Hl7V2StoreIdParseFunc),
"google_logging_billing_account_sink": resourceLoggingBillingAccountSink(),
"google_logging_billing_account_exclusion": ResourceLoggingExclusion(BillingAccountLoggingExclusionSchema, NewBillingAccountLoggingExclusionUpdater, billingAccountLoggingExclusionIdParseFunc),
"google_logging_billing_account_bucket_config": ResourceLoggingBillingAccountBucketConfig(),
"google_logging_organization_sink": resourceLoggingOrganizationSink(),
"google_logging_organization_exclusion": ResourceLoggingExclusion(OrganizationLoggingExclusionSchema, NewOrganizationLoggingExclusionUpdater, organizationLoggingExclusionIdParseFunc),
"google_logging_organization_bucket_config": ResourceLoggingOrganizationBucketConfig(),
"google_logging_folder_sink": resourceLoggingFolderSink(),
"google_logging_folder_exclusion": ResourceLoggingExclusion(FolderLoggingExclusionSchema, NewFolderLoggingExclusionUpdater, folderLoggingExclusionIdParseFunc),
"google_logging_folder_bucket_config": ResourceLoggingFolderBucketConfig(),
"google_logging_project_sink": resourceLoggingProjectSink(),
"google_logging_project_exclusion": ResourceLoggingExclusion(ProjectLoggingExclusionSchema, NewProjectLoggingExclusionUpdater, projectLoggingExclusionIdParseFunc),
"google_logging_project_bucket_config": ResourceLoggingProjectBucketConfig(),
"google_kms_key_ring_iam_binding": ResourceIamBinding(IamKmsKeyRingSchema, NewKmsKeyRingIamUpdater, KeyRingIdParseFunc),
"google_kms_key_ring_iam_member": ResourceIamMember(IamKmsKeyRingSchema, NewKmsKeyRingIamUpdater, KeyRingIdParseFunc),
"google_kms_key_ring_iam_policy": ResourceIamPolicy(IamKmsKeyRingSchema, NewKmsKeyRingIamUpdater, KeyRingIdParseFunc),
Expand Down
34 changes: 34 additions & 0 deletions google/resource_logging_billing_account_bucket_config.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package google

import (
"fmt"
"strings"

"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
)

var loggingBillingAccountBucketConfigSchema = map[string]*schema.Schema{
"billing_account": {
Type: schema.TypeString,
Required: true,
ForceNew: true,
},
}

func billingAccountBucketConfigID(d *schema.ResourceData, config *Config) (string, error) {
billingAccount := d.Get("billing_account").(string)
location := d.Get("location").(string)
bucketID := d.Get("bucket_id").(string)

if !strings.HasPrefix(billingAccount, "billingAccounts") {
billingAccount = "billingAccounts/" + billingAccount
}

id := fmt.Sprintf("%s/locations/%s/buckets/%s", billingAccount, location, bucketID)
return id, nil
}

// Create Logging Bucket config
func ResourceLoggingBillingAccountBucketConfig() *schema.Resource {
return ResourceLoggingBucketConfig("billing_account", loggingBillingAccountBucketConfigSchema, billingAccountBucketConfigID)
}
177 changes: 177 additions & 0 deletions google/resource_logging_bucket_config.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,177 @@
package google

import (
"fmt"
"log"
"regexp"
"strings"

"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
)

var loggingBucketConfigSchema = map[string]*schema.Schema{
"name": {
Type: schema.TypeString,
Computed: true,
},
"location": {
Type: schema.TypeString,
Required: true,
ForceNew: true,
},
"bucket_id": {
Type: schema.TypeString,
Required: true,
ForceNew: true,
},
"description": {
Type: schema.TypeString,
Optional: true,
Computed: true,
},
"retention_days": {
Type: schema.TypeInt,
Optional: true,
Default: 30,
},
"lifecycle_state": {
Type: schema.TypeString,
Computed: true,
},
}

type loggingBucketConfigIDFunc func(d *schema.ResourceData, config *Config) (string, error)

// ResourceLoggingBucketConfig creates a resource definition by merging a unique field (eg: folder) to a generic logging bucket
// config resource. In practice the only difference between these resources is the url location.
func ResourceLoggingBucketConfig(parentType string, parentSpecificSchema map[string]*schema.Schema, iDFunc loggingBucketConfigIDFunc) *schema.Resource {
return &schema.Resource{
Create: resourceLoggingBucketConfigAcquire(iDFunc),
Read: resourceLoggingBucketConfigRead,
Update: resourceLoggingBucketConfigUpdate,
Delete: resourceLoggingBucketConfigDelete,
Importer: &schema.ResourceImporter{
State: resourceLoggingBucketConfigImportState(parentType),
},
Schema: mergeSchemas(loggingBucketConfigSchema, parentSpecificSchema),
}
}

var loggingBucketConfigIDRegex = regexp.MustCompile("(.+)/(.+)/locations/(.+)/buckets/(.+)")

func resourceLoggingBucketConfigImportState(parent string) schema.StateFunc {
return func(d *schema.ResourceData, meta interface{}) ([]*schema.ResourceData, error) {
parts := loggingBucketConfigIDRegex.FindStringSubmatch(d.Id())
if parts == nil {
return nil, fmt.Errorf("unable to parse logging sink id %#v", d.Id())
}

if len(parts) != 5 {
return nil, fmt.Errorf("Invalid id format. Format should be '{{parent}}/{{parent_id}}/locations/{{location}}/buckets/{{bucket_id}} with parent in %s", loggingSinkResourceTypes)
}

validLoggingType := false
for _, v := range loggingSinkResourceTypes {
if v == parts[1] {
validLoggingType = true
break
}
}
if !validLoggingType {
return nil, fmt.Errorf("Logging parent type %s is not valid. Valid resource types: %#v", parts[1],
loggingSinkResourceTypes)
}

d.Set(parent, parts[1]+"/"+parts[2])

d.Set("location", parts[3])

d.Set("bucket_id", parts[4])

return []*schema.ResourceData{d}, nil
}
}

func resourceLoggingBucketConfigAcquire(iDFunc loggingBucketConfigIDFunc) func(*schema.ResourceData, interface{}) error {
return func(d *schema.ResourceData, meta interface{}) error {
config := meta.(*Config)

id, err := iDFunc(d, config)
if err != nil {
return err
}

d.SetId(id)

return resourceLoggingBucketConfigUpdate(d, meta)
}
}

func resourceLoggingBucketConfigRead(d *schema.ResourceData, meta interface{}) error {
config := meta.(*Config)

log.Printf("[DEBUG] Fetching logging bucket config: %#v", d.Id())

url, err := replaceVars(d, config, fmt.Sprintf("{{LoggingBasePath}}%s", d.Id()))
if err != nil {
return err
}

res, err := sendRequest(config, "GET", "", url, nil)
if err != nil {
log.Printf("[WARN] Unable to acquire logging bucket config at %s", d.Id())

d.SetId("")
return err
}

d.Set("name", res["name"])
d.Set("description", res["description"])
d.Set("lifecycle_state", res["lifecycleState"])
d.Set("retention_days", res["retentionDays"])

return nil

}

func resourceLoggingBucketConfigUpdate(d *schema.ResourceData, meta interface{}) error {
config := meta.(*Config)

obj := make(map[string]interface{})

url, err := replaceVars(d, config, fmt.Sprintf("{{LoggingBasePath}}%s", d.Id()))
if err != nil {
return err
}

obj["retentionDays"] = d.Get("retention_days")
obj["description"] = d.Get("description")

updateMask := []string{}
if d.HasChange("retention_days") {
updateMask = append(updateMask, "retentionDays")
}
if d.HasChange("description") {
updateMask = append(updateMask, "description")
}
url, err = addQueryParams(url, map[string]string{"updateMask": strings.Join(updateMask, ",")})
if err != nil {
return err
}

_, err = sendRequestWithTimeout(config, "PATCH", "", url, obj, d.Timeout(schema.TimeoutUpdate))
if err != nil {
return fmt.Errorf("Error updating Logging Bucket Config %q: %s", d.Id(), err)
}

return resourceLoggingBucketConfigRead(d, meta)

}

func resourceLoggingBucketConfigDelete(d *schema.ResourceData, meta interface{}) error {

log.Printf("[WARN] Logging bucket configs cannot be deleted. Removing logging bucket config from state: %#v", d.Id())
d.SetId("")

return nil
}
Loading

0 comments on commit 45d08c0

Please sign in to comment.