gcloud 0.11.0 → 0.12.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (121) hide show
  1. checksums.yaml +8 -8
  2. data/AUTHENTICATION.md +3 -3
  3. data/CHANGELOG.md +92 -0
  4. data/OVERVIEW.md +3 -3
  5. data/lib/gcloud.rb +75 -25
  6. data/lib/gcloud/backoff.rb +5 -1
  7. data/lib/gcloud/bigquery.rb +25 -43
  8. data/lib/gcloud/bigquery/copy_job.rb +13 -13
  9. data/lib/gcloud/bigquery/data.rb +20 -16
  10. data/lib/gcloud/bigquery/dataset.rb +202 -177
  11. data/lib/gcloud/bigquery/dataset/access.rb +118 -104
  12. data/lib/gcloud/bigquery/dataset/list.rb +14 -18
  13. data/lib/gcloud/bigquery/extract_job.rb +12 -12
  14. data/lib/gcloud/bigquery/insert_response.rb +12 -14
  15. data/lib/gcloud/bigquery/job.rb +45 -57
  16. data/lib/gcloud/bigquery/job/list.rb +18 -24
  17. data/lib/gcloud/bigquery/load_job.rb +35 -27
  18. data/lib/gcloud/bigquery/project.rb +53 -73
  19. data/lib/gcloud/bigquery/query_data.rb +28 -35
  20. data/lib/gcloud/bigquery/query_job.rb +18 -18
  21. data/lib/gcloud/bigquery/schema.rb +359 -0
  22. data/lib/gcloud/bigquery/service.rb +506 -0
  23. data/lib/gcloud/bigquery/table.rb +185 -266
  24. data/lib/gcloud/bigquery/table/list.rb +15 -19
  25. data/lib/gcloud/bigquery/view.rb +126 -81
  26. data/lib/gcloud/datastore.rb +39 -27
  27. data/lib/gcloud/datastore/commit.rb +2 -2
  28. data/lib/gcloud/datastore/dataset.rb +8 -19
  29. data/lib/gcloud/datastore/dataset/lookup_results.rb +2 -4
  30. data/lib/gcloud/datastore/dataset/query_results.rb +0 -2
  31. data/lib/gcloud/datastore/entity.rb +7 -1
  32. data/lib/gcloud/datastore/errors.rb +5 -27
  33. data/lib/gcloud/datastore/grpc_utils.rb +4 -3
  34. data/lib/gcloud/datastore/key.rb +6 -0
  35. data/lib/gcloud/datastore/service.rb +18 -12
  36. data/lib/gcloud/datastore/transaction.rb +0 -10
  37. data/lib/gcloud/dns.rb +29 -19
  38. data/lib/gcloud/dns/change.rb +10 -15
  39. data/lib/gcloud/dns/change/list.rb +4 -4
  40. data/lib/gcloud/dns/importer.rb +1 -1
  41. data/lib/gcloud/dns/project.rb +32 -49
  42. data/lib/gcloud/dns/record.rb +8 -2
  43. data/lib/gcloud/dns/record/list.rb +4 -4
  44. data/lib/gcloud/dns/service.rb +167 -0
  45. data/lib/gcloud/dns/zone.rb +33 -52
  46. data/lib/gcloud/dns/zone/list.rb +12 -16
  47. data/lib/gcloud/errors.rb +31 -19
  48. data/lib/gcloud/logging.rb +50 -39
  49. data/lib/gcloud/logging/entry.rb +197 -24
  50. data/lib/gcloud/logging/entry/list.rb +0 -2
  51. data/lib/gcloud/logging/logger.rb +1 -1
  52. data/lib/gcloud/logging/metric.rb +3 -9
  53. data/lib/gcloud/logging/metric/list.rb +0 -2
  54. data/lib/gcloud/logging/project.rb +58 -54
  55. data/lib/gcloud/logging/resource_descriptor.rb +2 -2
  56. data/lib/gcloud/logging/resource_descriptor/list.rb +0 -2
  57. data/lib/gcloud/logging/service.rb +32 -23
  58. data/lib/gcloud/logging/sink.rb +8 -14
  59. data/lib/gcloud/logging/sink/list.rb +0 -2
  60. data/lib/gcloud/pubsub.rb +21 -16
  61. data/lib/gcloud/pubsub/policy.rb +204 -0
  62. data/lib/gcloud/pubsub/project.rb +26 -38
  63. data/lib/gcloud/pubsub/service.rb +39 -31
  64. data/lib/gcloud/pubsub/subscription.rb +56 -59
  65. data/lib/gcloud/pubsub/subscription/list.rb +4 -4
  66. data/lib/gcloud/pubsub/topic.rb +69 -66
  67. data/lib/gcloud/pubsub/topic/list.rb +0 -2
  68. data/lib/gcloud/pubsub/topic/{batch.rb → publisher.rb} +15 -2
  69. data/lib/gcloud/resource_manager.rb +27 -26
  70. data/lib/gcloud/resource_manager/manager.rb +19 -39
  71. data/lib/gcloud/resource_manager/policy.rb +211 -0
  72. data/lib/gcloud/resource_manager/project.rb +97 -121
  73. data/lib/gcloud/resource_manager/project/list.rb +7 -7
  74. data/lib/gcloud/resource_manager/project/updater.rb +4 -9
  75. data/lib/gcloud/resource_manager/service.rb +127 -0
  76. data/lib/gcloud/storage.rb +24 -42
  77. data/lib/gcloud/storage/bucket.rb +104 -192
  78. data/lib/gcloud/storage/bucket/acl.rb +47 -143
  79. data/lib/gcloud/storage/bucket/cors.rb +55 -11
  80. data/lib/gcloud/storage/bucket/list.rb +14 -14
  81. data/lib/gcloud/storage/errors.rb +3 -43
  82. data/lib/gcloud/storage/file.rb +114 -111
  83. data/lib/gcloud/storage/file/acl.rb +27 -113
  84. data/lib/gcloud/storage/file/list.rb +21 -21
  85. data/lib/gcloud/storage/project.rb +49 -59
  86. data/lib/gcloud/storage/service.rb +347 -0
  87. data/lib/gcloud/translate.rb +24 -14
  88. data/lib/gcloud/translate/api.rb +12 -21
  89. data/lib/gcloud/translate/detection.rb +5 -5
  90. data/lib/gcloud/translate/language.rb +1 -1
  91. data/lib/gcloud/translate/service.rb +80 -0
  92. data/lib/gcloud/translate/translation.rb +6 -6
  93. data/lib/gcloud/version.rb +1 -1
  94. data/lib/gcloud/vision.rb +24 -15
  95. data/lib/gcloud/vision/annotate.rb +24 -21
  96. data/lib/gcloud/vision/annotation.rb +9 -9
  97. data/lib/gcloud/vision/annotation/entity.rb +11 -11
  98. data/lib/gcloud/vision/annotation/face.rb +25 -25
  99. data/lib/gcloud/vision/annotation/properties.rb +8 -8
  100. data/lib/gcloud/vision/annotation/safe_search.rb +4 -4
  101. data/lib/gcloud/vision/annotation/text.rb +7 -7
  102. data/lib/gcloud/vision/annotation/vertex.rb +1 -1
  103. data/lib/gcloud/vision/image.rb +11 -11
  104. data/lib/gcloud/vision/location.rb +5 -2
  105. data/lib/gcloud/vision/project.rb +14 -16
  106. data/lib/gcloud/vision/service.rb +66 -0
  107. data/lib/google/api_client.rb +0 -0
  108. metadata +27 -24
  109. data/lib/gcloud/bigquery/connection.rb +0 -624
  110. data/lib/gcloud/bigquery/errors.rb +0 -68
  111. data/lib/gcloud/bigquery/table/schema.rb +0 -234
  112. data/lib/gcloud/dns/connection.rb +0 -173
  113. data/lib/gcloud/dns/errors.rb +0 -68
  114. data/lib/gcloud/resource_manager/connection.rb +0 -134
  115. data/lib/gcloud/resource_manager/errors.rb +0 -68
  116. data/lib/gcloud/storage/connection.rb +0 -444
  117. data/lib/gcloud/translate/connection.rb +0 -85
  118. data/lib/gcloud/translate/errors.rb +0 -68
  119. data/lib/gcloud/upload.rb +0 -95
  120. data/lib/gcloud/vision/connection.rb +0 -63
  121. data/lib/gcloud/vision/errors.rb +0 -69
