Skip to content

Commit b8c66dc

Browse files
lwanderLars Wander
authored andcommitted
provider/google: Content field for bucket objects
1 parent aa05e82 commit b8c66dc

3 files changed

Lines changed: 80 additions & 11 deletions

File tree

builtin/providers/google/resource_storage_bucket_object.go

Lines changed: 32 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
package google
22

33
import (
4+
"bytes"
45
"fmt"
6+
"io"
57
"log"
68
"os"
79

@@ -23,26 +25,39 @@ func resourceStorageBucketObject() *schema.Resource {
2325
Required: true,
2426
ForceNew: true,
2527
},
28+
2629
"name": &schema.Schema{
2730
Type: schema.TypeString,
2831
Required: true,
2932
ForceNew: true,
3033
},
34+
3135
"source": &schema.Schema{
32-
Type: schema.TypeString,
33-
Required: true,
34-
ForceNew: true,
36+
Type: schema.TypeString,
37+
Optional: true,
38+
ForceNew: true,
39+
ConflictsWith: []string{"content"},
40+
},
41+
42+
"content": &schema.Schema{
43+
Type: schema.TypeString,
44+
Optional: true,
45+
ForceNew: true,
46+
ConflictsWith: []string{"source"},
3547
},
48+
3649
"predefined_acl": &schema.Schema{
3750
Type: schema.TypeString,
3851
Deprecated: "Please use resource \"storage_object_acl.predefined_acl\" instead.",
3952
Optional: true,
4053
ForceNew: true,
4154
},
55+
4256
"md5hash": &schema.Schema{
4357
Type: schema.TypeString,
4458
Computed: true,
4559
},
60+
4661
"crc32c": &schema.Schema{
4762
Type: schema.TypeString,
4863
Computed: true,
@@ -60,27 +75,34 @@ func resourceStorageBucketObjectCreate(d *schema.ResourceData, meta interface{})
6075

6176
bucket := d.Get("bucket").(string)
6277
name := d.Get("name").(string)
63-
source := d.Get("source").(string)
78+
var media io.Reader
6479

65-
file, err := os.Open(source)
66-
if err != nil {
67-
return fmt.Errorf("Error opening %s: %s", source, err)
80+
if v, ok := d.GetOk("source"); ok {
81+
err := error(nil)
82+
media, err = os.Open(v.(string))
83+
if err != nil {
84+
return err
85+
}
86+
} else if v, ok := d.GetOk("content"); ok {
87+
media = bytes.NewReader([]byte(v.(string)))
88+
} else {
89+
return fmt.Errorf("Error, either \"content\" or \"string\" must be specified")
6890
}
6991

7092
objectsService := storage.NewObjectsService(config.clientStorage)
7193
object := &storage.Object{Bucket: bucket}
7294

7395
insertCall := objectsService.Insert(bucket, object)
7496
insertCall.Name(name)
75-
insertCall.Media(file)
97+
insertCall.Media(media)
7698
if v, ok := d.GetOk("predefined_acl"); ok {
7799
insertCall.PredefinedAcl(v.(string))
78100
}
79101

80-
_, err = insertCall.Do()
102+
_, err := insertCall.Do()
81103

82104
if err != nil {
83-
return fmt.Errorf("Error uploading contents of object %s from %s: %s", name, source, err)
105+
return fmt.Errorf("Error uploading object %s: %s", name, err)
84106
}
85107

86108
return resourceStorageBucketObjectRead(d, meta)

builtin/providers/google/resource_storage_bucket_object_test.go

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import (
1616
var tf, err = ioutil.TempFile("", "tf-gce-test")
1717
var bucketName = "tf-gce-bucket-test"
1818
var objectName = "tf-gce-test"
19+
var content = "now this is content!"
1920

2021
func TestAccGoogleStorageObject_basic(t *testing.T) {
2122
data := []byte("data data data")
@@ -42,6 +43,31 @@ func TestAccGoogleStorageObject_basic(t *testing.T) {
4243
})
4344
}
4445

46+
func TestAccGoogleStorageObject_content(t *testing.T) {
47+
data := []byte(content)
48+
h := md5.New()
49+
h.Write(data)
50+
data_md5 := base64.StdEncoding.EncodeToString(h.Sum(nil))
51+
52+
ioutil.WriteFile(tf.Name(), data, 0644)
53+
resource.Test(t, resource.TestCase{
54+
PreCheck: func() {
55+
if err != nil {
56+
panic(err)
57+
}
58+
testAccPreCheck(t)
59+
},
60+
Providers: testAccProviders,
61+
CheckDestroy: testAccGoogleStorageObjectDestroy,
62+
Steps: []resource.TestStep{
63+
resource.TestStep{
64+
Config: testGoogleStorageBucketsObjectContent,
65+
Check: testAccCheckGoogleStorageObject(bucketName, objectName, data_md5),
66+
},
67+
},
68+
})
69+
}
70+
4571
func testAccCheckGoogleStorageObject(bucket, object, md5 string) resource.TestCheckFunc {
4672
return func(s *terraform.State) error {
4773
config := testAccProvider.Meta().(*Config)
@@ -87,6 +113,19 @@ func testAccGoogleStorageObjectDestroy(s *terraform.State) error {
87113
return nil
88114
}
89115

116+
var testGoogleStorageBucketsObjectContent = fmt.Sprintf(`
117+
resource "google_storage_bucket" "bucket" {
118+
name = "%s"
119+
}
120+
121+
resource "google_storage_bucket_object" "object" {
122+
name = "%s"
123+
bucket = "${google_storage_bucket.bucket.name}"
124+
content = "%s"
125+
predefined_acl = "projectPrivate"
126+
}
127+
`, bucketName, objectName, content)
128+
90129
var testGoogleStorageBucketsObjectBasic = fmt.Sprintf(`
91130
resource "google_storage_bucket" "bucket" {
92131
name = "%s"

website/source/docs/providers/google/r/storage_bucket_object.html.markdown

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,15 @@ resource "google_storage_bucket_object" "picture" {
2929
The following arguments are supported:
3030

3131
* `name` - (Required) The name of the object.
32+
3233
* `bucket` - (Required) The name of the containing bucket.
33-
* `source` - (Required) A path to the data you want to upload.
34+
35+
* `source` - (Optional) A path to the data you want to upload. Must be defined
36+
if `content` is not.
37+
38+
* `content` - (Optional) Data as `string` to be uploaded. Must be defined if
39+
`source` is not.
40+
3441
* `predefined_acl` - (Optional, Deprecated) The [canned GCS ACL](https://cloud.google.com/storage/docs/access-control#predefined-acl) apply. Please switch
3542
to `google_storage_object_acl.predefined_acl`.
3643

@@ -39,4 +46,5 @@ to `google_storage_object_acl.predefined_acl`.
3946
The following attributes are exported:
4047

4148
* `md5hash` - (Computed) Base 64 MD5 hash of the uploaded data.
49+
4250
* `crc32c` - (Computed) Base 64 CRC32 hash of the uploaded data.

0 commit comments

Comments
 (0)