From 209b7da3b27a1a7144371adca49ff5e0559f84c7 Mon Sep 17 00:00:00 2001
From: gdm85 <gdm85@users.noreply.github.com>
Date: Tue, 18 Jul 2017 16:15:29 +0200
Subject: [PATCH] gcs: Add ability to specify location and storage class via
 config and command line

* Add gcs-location and gcs-storage-class options for Google Cloud Storage
* Added config options (same as S3)
* Updated configuration example in documentation for Google Cloud Storage
---
 docs/content/googlecloudstorage.md       | 48 +++++++++++++-
 googlecloudstorage/googlecloudstorage.go | 84 +++++++++++++++++++++++-
 2 files changed, 130 insertions(+), 2 deletions(-)

diff --git a/docs/content/googlecloudstorage.md b/docs/content/googlecloudstorage.md
index 77ffda552..5ed930aba 100644
--- a/docs/content/googlecloudstorage.md
+++ b/docs/content/googlecloudstorage.md
@@ -1,7 +1,7 @@
 ---
 title: "Google Cloud Storage"
 description: "Rclone docs for Google Cloud Storage"
-date: "2015-09-12"
+date: "2017-07-18"
 ---
 
 <i class="fa fa-google"></i> Google Cloud Storage
@@ -91,6 +91,52 @@ Choose a number from below, or type in your own value
  5 / Project team owners get OWNER access, and all Users get WRITER access.
    \ "publicReadWrite"
 bucket_acl> 2
+Location for the newly created buckets.
+Choose a number from below, or type in your own value
+ 1 / Empty for default location (US).
+   \ ""
+ 2 / Multi-regional location for Asia.
+   \ "asia"
+ 3 / Multi-regional location for Europe.
+   \ "eu"
+ 4 / Multi-regional location for United States.
+   \ "us"
+ 5 / Taiwan.
+   \ "asia-east1"
+ 6 / Tokyo.
+   \ "asia-northeast1"
+ 7 / Singapore.
+   \ "asia-southeast1"
+ 8 / Sydney.
+   \ "australia-southeast1"
+ 9 / Belgium.
+   \ "europe-west1"
+10 / London.
+   \ "europe-west2"
+11 / Iowa.
+   \ "us-central1"
+12 / South Carolina.
+   \ "us-east1"
+13 / Northern Virginia.
+   \ "us-east4"
+14 / Oregon.
+   \ "us-west1"
+location> 12
+The storage class to use when storing objects in Google Cloud Storage.
+Choose a number from below, or type in your own value
+ 1 / Default
+   \ ""
+ 2 / Multi-regional storage class
+   \ "MULTI_REGIONAL"
+ 3 / Regional storage class
+   \ "REGIONAL"
+ 4 / Nearline storage class
+   \ "NEARLINE"
+ 5 / Coldline storage class
+   \ "COLDLINE"
+ 6 / Durable reduced availability storage class
+   \ "DURABLE_REDUCED_AVAILABILITY"
+storage_class> 5
 Remote config
 Use auto config?
  * Say Y if not sure