@@ -56,9 +56,8 @@ module Gcloud
56
56
  def initialize file
57
57
  @bucket = file.bucket
58
58
  @file = file.name
59
- @connection = file.connection
59
+ @service = file.service
60
60
  @owners = nil
61
- @writers = nil
62
61
  @readers = nil
63
62
  end
64
63
 
@@ -77,10 +76,13 @@ module Gcloud
77
76
  # file.acl.reload!
78
77
  #
79
78
  def reload!
80
- resp = @connection.list_file_acls @bucket, @file
81
- acls = resp.data["items"]
79
+ gapi = @service.list_file_acls @bucket, @file
80
+ acls = Array(gapi.items).map do |acl|
81
+ return acl if acl.is_a? Google::Apis::StorageV1::ObjectAccessControl
82
+ fail "Unknown ACL format: #{acl.class}" unless acl.is_a? Hash
83
+ Google::Apis::StorageV1::ObjectAccessControl.from_json acl.to_json
84
+ end
82
85
  @owners = entities_from_acls acls, "OWNER"
83
- @writers = entities_from_acls acls, "WRITER"
84
86
  @readers = entities_from_acls acls, "READER"
85
87
  end
86
88
  alias_method :refresh!, :reload!
@@ -106,27 +108,6 @@ module Gcloud
106
108
  @owners
107
109
  end
108
110
 
