From b8c66dc5e57ce8ff8a0cc71fa67726c737f2153a Mon Sep 17 00:00:00 2001 From: Lars Wander Date: Thu, 12 Nov 2015 16:20:08 -0500 Subject: [PATCH] provider/google: Content field for bucket objects --- .../google/resource_storage_bucket_object.go | 42 ++++++++++++++----- .../resource_storage_bucket_object_test.go | 39 +++++++++++++++++ .../r/storage_bucket_object.html.markdown | 10 ++++- 3 files changed, 80 insertions(+), 11 deletions(-) diff --git a/builtin/providers/google/resource_storage_bucket_object.go b/builtin/providers/google/resource_storage_bucket_object.go index 198d7b6850da..679c7e74e5d5 100644 --- a/builtin/providers/google/resource_storage_bucket_object.go +++ b/builtin/providers/google/resource_storage_bucket_object.go @@ -1,7 +1,9 @@ package google import ( + "bytes" "fmt" + "io" "log" "os" @@ -23,26 +25,39 @@ func resourceStorageBucketObject() *schema.Resource { Required: true, ForceNew: true, }, + "name": &schema.Schema{ Type: schema.TypeString, Required: true, ForceNew: true, }, + "source": &schema.Schema{ - Type: schema.TypeString, - Required: true, - ForceNew: true, + Type: schema.TypeString, + Optional: true, + ForceNew: true, + ConflictsWith: []string{"content"}, + }, + + "content": &schema.Schema{ + Type: schema.TypeString, + Optional: true, + ForceNew: true, + ConflictsWith: []string{"source"}, }, + "predefined_acl": &schema.Schema{ Type: schema.TypeString, Deprecated: "Please use resource \"storage_object_acl.predefined_acl\" instead.", Optional: true, ForceNew: true, }, + "md5hash": &schema.Schema{ Type: schema.TypeString, Computed: true, }, + "crc32c": &schema.Schema{ Type: schema.TypeString, Computed: true, @@ -60,11 +75,18 @@ func resourceStorageBucketObjectCreate(d *schema.ResourceData, meta interface{}) bucket := d.Get("bucket").(string) name := d.Get("name").(string) - source := d.Get("source").(string) + var media io.Reader - file, err := os.Open(source) - if err != nil { - return fmt.Errorf("Error opening %s: %s", source, err) + if v, ok := d.GetOk("source"); ok { + err := error(nil) + media, err = os.Open(v.(string)) + if err != nil { + return err + } + } else if v, ok := d.GetOk("content"); ok { + media = bytes.NewReader([]byte(v.(string))) + } else { + return fmt.Errorf("Error, either \"content\" or \"string\" must be specified") } objectsService := storage.NewObjectsService(config.clientStorage) @@ -72,15 +94,15 @@ func resourceStorageBucketObjectCreate(d *schema.ResourceData, meta interface{}) insertCall := objectsService.Insert(bucket, object) insertCall.Name(name) - insertCall.Media(file) + insertCall.Media(media) if v, ok := d.GetOk("predefined_acl"); ok { insertCall.PredefinedAcl(v.(string)) } - _, err = insertCall.Do() + _, err := insertCall.Do() if err != nil { - return fmt.Errorf("Error uploading contents of object %s from %s: %s", name, source, err) + return fmt.Errorf("Error uploading object %s: %s", name, err) } return resourceStorageBucketObjectRead(d, meta) diff --git a/builtin/providers/google/resource_storage_bucket_object_test.go b/builtin/providers/google/resource_storage_bucket_object_test.go index e84822fddf8f..a8fd49c8cc50 100644 --- a/builtin/providers/google/resource_storage_bucket_object_test.go +++ b/builtin/providers/google/resource_storage_bucket_object_test.go @@ -16,6 +16,7 @@ import ( var tf, err = ioutil.TempFile("", "tf-gce-test") var bucketName = "tf-gce-bucket-test" var objectName = "tf-gce-test" +var content = "now this is content!" func TestAccGoogleStorageObject_basic(t *testing.T) { data := []byte("data data data") @@ -42,6 +43,31 @@ func TestAccGoogleStorageObject_basic(t *testing.T) { }) } +func TestAccGoogleStorageObject_content(t *testing.T) { + data := []byte(content) + h := md5.New() + h.Write(data) + data_md5 := base64.StdEncoding.EncodeToString(h.Sum(nil)) + + ioutil.WriteFile(tf.Name(), data, 0644) + resource.Test(t, resource.TestCase{ + PreCheck: func() { + if err != nil { + panic(err) + } + testAccPreCheck(t) + }, + Providers: testAccProviders, + CheckDestroy: testAccGoogleStorageObjectDestroy, + Steps: []resource.TestStep{ + resource.TestStep{ + Config: testGoogleStorageBucketsObjectContent, + Check: testAccCheckGoogleStorageObject(bucketName, objectName, data_md5), + }, + }, + }) +} + func testAccCheckGoogleStorageObject(bucket, object, md5 string) resource.TestCheckFunc { return func(s *terraform.State) error { config := testAccProvider.Meta().(*Config) @@ -87,6 +113,19 @@ func testAccGoogleStorageObjectDestroy(s *terraform.State) error { return nil } +var testGoogleStorageBucketsObjectContent = fmt.Sprintf(` +resource "google_storage_bucket" "bucket" { + name = "%s" +} + +resource "google_storage_bucket_object" "object" { + name = "%s" + bucket = "${google_storage_bucket.bucket.name}" + content = "%s" + predefined_acl = "projectPrivate" +} +`, bucketName, objectName, content) + var testGoogleStorageBucketsObjectBasic = fmt.Sprintf(` resource "google_storage_bucket" "bucket" { name = "%s" diff --git a/website/source/docs/providers/google/r/storage_bucket_object.html.markdown b/website/source/docs/providers/google/r/storage_bucket_object.html.markdown index 1c970530d147..7b481550b87f 100644 --- a/website/source/docs/providers/google/r/storage_bucket_object.html.markdown +++ b/website/source/docs/providers/google/r/storage_bucket_object.html.markdown @@ -29,8 +29,15 @@ resource "google_storage_bucket_object" "picture" { The following arguments are supported: * `name` - (Required) The name of the object. + * `bucket` - (Required) The name of the containing bucket. -* `source` - (Required) A path to the data you want to upload. + +* `source` - (Optional) A path to the data you want to upload. Must be defined +if `content` is not. + +* `content` - (Optional) Data as `string` to be uploaded. Must be defined if +`source` is not. + * `predefined_acl` - (Optional, Deprecated) The [canned GCS ACL](https://cloud.google.com/storage/docs/access-control#predefined-acl) apply. Please switch to `google_storage_object_acl.predefined_acl`. @@ -39,4 +46,5 @@ to `google_storage_object_acl.predefined_acl`. The following attributes are exported: * `md5hash` - (Computed) Base 64 MD5 hash of the uploaded data. + * `crc32c` - (Computed) Base 64 CRC32 hash of the uploaded data.