-
Notifications
You must be signed in to change notification settings - Fork 1.8k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add resource_logging_billing_account_sink resource (#457)
* Add resource_logging_billing_account_sink resource * Fix bad style
- Loading branch information
Showing
8 changed files
with
405 additions
and
72 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
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,75 @@ | ||
package google | ||
|
||
import ( | ||
"fmt" | ||
"github.com/hashicorp/terraform/helper/schema" | ||
) | ||
|
||
func resourceLoggingBillingAccountSink() *schema.Resource { | ||
schm := &schema.Resource{ | ||
Create: resourceLoggingBillingAccountSinkCreate, | ||
Read: resourceLoggingBillingAccountSinkRead, | ||
Delete: resourceLoggingBillingAccountSinkDelete, | ||
Update: resourceLoggingBillingAccountSinkUpdate, | ||
Schema: resourceLoggingSinkSchema(), | ||
} | ||
schm.Schema["billing_account"] = &schema.Schema{ | ||
Type: schema.TypeString, | ||
Required: true, | ||
ForceNew: true, | ||
} | ||
return schm | ||
} | ||
|
||
func resourceLoggingBillingAccountSinkCreate(d *schema.ResourceData, meta interface{}) error { | ||
config := meta.(*Config) | ||
|
||
id, sink := expandResourceLoggingSink(d, "billingAccounts", d.Get("billing_account").(string)) | ||
|
||
// The API will reject any requests that don't explicitly set 'uniqueWriterIdentity' to true. | ||
_, err := config.clientLogging.BillingAccounts.Sinks.Create(id.parent(), sink).UniqueWriterIdentity(true).Do() | ||
if err != nil { | ||
return err | ||
} | ||
|
||
d.SetId(id.canonicalId()) | ||
return resourceLoggingBillingAccountSinkRead(d, meta) | ||
} | ||
|
||
func resourceLoggingBillingAccountSinkRead(d *schema.ResourceData, meta interface{}) error { | ||
config := meta.(*Config) | ||
|
||
sink, err := config.clientLogging.BillingAccounts.Sinks.Get(d.Id()).Do() | ||
if err != nil { | ||
return handleNotFoundError(err, d, fmt.Sprintf("Billing Logging Sink %s", d.Get("name").(string))) | ||
} | ||
|
||
flattenResourceLoggingSink(d, sink) | ||
return nil | ||
|
||
} | ||
|
||
func resourceLoggingBillingAccountSinkUpdate(d *schema.ResourceData, meta interface{}) error { | ||
config := meta.(*Config) | ||
|
||
sink := expandResourceLoggingSinkForUpdate(d) | ||
|
||
// The API will reject any requests that don't explicitly set 'uniqueWriterIdentity' to true. | ||
_, err := config.clientLogging.BillingAccounts.Sinks.Patch(d.Id(), sink).UniqueWriterIdentity(true).Do() | ||
if err != nil { | ||
return err | ||
} | ||
|
||
return resourceLoggingBillingAccountSinkRead(d, meta) | ||
} | ||
|
||
func resourceLoggingBillingAccountSinkDelete(d *schema.ResourceData, meta interface{}) error { | ||
config := meta.(*Config) | ||
|
||
_, err := config.clientLogging.Projects.Sinks.Delete(d.Id()).Do() | ||
if err != nil { | ||
return err | ||
} | ||
|
||
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,166 @@ | ||
package google | ||
|
||
import ( | ||
"fmt" | ||
"os" | ||
"testing" | ||
|
||
"github.com/hashicorp/terraform/helper/acctest" | ||
"github.com/hashicorp/terraform/helper/resource" | ||
"github.com/hashicorp/terraform/terraform" | ||
"google.golang.org/api/logging/v2" | ||
) | ||
|
||
func TestAccLoggingBillingAccountSink_basic(t *testing.T) { | ||
skipIfEnvNotSet(t, "GOOGLE_BILLING_ACCOUNT") | ||
|
||
sinkName := "tf-test-sink-" + acctest.RandString(10) | ||
bucketName := "tf-test-sink-bucket-" + acctest.RandString(10) | ||
billingAccount := os.Getenv("GOOGLE_BILLING_ACCOUNT") | ||
|
||
var sink logging.LogSink | ||
|
||
resource.Test(t, resource.TestCase{ | ||
PreCheck: func() { testAccPreCheck(t) }, | ||
Providers: testAccProviders, | ||
CheckDestroy: testAccCheckLoggingBillingAccountSinkDestroy, | ||
Steps: []resource.TestStep{ | ||
{ | ||
Config: testAccLoggingBillingAccountSink_basic(sinkName, bucketName, billingAccount), | ||
Check: resource.ComposeTestCheckFunc( | ||
testAccCheckLoggingBillingAccountSinkExists("google_logging_billing_account_sink.basic", &sink), | ||
testAccCheckLoggingBillingAccountSink(&sink, "google_logging_billing_account_sink.basic"), | ||
), | ||
}, | ||
}, | ||
}) | ||
} | ||
|
||
func TestAccLoggingBillingAccountSink_update(t *testing.T) { | ||
skipIfEnvNotSet(t, "GOOGLE_BILLING_ACCOUNT") | ||
|
||
sinkName := "tf-test-sink-" + acctest.RandString(10) | ||
bucketName := "tf-test-sink-bucket-" + acctest.RandString(10) | ||
updatedBucketName := "tf-test-sink-bucket-" + acctest.RandString(10) | ||
billingAccount := os.Getenv("GOOGLE_BILLING_ACCOUNT") | ||
|
||
var sinkBefore, sinkAfter logging.LogSink | ||
|
||
resource.Test(t, resource.TestCase{ | ||
PreCheck: func() { testAccPreCheck(t) }, | ||
Providers: testAccProviders, | ||
CheckDestroy: testAccCheckLoggingBillingAccountSinkDestroy, | ||
Steps: []resource.TestStep{ | ||
{ | ||
Config: testAccLoggingBillingAccountSink_update(sinkName, bucketName, billingAccount), | ||
Check: resource.ComposeTestCheckFunc( | ||
testAccCheckLoggingBillingAccountSinkExists("google_logging_billing_account_sink.update", &sinkBefore), | ||
testAccCheckLoggingBillingAccountSink(&sinkBefore, "google_logging_billing_account_sink.update"), | ||
), | ||
}, { | ||
Config: testAccLoggingBillingAccountSink_update(sinkName, updatedBucketName, billingAccount), | ||
Check: resource.ComposeTestCheckFunc( | ||
testAccCheckLoggingBillingAccountSinkExists("google_logging_billing_account_sink.update", &sinkAfter), | ||
testAccCheckLoggingBillingAccountSink(&sinkAfter, "google_logging_billing_account_sink.update"), | ||
), | ||
}, | ||
}, | ||
}) | ||
|
||
// Destination should have changed, but WriterIdentity should be the same | ||
if sinkBefore.Destination == sinkAfter.Destination { | ||
t.Errorf("Expected Destination to change, but it didn't: Destination = %#v", sinkBefore.Destination) | ||
} | ||
if sinkBefore.WriterIdentity != sinkAfter.WriterIdentity { | ||
t.Errorf("Expected WriterIdentity to be the same, but it differs: before = %#v, after = %#v", | ||
sinkBefore.WriterIdentity, sinkAfter.WriterIdentity) | ||
} | ||
} | ||
|
||
func testAccCheckLoggingBillingAccountSinkDestroy(s *terraform.State) error { | ||
config := testAccProvider.Meta().(*Config) | ||
|
||
for _, rs := range s.RootModule().Resources { | ||
if rs.Type != "google_logging_billing_account_sink" { | ||
continue | ||
} | ||
|
||
attributes := rs.Primary.Attributes | ||
|
||
_, err := config.clientLogging.BillingAccounts.Sinks.Get(attributes["id"]).Do() | ||
if err == nil { | ||
return fmt.Errorf("billing sink still exists") | ||
} | ||
} | ||
|
||
return nil | ||
} | ||
|
||
func testAccCheckLoggingBillingAccountSinkExists(n string, sink *logging.LogSink) resource.TestCheckFunc { | ||
return func(s *terraform.State) error { | ||
attributes, err := getResourceAttributes(n, s) | ||
if err != nil { | ||
return err | ||
} | ||
config := testAccProvider.Meta().(*Config) | ||
|
||
si, err := config.clientLogging.BillingAccounts.Sinks.Get(attributes["id"]).Do() | ||
if err != nil { | ||
return err | ||
} | ||
*sink = *si | ||
|
||
return nil | ||
} | ||
} | ||
|
||
func testAccCheckLoggingBillingAccountSink(sink *logging.LogSink, n string) resource.TestCheckFunc { | ||
return func(s *terraform.State) error { | ||
attributes, err := getResourceAttributes(n, s) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
if sink.Destination != attributes["destination"] { | ||
return fmt.Errorf("mismatch on destination: api has %s but client has %s", sink.Destination, attributes["destination"]) | ||
} | ||
|
||
if sink.Filter != attributes["filter"] { | ||
return fmt.Errorf("mismatch on filter: api has %s but client has %s", sink.Filter, attributes["filter"]) | ||
} | ||
|
||
if sink.WriterIdentity != attributes["writer_identity"] { | ||
return fmt.Errorf("mismatch on writer_identity: api has %s but client has %s", sink.WriterIdentity, attributes["writer_identity"]) | ||
} | ||
|
||
return nil | ||
} | ||
} | ||
|
||
func testAccLoggingBillingAccountSink_basic(name, bucketName, billingAccount string) string { | ||
return fmt.Sprintf(` | ||
resource "google_logging_billing_account_sink" "basic" { | ||
name = "%s" | ||
billing_account = "%s" | ||
destination = "storage.googleapis.com/${google_storage_bucket.log-bucket.name}" | ||
filter = "logName=\"projects/%s/logs/compute.googleapis.com%%2Factivity_log\" AND severity>=ERROR" | ||
} | ||
resource "google_storage_bucket" "log-bucket" { | ||
name = "%s" | ||
}`, name, billingAccount, getTestProjectFromEnv(), bucketName) | ||
} | ||
|
||
func testAccLoggingBillingAccountSink_update(name, bucketName, billingAccount string) string { | ||
return fmt.Sprintf(` | ||
resource "google_logging_billing_account_sink" "update" { | ||
name = "%s" | ||
billing_account = "%s" | ||
destination = "storage.googleapis.com/${google_storage_bucket.log-bucket.name}" | ||
filter = "logName=\"projects/%s/logs/compute.googleapis.com%%2Factivity_log\" AND severity>=ERROR" | ||
} | ||
resource "google_storage_bucket" "log-bucket" { | ||
name = "%s" | ||
}`, name, billingAccount, getTestProjectFromEnv(), bucketName) | ||
} |
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 |
---|---|---|
|
@@ -4,53 +4,30 @@ import ( | |
"fmt" | ||
|
||
"github.com/hashicorp/terraform/helper/schema" | ||
"google.golang.org/api/logging/v2" | ||
) | ||
|
||
const nonUniqueWriterAccount = "serviceAccount:[email protected]" | ||
|
||
func resourceLoggingProjectSink() *schema.Resource { | ||
return &schema.Resource{ | ||
schm := &schema.Resource{ | ||
Create: resourceLoggingProjectSinkCreate, | ||
Read: resourceLoggingProjectSinkRead, | ||
Delete: resourceLoggingProjectSinkDelete, | ||
Update: resourceLoggingProjectSinkUpdate, | ||
Schema: map[string]*schema.Schema{ | ||
"name": { | ||
Type: schema.TypeString, | ||
Required: true, | ||
ForceNew: true, | ||
}, | ||
|
||
"destination": { | ||
Type: schema.TypeString, | ||
Required: true, | ||
}, | ||
|
||
"filter": { | ||
Type: schema.TypeString, | ||
Optional: true, | ||
}, | ||
|
||
"project": { | ||
Type: schema.TypeString, | ||
Optional: true, | ||
ForceNew: true, | ||
}, | ||
|
||
"unique_writer_identity": { | ||
Type: schema.TypeBool, | ||
Optional: true, | ||
Default: false, | ||
ForceNew: true, | ||
}, | ||
|
||
"writer_identity": { | ||
Type: schema.TypeString, | ||
Computed: true, | ||
}, | ||
}, | ||
Schema: resourceLoggingSinkSchema(), | ||
} | ||
schm.Schema["project"] = &schema.Schema{ | ||
Type: schema.TypeString, | ||
Optional: true, | ||
ForceNew: true, | ||
} | ||
schm.Schema["unique_writer_identity"] = &schema.Schema{ | ||
Type: schema.TypeBool, | ||
Optional: true, | ||
Default: false, | ||
ForceNew: true, | ||
} | ||
return schm | ||
} | ||
|
||
func resourceLoggingProjectSinkCreate(d *schema.ResourceData, meta interface{}) error { | ||
|
@@ -61,23 +38,10 @@ func resourceLoggingProjectSinkCreate(d *schema.ResourceData, meta interface{}) | |
return err | ||
} | ||
|
||
name := d.Get("name").(string) | ||
|
||
id := LoggingSinkId{ | ||
resourceType: "projects", | ||
resourceId: project, | ||
name: name, | ||
} | ||
|
||
sink := logging.LogSink{ | ||
Name: d.Get("name").(string), | ||
Destination: d.Get("destination").(string), | ||
Filter: d.Get("filter").(string), | ||
} | ||
|
||
id, sink := expandResourceLoggingSink(d, "projects", project) | ||
uniqueWriterIdentity := d.Get("unique_writer_identity").(bool) | ||
|
||
_, err = config.clientLogging.Projects.Sinks.Create(id.parent(), &sink).UniqueWriterIdentity(uniqueWriterIdentity).Do() | ||
_, err = config.clientLogging.Projects.Sinks.Create(id.parent(), sink).UniqueWriterIdentity(uniqueWriterIdentity).Do() | ||
if err != nil { | ||
return err | ||
} | ||
|
@@ -95,10 +59,7 @@ func resourceLoggingProjectSinkRead(d *schema.ResourceData, meta interface{}) er | |
return handleNotFoundError(err, d, fmt.Sprintf("Project Logging Sink %s", d.Get("name").(string))) | ||
} | ||
|
||
d.Set("name", sink.Name) | ||
d.Set("destination", sink.Destination) | ||
d.Set("filter", sink.Filter) | ||
d.Set("writer_identity", sink.WriterIdentity) | ||
flattenResourceLoggingSink(d, sink) | ||
if sink.WriterIdentity != nonUniqueWriterAccount { | ||
d.Set("unique_writer_identity", true) | ||
} else { | ||
|
@@ -110,23 +71,10 @@ func resourceLoggingProjectSinkRead(d *schema.ResourceData, meta interface{}) er | |
func resourceLoggingProjectSinkUpdate(d *schema.ResourceData, meta interface{}) error { | ||
config := meta.(*Config) | ||
|
||
// Can only update destination/filter right now. Despite the method below using 'Patch', the API requires both | ||
// destination and filter (even if unchanged). | ||
sink := logging.LogSink{ | ||
Destination: d.Get("destination").(string), | ||
Filter: d.Get("filter").(string), | ||
} | ||
|
||
if d.HasChange("destination") { | ||
sink.ForceSendFields = append(sink.ForceSendFields, "Destination") | ||
} | ||
if d.HasChange("filter") { | ||
sink.ForceSendFields = append(sink.ForceSendFields, "Filter") | ||
} | ||
|
||
sink := expandResourceLoggingSinkForUpdate(d) | ||
uniqueWriterIdentity := d.Get("unique_writer_identity").(bool) | ||
|
||
_, err := config.clientLogging.Projects.Sinks.Patch(d.Id(), &sink).UniqueWriterIdentity(uniqueWriterIdentity).Do() | ||
_, err := config.clientLogging.Projects.Sinks.Patch(d.Id(), sink).UniqueWriterIdentity(uniqueWriterIdentity).Do() | ||
if err != nil { | ||
return err | ||
} | ||
|
Oops, something went wrong.