109
- ##
110
- # Lists the owners of the file.
111
- #
112
- # @return [Array<String>]
113
- #
114
- # @example
115
- # require "gcloud"
116
- #
117
- # gcloud = Gcloud.new
118
- # storage = gcloud.storage
119
- #
120
- # bucket = storage.bucket "my-bucket"
121
- #
122
- # file = bucket.file "path/to/my-file.ext"
123
- # file.acl.writers.each { |writer| puts writer }
124
- #
125
- def writers
126
- reload! if @writers.nil?
127
- @writers
128
- end
129
-
130
111
  ##
131
112
  # Lists the readers of the file.
132
113
  #
@@ -192,68 +173,11 @@ module Gcloud
192
173
  #
193
174
  def add_owner entity, generation: nil
194
175
  options = { generation: generation }
195
- resp = @connection.insert_file_acl @bucket, @file, entity,
196
- "OWNER", options
197
- if resp.success?
198
- entity = resp.data["entity"]
199
- @owners.push entity unless @owners.nil?
200
- return entity
201
- end
202
- nil
203
- end
204
-
205
- ##
206
- # Grants writer permission to the file.
207
- #
208
- # @param [String] entity The entity holding the permission, in one of
209
- # the following forms:
210
- #
211
- # * user-userId
212
- # * user-email
213
- # * group-groupId
214
- # * group-email
215
- # * domain-domain
216
- # * project-team-projectId
217
- # * allUsers
218
- # * allAuthenticatedUsers
219
- #
220
- # @param [Integer] generation When present, selects a specific revision
221
- # of this object. Default is the latest version.
222
- #
223
- # @example Grant access to a user by pre-pending `"user-"` to an email:
224
- # require "gcloud"
225
- #
226
- # gcloud = Gcloud.new
227
- # storage = gcloud.storage
228
- #
229
- # bucket = storage.bucket "my-bucket"
230
- #
231
- # file = bucket.file "path/to/my-file.ext"
232
- # email = "heidi@example.net"
233
- # file.acl.add_writer "user-#{email}"
234
- #
235
- # @example Grant access to a group by pre-pending `"group-"` to an email
236
- # require "gcloud"
237
- #
238
- # gcloud = Gcloud.new
239
- # storage = gcloud.storage
240
- #
241
- # bucket = storage.bucket "my-bucket"
242
- #
243
- # file = bucket.file "path/to/my-file.ext"
244
- # email = "authors@example.net"
245
- # file.acl.add_writer "group-#{email}"
246
- #
247
- def add_writer entity, generation: nil
248
- options = { generation: generation }
249
- resp = @connection.insert_file_acl @bucket, @file, entity,
250
- "WRITER", options
251
- if resp.success?
252
- entity = resp.data["entity"]
253
- @writers.push entity unless @writers.nil?
254
- return entity
255
- end
256
- nil
176
+ gapi = @service.insert_file_acl @bucket, @file, entity, "OWNER",
177
+ options
178
+ entity = gapi.entity
179
+ @owners.push entity unless @owners.nil?
180
+ entity
257
181
  end
258
182
 
259
183
  ##
@@ -300,14 +224,11 @@ module Gcloud
300
224
  #
301
225
  def add_reader entity, generation: nil
302
226
  options = { generation: generation }
303
- resp = @connection.insert_file_acl @bucket, @file, entity,
304
- "READER", options
305
- if resp.success?
306
- entity = resp.data["entity"]
307
- @readers.push entity unless @readers.nil?
308
- return entity
309
- end
310
- nil
227
+ gapi = @service.insert_file_acl @bucket, @file, entity, "READER",
228
+ options
229
+ entity = gapi.entity
230
+ @readers.push entity unless @readers.nil?
231
+ entity
311
232
  end
312
233
 
313
234
  ##
@@ -342,14 +263,10 @@ module Gcloud
342
263
  #
343
264
  def delete entity, generation: nil
344
265
  options = { generation: generation }
345
- resp = @connection.delete_file_acl @bucket, @file, entity, options
346
- if resp.success?
347
- @owners.delete entity unless @owners.nil?
348
- @writers.delete entity unless @writers.nil?
349
- @readers.delete entity unless @readers.nil?
350
- return true
351
- end
352
- false
266
+ @service.delete_file_acl @bucket, @file, entity, options
267
+ @owners.delete entity unless @owners.nil?
268
+ @readers.delete entity unless @readers.nil?
269
+ true
353
270
  end
354
271
 
355
272
  # @private
@@ -486,23 +403,20 @@ module Gcloud
486
403
 
487
404
  def clear!
488
405
  @owners = nil
489
- @writers = nil
490
406
  @readers = nil
491
407
  self
492
408
  end
493
409
 
494
410
  def update_predefined_acl! acl_role
495
- resp = @connection.patch_file @bucket, @file,
496
- predefined_acl: acl_role,
497
- acl: []
498
-
499
- return clear! if resp.success?
500
- fail Gcloud::Storage::ApiError.from_response(resp)
411
+ patched_file = Google::Apis::StorageV1::Object.new acl: nil
412
+ @service.patch_file \
413
+ @bucket, @file, patched_file, predefined_acl: acl_role
414
+ clear!
501
415
  end
