1// Copyright 2016 Google Inc. All Rights Reserved. 2// 3// Licensed under the Apache License, Version 2.0 (the "License"); 4// you may not use this file except in compliance with the License. 5// You may obtain a copy of the License at 6// 7// http://www.apache.org/licenses/LICENSE-2.0 8// 9// Unless required by applicable law or agreed to in writing, software 10// distributed under the License is distributed on an "AS IS" BASIS, 11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12// See the License for the specific language governing permissions and 13// limitations under the License. 14 15/* 16Package storage provides an easy way to work with Google Cloud Storage. 17Google Cloud Storage stores data in named objects, which are grouped into buckets. 18 19More information about Google Cloud Storage is available at 20https://cloud.google.com/storage/docs. 21 22All of the methods of this package use exponential backoff to retry calls 23that fail with certain errors, as described in 24https://cloud.google.com/storage/docs/exponential-backoff. 25 26Note: This package is in beta. Some backwards-incompatible changes may occur. 27 28 29Creating a Client 30 31To start working with this package, create a client: 32 33 ctx := context.Background() 34 client, err := storage.NewClient(ctx) 35 if err != nil { 36 // TODO: Handle error. 37 } 38 39Buckets 40 41A Google Cloud Storage bucket is a collection of objects. To work with a 42bucket, make a bucket handle: 43 44 bkt := client.Bucket(bucketName) 45 46A handle is a reference to a bucket. You can have a handle even if the 47bucket doesn't exist yet. To create a bucket in Google Cloud Storage, 48call Create on the handle: 49 50 if err := bkt.Create(ctx, projectID, nil); err != nil { 51 // TODO: Handle error. 52 } 53 54Note that although buckets are associated with projects, bucket names are 55global across all projects. 56 57Each bucket has associated metadata, represented in this package by 58BucketAttrs. The third argument to BucketHandle.Create allows you to set 59the intial BucketAttrs of a bucket. To retrieve a bucket's attributes, use 60Attrs: 61 62 attrs, err := bkt.Attrs(ctx) 63 if err != nil { 64 // TODO: Handle error. 65 } 66 fmt.Printf("bucket %s, created at %s, is located in %s with storage class %s\n", 67 attrs.Name, attrs.Created, attrs.Location, attrs.StorageClass) 68 69Objects 70 71An object holds arbitrary data as a sequence of bytes, like a file. You 72refer to objects using a handle, just as with buckets. You can use the 73standard Go io.Reader and io.Writer interfaces to read and write 74object data: 75 76 obj := bkt.Object("data") 77 // Write something to obj. 78 // w implements io.Writer. 79 w := obj.NewWriter(ctx) 80 // Write some text to obj. This will overwrite whatever is there. 81 if _, err := fmt.Fprintf(w, "This object contains text.\n"); err != nil { 82 // TODO: Handle error. 83 } 84 // Close, just like writing a file. 85 if err := w.Close(); err != nil { 86 // TODO: Handle error. 87 } 88 89 // Read it back. 90 r, err := obj.NewReader(ctx) 91 if err != nil { 92 // TODO: Handle error. 93 } 94 defer r.Close() 95 if _, err := io.Copy(os.Stdout, r); err != nil { 96 // TODO: Handle error. 97 } 98 // Prints "This object contains text." 99 100Objects also have attributes, which you can fetch with Attrs: 101 102 objAttrs, err := obj.Attrs(ctx) 103 if err != nil { 104 // TODO: Handle error. 105 } 106 fmt.Printf("object %s has size %d and can be read using %s\n", 107 objAttrs.Name, objAttrs.Size, objAttrs.MediaLink) 108 109ACLs 110 111Both objects and buckets have ACLs (Access Control Lists). An ACL is a list of 112ACLRules, each of which specifies the role of a user, group or project. ACLs 113are suitable for fine-grained control, but you may prefer using IAM to control 114access at the project level (see 115https://cloud.google.com/storage/docs/access-control/iam). 116 117To list the ACLs of a bucket or object, obtain an ACLHandle and call its List method: 118 119 acls, err := obj.ACL().List(ctx) 120 if err != nil { 121 // TODO: Handle error. 122 } 123 for _, rule := range acls { 124 fmt.Printf("%s has role %s\n", rule.Entity, rule.Role) 125 } 126 127You can also set and delete ACLs. 128 129Conditions 130 131Every object has a generation and a metageneration. The generation changes 132whenever the content changes, and the metageneration changes whenever the 133metadata changes. Conditions let you check these values before an operation; 134the operation only executes if the conditions match. You can use conditions to 135prevent race conditions in read-modify-write operations. 136 137For example, say you've read an object's metadata into objAttrs. Now 138you want to write to that object, but only if its contents haven't changed 139since you read it. Here is how to express that: 140 141 w = obj.If(storage.Conditions{GenerationMatch: objAttrs.Generation}).NewWriter(ctx) 142 // Proceed with writing as above. 143 144Signed URLs 145 146You can obtain a URL that lets anyone read or write an object for a limited time. 147You don't need to create a client to do this. See the documentation of 148SignedURL for details. 149 150 url, err := storage.SignedURL(bucketName, "shared-object", opts) 151 if err != nil { 152 // TODO: Handle error. 153 } 154 fmt.Println(url) 155 156Authentication 157 158See examples of authorization and authentication at 159https://godoc.org/cloud.google.com/go#pkg-examples. 160*/ 161package storage 162