diff --git a/googlecloudstorage/googlecloudstorage.go b/googlecloudstorage/googlecloudstorage.go
index d8175a6af..0bce47173 100644
--- a/googlecloudstorage/googlecloudstorage.go
+++ b/googlecloudstorage/googlecloudstorage.go
@@ -46,6 +46,8 @@ const (
 )
 
 var (
+	gcsLocation     = fs.StringP("gcs-location", "", "", "Default location for buckets (us|eu|asia|us-central1|us-east1|us-east4|us-west1|asia-east1|asia-noetheast1|asia-southeast1|australia-southeast1|europe-west1|europe-west2).")
+	gcsStorageClass = fs.StringP("gcs-storage-class", "", "", "Default storage class for buckets (MULTI_REGIONAL|REGIONAL|STANDARD|NEARLINE|COLDLINE|DURABLE_REDUCED_AVAILABILITY).")
 	// Description of how to auth for this app
 	storageConfig = &oauth2.Config{
 		Scopes:       []string{storage.DevstorageFullControlScope},
@@ -124,6 +126,74 @@ func init() {
 				Value: "publicReadWrite",
 				Help:  "Project team owners get OWNER access, and all Users get WRITER access.",
 			}},
+		}, {
+			Name: "location",
+			Help: "Location for the newly created buckets.",
+			Examples: []fs.OptionExample{{
+				Value: "",
+				Help:  "Empty for default location (US).",
+			}, {
+				Value: "asia",
+				Help:  "Multi-regional location for Asia.",
+			}, {
+				Value: "eu",
+				Help:  "Multi-regional location for Europe.",
+			}, {
+				Value: "us",
+				Help:  "Multi-regional location for United States.",
+			}, {
+				Value: "asia-east1",
+				Help:  "Taiwan.",
+			}, {
+				Value: "asia-northeast1",
+				Help:  "Tokyo.",
+			}, {
+				Value: "asia-southeast1",
+				Help:  "Singapore.",
+			}, {
+				Value: "australia-southeast1",
+				Help:  "Sydney.",
+			}, {
+				Value: "europe-west1",
+				Help:  "Belgium.",
+			}, {
+				Value: "europe-west2",
+				Help:  "London.",
+			}, {
+				Value: "us-central1",
+				Help:  "Iowa.",
+			}, {
+				Value: "us-east1",
+				Help:  "South Carolina.",
+			}, {
+				Value: "us-east4",
+				Help:  "Northern Virginia.",
+			}, {
+				Value: "us-west1",
+				Help:  "Oregon.",
+			}},
+		}, {
+			Name: "storage_class",
+			Help: "The storage class to use when storing objects in Google Cloud Storage.",
+			Examples: []fs.OptionExample{{
+				Value: "",
+				Help:  "Default",
+			}, {
+				Value: "MULTI_REGIONAL",
+				Help:  "Multi-regional storage class",
+			}, {
+				Value: "REGIONAL",
+				Help:  "Regional storage class",
+			}, {
+				Value: "NEARLINE",
+				Help:  "Nearline storage class",
+			}, {
+				Value: "COLDLINE",
+				Help:  "Coldline storage class",
+			}, {
+				Value: "DURABLE_REDUCED_AVAILABILITY",
+				Help:  "Durable reduced availability storage class",
+			}},
 		}},
 	})
 }
@@ -141,6 +211,8 @@ type Fs struct {
 	projectNumber string           // used for finding buckets
 	objectACL     string           // used when creating new objects
 	bucketACL     string           // used when creating new buckets
+	location      string           // location of new buckets
+	storageClass  string           // storage class of new buckets
 }
 
 // Object describes a storage object
@@ -242,6 +314,8 @@ func NewFs(name, root string) (fs.Fs, error) {
 		projectNumber: fs.ConfigFileGet(name, "project_number"),
 		objectACL:     fs.ConfigFileGet(name, "object_acl"),
 		bucketACL:     fs.ConfigFileGet(name, "bucket_acl"),
+		location:      fs.ConfigFileGet(name, "location"),
+		storageClass:  fs.ConfigFileGet(name, "storage_class"),
 	}
 	f.features = (&fs.Features{ReadMimeType: true, WriteMimeType: true}).Fill(f)
 	if f.objectACL == "" {
@@ -250,6 +324,12 @@ func NewFs(name, root string) (fs.Fs, error) {
 	if f.bucketACL == "" {
 		f.bucketACL = "private"
 	}
+	if *gcsLocation != "" {
+		f.location = *gcsLocation
+	}
+	if *gcsStorageClass != "" {
+		f.storageClass = *gcsStorageClass
+	}
 
 	// Create a new authorized Drive client.
 	f.client = oAuthClient
@@ -501,7 +581,9 @@ func (f *Fs) Mkdir(dir string) error {
 	}
 
 	bucket := storage.Bucket{
-		Name: f.bucket,
+		Name:         f.bucket,
+		Location:     f.location,
+		StorageClass: f.storageClass,
 	}
 	_, err = f.svc.Buckets.Insert(f.projectNumber, &bucket).PredefinedAcl(f.bucketACL).Do()
 	if err == nil {