502
416
 
503
417
  def entities_from_acls acls, role
504
- selected = acls.select { |acl| acl["role"] == role }
505
- entities = selected.map { |acl| acl["entity"] }
418
+ selected = acls.select { |acl| acl.role == role }
419
+ entities = selected.map(&:entity)
506
420
  entities
507
421
  end
508
422
  end
@@ -77,15 +77,14 @@ module Gcloud
77
77
  #
78
78
  def next
79
79
  return nil unless next?
80
- ensure_connection!
80
+ ensure_service!
81
81
  options = {
82
82
  prefix: @prefix, delimiter: @delimiter, token: @token, max: @max,
83
83
  versions: @versions
84
84
  }
85
- resp = @connection.list_files @bucket, options
86
- fail ApiError.from_response(resp) unless resp.success?
87
- File::List.from_response resp, @connection, @bucket, @prefix,
88
- @delimiter, @max, @versions
85
+ gapi = @service.list_files @bucket, options
86
+ File::List.from_gapi gapi, @service, @bucket, @prefix,
87
+ @delimiter, @max, @versions
89
88
  end
90
89
 
91
90
  ##
@@ -161,29 +160,30 @@ module Gcloud
161
160
  end
162
161
 
163
162
  ##
164
- # @private New File::List from a response object.
165
- def self.from_response resp, conn, bucket = nil, prefix = nil,
166
- delimiter = nil, max = nil, versions = nil
167
- files = new(Array(resp.data["items"]).map do |gapi_object|
168
- File.from_gapi gapi_object, conn
163
+ # @private New File::List from a Google API Client
164
+ # Google::Apis::StorageV1::Objects object.
165
+ def self.from_gapi gapi_list, service, bucket = nil, prefix = nil,
166
+ delimiter = nil, max = nil, versions = nil
167
+ files = new(Array(gapi_list.items).map do |gapi_object|
168
+ File.from_gapi gapi_object, service
169
169
  end)
170
- files.instance_variable_set "@token", resp.data["nextPageToken"]
171
- files.instance_variable_set "@prefixes", Array(resp.data["prefixes"])
172
- files.instance_variable_set "@connection", conn
173
- files.instance_variable_set "@bucket", bucket
174
- files.instance_variable_set "@prefix", prefix
175
- files.instance_variable_set "@delimiter", delimiter
176
- files.instance_variable_set "@max", max
177
- files.instance_variable_set "@versions", versions
170
+ files.instance_variable_set :@token, gapi_list.next_page_token
171
+ files.instance_variable_set :@prefixes, Array(gapi_list.prefixes)
172
+ files.instance_variable_set :@service, service
173
+ files.instance_variable_set :@bucket, bucket
174
+ files.instance_variable_set :@prefix, prefix
175
+ files.instance_variable_set :@delimiter, delimiter
176
+ files.instance_variable_set :@max, max
177
+ files.instance_variable_set :@versions, versions
178
178
  files
179
179
  end
180
180
 
181
181
  protected
182
182
 
183
183
  ##
184
- # Raise an error unless an active connection is available.
185
- def ensure_connection!
186
- fail "Must have active connection" unless @connection
184
+ # Raise an error unless an active service is available.
185
+ def ensure_service!
186
+ fail "Must have active connection" unless @service
187
187
  end
188
188
  end
189
189
  end
@@ -15,7 +15,7 @@
15
15
 
16
16
  require "gcloud/gce"
17
17
  require "gcloud/storage/errors"
18
- require "gcloud/storage/connection"
18
+ require "gcloud/storage/service"
19
19
  require "gcloud/storage/credentials"
20
20
  require "gcloud/storage/bucket"
21
21
  require "gcloud/storage/bucket/cors"
@@ -48,17 +48,15 @@ module Gcloud
48
48
  #
49
49
  class Project
50
50
  ##
51
- # @private The Connection object.
52
- attr_accessor :connection
51
+ # @private The Service object.
52
+ attr_accessor :service
53
53
 
54
54
  ##
55
55
  # @private Creates a new Project instance.
56
56
  #
57
57
  # See {Gcloud#storage}
58
- def initialize project, credentials
59
- project = project.to_s # Always cast to a string
60
- fail ArgumentError, "project is missing" if project.empty?
61
- @connection = Connection.new project, credentials
58
+ def initialize service
59
+ @service = service
62
60
  end
63
61
 
64
62
  ##
@@ -74,7 +72,7 @@ module Gcloud
74
72
  # storage.project #=> "my-todo-project"
75
73
  #
76
74
  def project
77
- connection.project
75
+ service.project
78
76
  end
79
77
 
80
78
  ##
@@ -133,12 +131,8 @@ module Gcloud
133
131
  #
134
132
  def buckets prefix: nil, token: nil, max: nil
135
133
  options = { prefix: prefix, token: token, max: max }
136
- resp = connection.list_buckets options
137
- if resp.success?
138
- Bucket::List.from_response resp, connection, prefix, max
139
- else
140
- fail ApiError.from_response(resp)
141
- end
134
+ gapi = service.list_buckets options
135
+ Bucket::List.from_gapi gapi, service, prefix, max
142
136
  end
143
137
  alias_method :find_buckets, :buckets
144
138
 
@@ -160,13 +154,10 @@ module Gcloud
160
154
  # puts bucket.name
161
155
  #
162
156
  def bucket bucket_name
163
- resp = connection.get_bucket bucket_name
164
- if resp.success?
165
- Bucket.from_gapi resp.data, connection
166
- else
167
- return nil if resp.data["error"]["code"] == 404
168
- fail ApiError.from_response(resp)
169
- end
157
+ gapi = service.get_bucket bucket_name
158
+ Bucket.from_gapi gapi, service
159
+ rescue Gcloud::NotFoundError
160
+ nil
170
161
  end
171
162
  alias_method :find_bucket, :bucket
172
163
 
@@ -176,7 +167,7 @@ module Gcloud
176
167
  # bucket. See {Bucket::Cors} for details.
177
168
  #
178
169
  # The API call to create the bucket may be retried under certain
179
- # conditions. See {Gcloud::Backoff} to control this behavior.
170
+ # conditions. See {Gcloud#storage} to control this behavior.
180
171
  #
181
172
  # You can pass [website
182
173
  # settings](https://cloud.google.com/storage/docs/website-configuration)
@@ -221,10 +212,6 @@ module Gcloud
221
212
  # and project team members get access according to their roles.
222
213
  # * `public`, `public_read`, `publicRead` - File owner gets OWNER
223
214
  # access, and allUsers get READER access.
224
- # @param [String] cors The CORS rules for the bucket. Accepts an array of
225
- # hashes containing the attributes specified for the [resource
226
- # description of
227
- # cors](https://cloud.google.com/storage/docs/json_api/v1/buckets#cors).
228
215
  # @param [String] location The location of the bucket. Object data for
229
216
  # objects in the bucket resides in physical storage within this region.
230
217
  # Possible values include `ASIA`, `EU`, and `US`. (See the [developer's
@@ -260,8 +247,8 @@ module Gcloud
260
247
  # does not exist. For more information, see [How to Host a Static
261
248
  # Website
262
249
  # ](https://cloud.google.com/storage/docs/website-configuration#step4).
263
- # @yield [cors] a block for setting CORS rules
264
- # @yieldparam [Bucket::Cors] cors the object accepting CORS rules
250
+ # @yield [bucket] a block for configuring the bucket before it is created
251
+ # @yieldparam [Bucket] cors the bucket object to be configured
265
252
  #
266
253
  # @return [Gcloud::Storage::Bucket]
267
254
  #
@@ -273,38 +260,42 @@ module Gcloud
273
260
  #
274
261
  # bucket = storage.create_bucket "my-bucket"
275
262
  #
276
- # @example Add CORS rules in a block:
263
+ # @example Configure the bucket in a block:
277
264
  # require "gcloud"
278
265
  #
279
266
  # gcloud = Gcloud.new
280
267
  # storage = gcloud.storage
281
268
  #
282
- # options = {
283
- # website_main: "index.html"
284
- # website_404: "not_found.html"
285
- # }
286
- # bucket = storage.create_bucket "my-bucket", options do |c|
287
- # c.add_rule ["http://example.org", "https://example.org"],
288
- # "*",
289
- # response_headers: ["X-My-Custom-Header"],
290
- # max_age: 300
269
+ # bucket = storage.create_bucket "my-bucket" do |b|
270
+ # b.website_main = "index.html"
271
+ # b.website_404 = "not_found.html"
272
+ # b.cors.add_rule ["http://example.org", "https://example.org"],
273
+ # "*",
274
+ # response_headers: ["X-My-Custom-Header"],
275
+ # max_age: 300
291
276
  # end
292
277
  #
293
- def create_bucket bucket_name, acl: nil, default_acl: nil, cors: nil,
294
- location: nil, logging_bucket: nil, logging_prefix: nil,
295
- storage_class: nil, versioning: nil, website_main: nil,
296
- website_404: nil
297
- opts = { acl: acl_rule(acl), default_acl: acl_rule(default_acl),
298
- cors: cors, location: location, logging_bucket: logging_bucket,
299
- logging_prefix: logging_prefix, storage_class: storage_class,
300
- versioning: versioning, website_main: website_main,
301
- website_404: website_404 }
302
- if block_given?
303
- cors_builder = Bucket::Cors.new
304
- yield cors_builder
305
- opts[:cors] = cors_builder if cors_builder.changed?
278
+ def create_bucket bucket_name, acl: nil, default_acl: nil,
279
+ location: nil, storage_class: nil, logging_bucket: nil,
280
+ logging_prefix: nil, website_main: nil,
281
+ website_404: nil, versioning: nil
282
+ new_bucket = Google::Apis::StorageV1::Bucket.new({
283
+ name: bucket_name,
284
+ location: location,
285
+ storage_class: storage_class_for(storage_class)
286
+ }.delete_if { |_, v| v.nil? })
287
+ updater = Bucket::Updater.new(new_bucket).tap do |b|
288
+ b.logging_bucket = logging_bucket unless logging_bucket.nil?
289
+ b.logging_prefix = logging_prefix unless logging_prefix.nil?
290
+ b.website_main = website_main unless website_main.nil?
291
+ b.website_404 = website_404 unless website_404.nil?
292
+ b.versioning = versioning unless versioning.nil?
306
293
  end
307
- insert_bucket bucket_name, opts
294
+ yield updater if block_given?
295
+ updater.check_for_mutable_cors!
296
+ gapi = service.insert_bucket \
297
+ new_bucket, acl: acl_rule(acl), default_acl: acl_rule(default_acl)
298
+ Bucket.from_gapi gapi, service
308
299
  end
309
300
 
310
301
  protected
@@ -313,13 +304,12 @@ module Gcloud
313
304
  Bucket::Acl.predefined_rule_for option_name
314
305
  end
315
306
 
316
- def insert_bucket bucket_name, options
317
- resp = connection.insert_bucket bucket_name, options
318
- if resp.success?
319
- Bucket.from_gapi resp.data, connection
320
- else
321
- fail ApiError.from_response(resp)
322
- end
307
+ def storage_class_for str
308
+ { "durable_reduced_availability" => "DURABLE_REDUCED_AVAILABILITY",
309
+ "dra" => "DURABLE_REDUCED_AVAILABILITY",
310
+ "durable" => "DURABLE_REDUCED_AVAILABILITY",
311
+ "nearline" => "NEARLINE",
312
+ "standard" => "STANDARD" }[str.to_s.downcase]
323
313
  end
324
314
  end
325
315
  end
@@ -0,0 +1,347 @@
1
+ # Copyright 2014 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
+
16
+ require "gcloud/version"
17
+ require "gcloud/backoff"
18
+ require "google/apis/storage_v1"
19
+ require "digest"
20
+ require "mime/types"
21
+ require "pathname"
22
+
23
+ module Gcloud
24
+ module Storage
25
+ ##
26
+ # @private Represents the connection to Storage,
27
+ # as well as expose the API calls.
28
+ class Service
29
+ ##
30
+ # Alias to the Google Client API module
31
+ API = Google::Apis::StorageV1
32
+
33
+ # @private
34
+ attr_accessor :project
35
+
36
+ # @private
37
+ attr_accessor :credentials
38
+
39
+ ##
40
+ # Creates a new Service instance.
41
+ def initialize project, credentials, retries: nil, timeout: nil
42
+ @project = project
43
+ @credentials = credentials
44
+ @credentials = credentials
45
+ @service = API::StorageService.new
46
+ @service.client_options.application_name = "gcloud-ruby"
47
+ @service.client_options.application_version = Gcloud::VERSION
48
+ @service.request_options.retries = retries || 3
49
+ @service.request_options.timeout_sec = timeout if timeout
50
+ @service.authorization = @credentials.client
51
+ end
52
+
53
+ def service
54
+ return mocked_service if mocked_service
55
+ @service
56
+ end
57
+ attr_accessor :mocked_service
58
+
59
+ ##
60
+ # Retrieves a list of buckets for the given project.
61
+ def list_buckets prefix: nil, token: nil, max: nil
62
+ service.list_buckets @project, prefix: prefix, page_token: token,
63
+ max_results: max
64
+ rescue Google::Apis::Error => e
65
+ raise Gcloud::Error.from_error(e)
66
+ end
67
+
68
+ ##
69
+ # Retrieves bucket by name.
70
+ # Returns Google::Apis::StorageV1::Bucket.
71
+ def get_bucket bucket_name
72
+ service.get_bucket bucket_name
73
+ rescue Google::Apis::Error => e
74
+ raise Gcloud::Error.from_error(e)
75
+ end
76
+
77
+ ##
78
+ # Creates a new bucket.
79
+ # Returns Google::Apis::StorageV1::Bucket.
80
+ def insert_bucket bucket_gapi, options = {}
81
+ service.insert_bucket \
82
+ @project, bucket_gapi,
83
+ predefined_acl: options[:acl],
84
+ predefined_default_object_acl: options[:default_acl]
85
+ rescue Google::Apis::Error => e
86
+ raise Gcloud::Error.from_error(e)
87
+ end
88
+
89
+ ##
90
+ # Updates a bucket, including its ACL metadata.
91
+ def patch_bucket bucket_name, bucket_gapi = nil, predefined_acl: nil,
92
+ predefined_default_acl: nil
93
+ bucket_gapi ||= Google::Apis::StorageV1::Bucket.new
94
+ bucket_gapi.acl = nil if predefined_acl
95
+ bucket_gapi.default_object_acl = nil if predefined_default_acl
96
+
97
+ service.patch_bucket \
98
+ bucket_name, bucket_gapi,
99
+ predefined_acl: predefined_acl,
100
+ predefined_default_object_acl: predefined_default_acl
101
+ rescue Google::Apis::Error => e
102
+ raise Gcloud::Error.from_error(e)
103
+ end
104
+
105
+ ##
106
+ # Permanently deletes an empty bucket.
107
+ def delete_bucket bucket_name
108
+ service.delete_bucket bucket_name
109
+ rescue Google::Apis::Error => e
110
+ raise Gcloud::Error.from_error(e)
111
+ end
112
+
113
+ ##
114
+ # Retrieves a list of ACLs for the given bucket.
115
+ def list_bucket_acls bucket_name
116
+ service.list_bucket_access_controls bucket_name
117
+ rescue Google::Apis::Error => e
118
+ raise Gcloud::Error.from_error(e)
119
+ end
120
+
121
+ ##
122
+ # Creates a new bucket ACL.
123
+ def insert_bucket_acl bucket_name, entity, role
124
+ new_acl = Google::Apis::StorageV1::BucketAccessControl.new \
125
+ entity: entity, role: role
126
+ service.insert_bucket_access_control bucket_name, new_acl
127
+ rescue Google::Apis::Error => e
128
+ raise Gcloud::Error.from_error(e)
129
+ end
130
+
131
+ ##
132
+ # Permanently deletes a bucket ACL.
133
+ def delete_bucket_acl bucket_name, entity
134
+ service.delete_bucket_access_control bucket_name, entity
135
+ rescue Google::Apis::Error => e
136
+ raise Gcloud::Error.from_error(e)
137
+ end
138
+
139
+ ##
140
+ # Retrieves a list of default ACLs for the given bucket.
141
+ def list_default_acls bucket_name
142
+ service.list_default_object_access_controls bucket_name
143
+ rescue Google::Apis::Error => e
144
+ raise Gcloud::Error.from_error(e)
145
+ end
146
+
147
+ ##
148
+ # Creates a new default ACL.
149
+ def insert_default_acl bucket_name, entity, role
150
+ new_acl = Google::Apis::StorageV1::ObjectAccessControl.new \
151
+ entity: entity, role: role
152
+ service.insert_default_object_access_control bucket_name, new_acl
153
+ rescue Google::Apis::Error => e
154
+ raise Gcloud::Error.from_error(e)
155
+ end
156
+
157
+ ##
158
+ # Permanently deletes a default ACL.
159
+ def delete_default_acl bucket_name, entity
160
+ service.delete_default_object_access_control bucket_name, entity
161
+ rescue Google::Apis::Error => e
162
+ raise Gcloud::Error.from_error(e)
163
+ end
164
+
165
+ ##
166
+ # Retrieves a list of files matching the criteria.
167
+ def list_files bucket_name, options = {}
168
+ service.list_objects \
169
+ bucket_name, delimiter: options[:delimiter],
170
+ max_results: options[:max], page_token: options[:token],
171
+ prefix: options[:prefix], versions: options[:versions]
172
+ rescue Google::Apis::Error => e
173
+ raise Gcloud::Error.from_error(e)
174
+ end
175
+
176
+ ##
177
+ # Inserts a new file for the given bucket
178
+ def insert_file bucket_name, source, path = nil, acl: nil,
179
+ cache_control: nil, content_disposition: nil,
180
+ content_encoding: nil, content_language: nil,
181
+ content_type: nil, crc32c: nil, md5: nil, metadata: nil,
182
+ key: nil, key_sha256: nil
183
+ file_obj = Google::Apis::StorageV1::Object.new \
184
+ cache_control: cache_control, content_type: content_type,
185
+ content_disposition: content_disposition, md5_hash: md5,
186
+ content_encoding: content_encoding, crc32c: crc32c,
187
+ content_language: content_language, metadata: metadata
188
+ content_type ||= mime_type_for(Pathname(source).to_path)
189
+ service.insert_object \
190
+ bucket_name, file_obj,
191
+ name: path, predefined_acl: acl, upload_source: source,
192
+ content_encoding: content_encoding, content_type: content_type,
193
+ options: key_options(key: key, key_sha256: key_sha256)
194
+ rescue Google::Apis::Error => e
195
+ raise Gcloud::Error.from_error(e)
196
+ end
197
+
198
+ ##
199
+ # Retrieves an object or its metadata.
200
+ def get_file bucket_name, file_path, generation: nil, key: nil,
201
+ key_sha256: nil
202
+ service.get_object \
203
+ bucket_name, file_path,
204
+ generation: generation,
205
+ options: key_options(key: key, key_sha256: key_sha256)
206
+ rescue Google::Apis::Error => e
207
+ raise Gcloud::Error.from_error(e)
208
+ end
209
+
210
+ ## Copy a file from source bucket/object to a
211
+ # destination bucket/object.
212
+ def copy_file source_bucket_name, source_file_path,
213
+ destination_bucket_name, destination_file_path, options = {}
214
+ service.copy_object \
215
+ source_bucket_name, source_file_path,
216
+ destination_bucket_name, destination_file_path,
217
+ destination_predefined_acl: options[:acl],
218
+ source_generation: options[:generation],
219
+ options: key_options(key: options[:key],
220
+ key_sha256: options[:key_sha256])
221
+ rescue Google::Apis::Error => e
222
+ raise Gcloud::Error.from_error(e)
223
+ end
224
+
225
+ ##
226
+ # Download contents of a file.
227
+ def download_file bucket_name, file_path, target_path, generation: nil,
228
+ key: nil, key_sha256: nil
229
+ service.get_object \
230
+ bucket_name, file_path,
231
+ download_dest: target_path, generation: generation,
232
+ options: key_options(key: key, key_sha256: key_sha256)
233
+ rescue Google::Apis::Error => e
234
+ raise Gcloud::Error.from_error(e)
235
+ end
236
+
237
+ ##
238
+ # Updates a file's metadata.
239
+ def patch_file bucket_name, file_path, file_gapi = nil,
240
+ predefined_acl: nil
241
+ file_gapi ||= Google::Apis::StorageV1::Object.new
242
+ service.patch_object \
243
+ bucket_name, file_path, file_gapi,
244
+ predefined_acl: predefined_acl
245
+ rescue Google::Apis::Error => e
246
+ raise Gcloud::Error.from_error(e)
247
+ end
248
+
249
+ ##
250
+ # Permanently deletes a file.
251
+ def delete_file bucket_name, file_path
252
+ service.delete_object bucket_name, file_path
253
+ rescue Google::Apis::Error => e
254
+ raise Gcloud::Error.from_error(e)
255
+ end
256
+
257
+ ##
258
+ # Retrieves a list of ACLs for the given file.
259
+ def list_file_acls bucket_name, file_name
260
+ service.list_object_access_controls bucket_name, file_name
261
+ rescue Google::Apis::Error => e
262
+ raise Gcloud::Error.from_error(e)
263
+ end
264
+
265
+ ##
266
+ # Creates a new file ACL.
267
+ def insert_file_acl bucket_name, file_name, entity, role, options = {}
268
+ new_acl = Google::Apis::StorageV1::ObjectAccessControl.new \
269
+ entity: entity, role: role
270
+ service.insert_object_access_control \
271
+ bucket_name, file_name, new_acl, generation: options[:generation]
272
+ rescue Google::Apis::Error => e
273
+ raise Gcloud::Error.from_error(e)
274
+ end
275
+
276
+ ##
277
+ # Permanently deletes a file ACL.
278
+ def delete_file_acl bucket_name, file_name, entity, options = {}
279
+ service.delete_object_access_control \
280
+ bucket_name, file_name, entity, generation: options[:generation]
281
+ rescue Google::Apis::Error => e
282
+ raise Gcloud::Error.from_error(e)
283
+ end
284
+
285
+ ##
286
+ # Retrieves the mime-type for a file path.
287
+ # An empty string is returned if no mime-type can be found.
288
+ def mime_type_for path
289
+ MIME::Types.of(path).first.to_s
290
+ end
291
+
292
+ # @private
293
+ def inspect
294
+ "#{self.class}(#{@project})"
295
+ end
296
+
297
+ protected
298
+
299
+ def key_options key: nil, key_sha256: nil
300
+ options = {}
301
+ if key
302
+ headers = {}
303
+ headers["x-goog-encryption-algorithm"] = "AES256"
304
+ headers["x-goog-encryption-key"] = Base64.strict_encode64 key
305
+ key_sha256 ||= Digest::SHA256.digest key
306
+ headers["x-goog-encryption-key-sha256"] = \
307
+ Base64.strict_encode64 key_sha256
308
+ options[:header] = headers
309
+ end
310
+ options
311
+ end
312
+
313
+ def patch_bucket_request options = {}
314
+ {
315
+ "cors" => options[:cors],
316
+ "logging" => logging_config(options),
317
+ "versioning" => versioning_config(options[:versioning]),
318
+ "website" => website_config(options),
319
+ "acl" => options[:acl],
320
+ "defaultObjectAcl" => options[:default_acl]
321
+ }.delete_if { |_, v| v.nil? }
322
+ end
323
+
324
+ def versioning_config enabled
325
+ { "enabled" => enabled } unless enabled.nil?
326
+ end
327
+
328
+ def logging_config options
329
+ bucket = options[:logging_bucket]
330
+ prefix = options[:logging_prefix]
331
+ {
332
+ log_bucket: bucket,
333
+ log_object_prefix: prefix
334
+ }.delete_if { |_, v| v.nil? } if bucket || prefix
335
+ end
336
+
337
+ def website_config options
338
+ website_main = options[:website_main]
339
+ website_404 = options[:website_404]
340
+ {
341
+ main_page_suffix: website_main,
342
+ not_found_page: website_404
343
+ }.delete_if { |_, v| v.nil? } if website_main || website_404
344
+ end
345
+ end
346
+ end
347
+ end