google-cloud-storage 1.37.0 → 1.54.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -15,6 +15,7 @@
15
15
 
16
16
  require "google/cloud/storage/version"
17
17
  require "google/apis/storage_v1"
18
+ require "google/cloud/config"
18
19
  require "digest"
19
20
  require "mini_mime"
20
21
  require "pathname"
@@ -36,6 +37,11 @@ module Google
36
37
  # @private
37
38
  attr_accessor :credentials
38
39
 
40
+ # @private
41
+ def universe_domain
42
+ service.universe_domain
43
+ end
44
+
39
45
  ##
40
46
  # Creates a new Service instance.
41
47
  # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
@@ -43,7 +49,8 @@ module Google
43
49
  timeout: nil, open_timeout: nil, read_timeout: nil,
44
50
  send_timeout: nil, host: nil, quota_project: nil,
45
51
  max_elapsed_time: nil, base_interval: nil, max_interval: nil,
46
- multiplier: nil
52
+ multiplier: nil, upload_chunk_size: nil, universe_domain: nil
53
+ host ||= Google::Cloud::Storage.configure.endpoint
47
54
  @project = project
48
55
  @credentials = credentials
49
56
  @service = API::StorageService.new
@@ -64,8 +71,17 @@ module Google
64
71
  @service.request_options.base_interval = base_interval if base_interval
65
72
  @service.request_options.max_interval = max_interval if max_interval
66
73
  @service.request_options.multiplier = multiplier if multiplier
74
+ @service.request_options.add_invocation_id_header = true
75
+ @service.request_options.upload_chunk_size = upload_chunk_size if upload_chunk_size
67
76
  @service.authorization = @credentials.client if @credentials
68
77
  @service.root_url = host if host
78
+ @service.universe_domain = universe_domain || Google::Cloud::Storage.configure.universe_domain
79
+ begin
80
+ @service.verify_universe_domain!
81
+ rescue Google::Apis::UniverseDomainError => e
82
+ # TODO: Create a Google::Cloud::Error subclass for this.
83
+ raise Google::Cloud::Error, e.message
84
+ end
69
85
  end
70
86
  # rubocop:enable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
71
87
 
@@ -81,11 +97,11 @@ module Google
81
97
 
82
98
  ##
83
99
  # Retrieves a list of buckets for the given project.
84
- def list_buckets prefix: nil, token: nil, max: nil, user_project: nil
100
+ def list_buckets prefix: nil, token: nil, max: nil, user_project: nil, options: {}
85
101
  execute do
86
102
  service.list_buckets \
87
103
  @project, prefix: prefix, page_token: token, max_results: max,
88
- user_project: user_project(user_project)
104
+ user_project: user_project(user_project), options: options
89
105
  end
90
106
  end
91
107
 
@@ -95,12 +111,14 @@ module Google
95
111
  def get_bucket bucket_name,
96
112
  if_metageneration_match: nil,
97
113
  if_metageneration_not_match: nil,
98
- user_project: nil
114
+ user_project: nil,
115
+ options: {}
99
116
  execute do
100
117
  service.get_bucket bucket_name,
101
118
  if_metageneration_match: if_metageneration_match,
102
119
  if_metageneration_not_match: if_metageneration_not_match,
103
- user_project: user_project(user_project)
120
+ user_project: user_project(user_project),
121
+ options: options
104
122
  end
105
123
  end
106
124
 
@@ -108,13 +126,16 @@ module Google
108
126
  # Creates a new bucket.
109
127
  # Returns Google::Apis::StorageV1::Bucket.
110
128
  def insert_bucket bucket_gapi, acl: nil, default_acl: nil,
111
- user_project: nil
129
+ user_project: nil, enable_object_retention: nil,
130
+ options: {}
112
131
  execute do
113
132
  service.insert_bucket \
114
133
  @project, bucket_gapi,
115
134
  predefined_acl: acl,
116
135
  predefined_default_object_acl: default_acl,
117
- user_project: user_project(user_project)
136
+ user_project: user_project(user_project),
137
+ options: options,
138
+ enable_object_retention: enable_object_retention
118
139
  end
119
140
  end
120
141
 
@@ -126,11 +147,17 @@ module Google
126
147
  predefined_default_acl: nil,
127
148
  if_metageneration_match: nil,
128
149
  if_metageneration_not_match: nil,
129
- user_project: nil
150
+ user_project: nil,
151
+ options: {}
130
152
  bucket_gapi ||= Google::Apis::StorageV1::Bucket.new
131
153
  bucket_gapi.acl = [] if predefined_acl
132
154
  bucket_gapi.default_object_acl = [] if predefined_default_acl
133
155
 
156
+ if options[:retries].nil?
157
+ is_idempotent = retry? if_metageneration_match: if_metageneration_match
158
+ options = is_idempotent ? {} : { retries: 0 }
159
+ end
160
+
134
161
  execute do
135
162
  service.patch_bucket bucket_name,
136
163
  bucket_gapi,
@@ -138,7 +165,8 @@ module Google
138
165
  predefined_default_object_acl: predefined_default_acl,
139
166
  if_metageneration_match: if_metageneration_match,
140
167
  if_metageneration_not_match: if_metageneration_not_match,
141
- user_project: user_project(user_project)
168
+ user_project: user_project(user_project),
169
+ options: options
142
170
  end
143
171
  end
144
172
 
@@ -147,119 +175,144 @@ module Google
147
175
  def delete_bucket bucket_name,
148
176
  if_metageneration_match: nil,
149
177
  if_metageneration_not_match: nil,
150
- user_project: nil
178
+ user_project: nil,
179
+ options: {}
151
180
  execute do
152
181
  service.delete_bucket bucket_name,
153
182
  if_metageneration_match: if_metageneration_match,
154
183
  if_metageneration_not_match: if_metageneration_not_match,
155
- user_project: user_project(user_project)
184
+ user_project: user_project(user_project),
185
+ options: options
156
186
  end
157
187
  end
158
188
 
159
189
  ##
160
190
  # Locks retention policy on a bucket.
161
191
  def lock_bucket_retention_policy bucket_name, metageneration,
162
- user_project: nil
192
+ user_project: nil,
193
+ options: {}
163
194
  execute do
164
195
  service.lock_bucket_retention_policy \
165
196
  bucket_name, metageneration,
166
- user_project: user_project(user_project)
197
+ user_project: user_project(user_project),
198
+ options: options
167
199
  end
168
200
  end
169
201
 
170
202
  ##
171
203
  # Retrieves a list of ACLs for the given bucket.
172
- def list_bucket_acls bucket_name, user_project: nil
204
+ def list_bucket_acls bucket_name, user_project: nil, options: {}
173
205
  execute do
174
206
  service.list_bucket_access_controls \
175
- bucket_name, user_project: user_project(user_project)
207
+ bucket_name, user_project: user_project(user_project),
208
+ options: options
176
209
  end
177
210
  end
178
211
 
179
212
  ##
180
213
  # Creates a new bucket ACL.
181
- def insert_bucket_acl bucket_name, entity, role, user_project: nil
214
+ def insert_bucket_acl bucket_name, entity, role, user_project: nil, options: {}
182
215
  params = { entity: entity, role: role }.delete_if { |_k, v| v.nil? }
183
216
  new_acl = Google::Apis::StorageV1::BucketAccessControl.new(**params)
217
+ if options[:retries].nil?
218
+ options = options.merge({ retries: 0 })
219
+ end
184
220
  execute do
185
221
  service.insert_bucket_access_control \
186
- bucket_name, new_acl, user_project: user_project(user_project)
222
+ bucket_name, new_acl, user_project: user_project(user_project),
223
+ options: options
187
224
  end
188
225
  end
189
226
 
190
227
  ##
191
228
  # Permanently deletes a bucket ACL.
192
- def delete_bucket_acl bucket_name, entity, user_project: nil
229
+ def delete_bucket_acl bucket_name, entity, user_project: nil, options: {}
230
+ if options[:retries].nil?
231
+ options = options.merge({ retries: 0 })
232
+ end
193
233
  execute do
194
234
  service.delete_bucket_access_control \
195
- bucket_name, entity, user_project: user_project(user_project)
235
+ bucket_name, entity, user_project: user_project(user_project),
236
+ options: options
196
237
  end
197
238
  end
198
239
 
199
240
  ##
200
241
  # Retrieves a list of default ACLs for the given bucket.
201
- def list_default_acls bucket_name, user_project: nil
242
+ def list_default_acls bucket_name, user_project: nil, options: {}
202
243
  execute do
203
244
  service.list_default_object_access_controls \
204
- bucket_name, user_project: user_project(user_project)
245
+ bucket_name, user_project: user_project(user_project),
246
+ options: options
205
247
  end
206
248
  end
207
249
 
208
250
  ##
209
251
  # Creates a new default ACL.
210
- def insert_default_acl bucket_name, entity, role, user_project: nil
252
+ def insert_default_acl bucket_name, entity, role, user_project: nil, options: {}
253
+ if options[:retries].nil?
254
+ options = options.merge({ retries: 0 })
255
+ end
211
256
  param = { entity: entity, role: role }.delete_if { |_k, v| v.nil? }
212
257
  new_acl = Google::Apis::StorageV1::ObjectAccessControl.new(**param)
213
258
  execute do
214
259
  service.insert_default_object_access_control \
215
- bucket_name, new_acl, user_project: user_project(user_project)
260
+ bucket_name, new_acl, user_project: user_project(user_project),
261
+ options: options
216
262
  end
217
263
  end
218
264
 
219
265
  ##
220
266
  # Permanently deletes a default ACL.
221
- def delete_default_acl bucket_name, entity, user_project: nil
267
+ def delete_default_acl bucket_name, entity, user_project: nil, options: {}
268
+ if options[:retries].nil?
269
+ options = options.merge({ retries: 0 })
270
+ end
222
271
  execute do
223
272
  service.delete_default_object_access_control \
224
- bucket_name, entity, user_project: user_project(user_project)
273
+ bucket_name, entity, user_project: user_project(user_project),
274
+ options: options
225
275
  end
226
276
  end
227
277
 
228
278
  ##
229
279
  # Returns Google::Apis::StorageV1::Policy
230
- def get_bucket_policy bucket_name, requested_policy_version: nil, user_project: nil
280
+ def get_bucket_policy bucket_name, requested_policy_version: nil, user_project: nil,
281
+ options: {}
231
282
  # get_bucket_iam_policy(bucket, fields: nil, quota_user: nil,
232
283
  # user_ip: nil, options: nil)
233
284
  execute do
234
285
  service.get_bucket_iam_policy bucket_name, options_requested_policy_version: requested_policy_version,
235
- user_project: user_project(user_project)
286
+ user_project: user_project(user_project), options: options
236
287
  end
237
288
  end
238
289
 
239
290
  ##
240
291
  # Returns Google::Apis::StorageV1::Policy
241
- def set_bucket_policy bucket_name, new_policy, user_project: nil
292
+ def set_bucket_policy bucket_name, new_policy, user_project: nil, options: {}
242
293
  execute do
243
294
  service.set_bucket_iam_policy \
244
- bucket_name, new_policy, user_project: user_project(user_project)
295
+ bucket_name, new_policy, user_project: user_project(user_project), options: options
245
296
  end
246
297
  end
247
298
 
248
299
  ##
249
300
  # Returns Google::Apis::StorageV1::TestIamPermissionsResponse
250
- def test_bucket_permissions bucket_name, permissions, user_project: nil
301
+ def test_bucket_permissions bucket_name, permissions, user_project: nil, options: {}
251
302
  execute do
252
303
  service.test_bucket_iam_permissions \
253
- bucket_name, permissions, user_project: user_project(user_project)
304
+ bucket_name, permissions, user_project: user_project(user_project),
305
+ options: options
254
306
  end
255
307
  end
256
308
 
257
309
  ##
258
310
  # Retrieves a list of Pub/Sub notification subscriptions for a bucket.
259
- def list_notifications bucket_name, user_project: nil
311
+ def list_notifications bucket_name, user_project: nil, options: {}
260
312
  execute do
261
313
  service.list_notifications bucket_name,
262
- user_project: user_project(user_project)
314
+ user_project: user_project(user_project),
315
+ options: options
263
316
  end
264
317
  end
265
318
 
@@ -267,7 +320,7 @@ module Google
267
320
  # Creates a new Pub/Sub notification subscription for a bucket.
268
321
  def insert_notification bucket_name, topic_name, custom_attrs: nil,
269
322
  event_types: nil, prefix: nil, payload: nil,
270
- user_project: nil
323
+ user_project: nil, options: {}
271
324
  params =
272
325
  { custom_attributes: custom_attrs,
273
326
  event_types: event_types(event_types),
@@ -276,41 +329,54 @@ module Google
276
329
  topic: topic_path(topic_name) }.delete_if { |_k, v| v.nil? }
277
330
  new_notification = Google::Apis::StorageV1::Notification.new(**params)
278
331
 
332
+ if options[:retries].nil?
333
+ options = options.merge({ retries: 0 })
334
+ end
335
+
279
336
  execute do
280
337
  service.insert_notification \
281
338
  bucket_name, new_notification,
282
- user_project: user_project(user_project)
339
+ user_project: user_project(user_project),
340
+ options: options
283
341
  end
284
342
  end
285
343
 
286
344
  ##
287
345
  # Retrieves a Pub/Sub notification subscription for a bucket.
288
- def get_notification bucket_name, notification_id, user_project: nil
346
+ def get_notification bucket_name, notification_id, user_project: nil, options: {}
289
347
  execute do
290
348
  service.get_notification bucket_name, notification_id,
291
- user_project: user_project(user_project)
349
+ user_project: user_project(user_project),
350
+ options: options
292
351
  end
293
352
  end
294
353
 
295
354
  ##
296
355
  # Deletes a new Pub/Sub notification subscription for a bucket.
297
- def delete_notification bucket_name, notification_id, user_project: nil
356
+ def delete_notification bucket_name, notification_id, user_project: nil, options: {}
298
357
  execute do
299
358
  service.delete_notification bucket_name, notification_id,
300
- user_project: user_project(user_project)
359
+ user_project: user_project(user_project),
360
+ options: options
301
361
  end
302
362
  end
303
363
 
304
364
  ##
305
365
  # Retrieves a list of files matching the criteria.
306
366
  def list_files bucket_name, delimiter: nil, max: nil, token: nil,
307
- prefix: nil, versions: nil, user_project: nil
367
+ prefix: nil, versions: nil, user_project: nil,
368
+ match_glob: nil, include_folders_as_prefixes: nil,
369
+ soft_deleted: nil, options: {}
308
370
  execute do
309
371
  service.list_objects \
310
372
  bucket_name, delimiter: delimiter, max_results: max,
311
373
  page_token: token, prefix: prefix,
312
374
  versions: versions,
313
- user_project: user_project(user_project)
375
+ user_project: user_project(user_project),
376
+ match_glob: match_glob,
377
+ include_folders_as_prefixes: include_folders_as_prefixes,
378
+ soft_deleted: soft_deleted,
379
+ options: options
314
380
  end
315
381
  end
316
382
 
@@ -338,7 +404,8 @@ module Google
338
404
  if_generation_not_match: nil,
339
405
  if_metageneration_match: nil,
340
406
  if_metageneration_not_match: nil,
341
- user_project: nil
407
+ user_project: nil,
408
+ options: {}
342
409
  params = {
343
410
  cache_control: cache_control,
344
411
  content_type: content_type,
@@ -356,6 +423,13 @@ module Google
356
423
  file_obj = Google::Apis::StorageV1::Object.new(**params)
357
424
  content_type ||= mime_type_for(path || Pathname(source).to_path)
358
425
 
426
+ if options[:retries].nil?
427
+ is_idempotent = retry? if_generation_match: if_generation_match
428
+ options = is_idempotent ? key_options(key) : key_options(key).merge(retries: 0)
429
+ else
430
+ options = key_options(key).merge options
431
+ end
432
+
359
433
  execute do
360
434
  service.insert_object bucket_name,
361
435
  file_obj,
@@ -370,7 +444,7 @@ module Google
370
444
  if_metageneration_not_match: if_metageneration_not_match,
371
445
  kms_key_name: kms_key,
372
446
  user_project: user_project(user_project),
373
- options: key_options(key)
447
+ options: options
374
448
  end
375
449
  end
376
450
 
@@ -384,7 +458,9 @@ module Google
384
458
  if_metageneration_match: nil,
385
459
  if_metageneration_not_match: nil,
386
460
  key: nil,
387
- user_project: nil
461
+ user_project: nil,
462
+ soft_deleted: nil,
463
+ options: {}
388
464
  execute do
389
465
  service.get_object \
390
466
  bucket_name, file_path,
@@ -394,7 +470,8 @@ module Google
394
470
  if_metageneration_match: if_metageneration_match,
395
471
  if_metageneration_not_match: if_metageneration_not_match,
396
472
  user_project: user_project(user_project),
397
- options: key_options(key)
473
+ soft_deleted: soft_deleted,
474
+ options: key_options(key).merge(options)
398
475
  end
399
476
  end
400
477
 
@@ -419,8 +496,17 @@ module Google
419
496
  if_source_metageneration_match: nil,
420
497
  if_source_metageneration_not_match: nil,
421
498
  token: nil,
422
- user_project: nil
499
+ user_project: nil,
500
+ options: {}
423
501
  key_options = rewrite_key_options source_key, destination_key
502
+
503
+ if options[:retries].nil?
504
+ is_idempotent = retry? if_generation_match: if_generation_match
505
+ options = is_idempotent ? key_options : key_options.merge(retries: 0)
506
+ else
507
+ options = key_options.merge options
508
+ end
509
+
424
510
  execute do
425
511
  service.rewrite_object source_bucket_name,
426
512
  source_file_path,
@@ -440,7 +526,7 @@ module Google
440
526
  if_source_metageneration_not_match: if_source_metageneration_not_match,
441
527
  rewrite_token: token,
442
528
  user_project: user_project(user_project),
443
- options: key_options
529
+ options: options
444
530
  end
445
531
  end
446
532
 
@@ -455,12 +541,19 @@ module Google
455
541
  if_source_generation_match: nil,
456
542
  if_generation_match: nil,
457
543
  if_metageneration_match: nil,
458
- user_project: nil
459
-
544
+ user_project: nil,
545
+ options: {}
460
546
  source_objects = compose_file_source_objects source_files, if_source_generation_match
461
547
  compose_req = Google::Apis::StorageV1::ComposeRequest.new source_objects: source_objects,
462
548
  destination: destination_gapi
463
549
 
550
+ if options[:retries].nil?
551
+ is_idempotent = retry? if_generation_match: if_generation_match
552
+ options = is_idempotent ? key_options(key) : key_options(key).merge(retries: 0)
553
+ else
554
+ options = key_options.merge options
555
+ end
556
+
464
557
  execute do
465
558
  service.compose_object bucket_name,
466
559
  destination_path,
@@ -469,7 +562,7 @@ module Google
469
562
  if_generation_match: if_generation_match,
470
563
  if_metageneration_match: if_metageneration_match,
471
564
  user_project: user_project(user_project),
472
- options: key_options(key)
565
+ options: options
473
566
  end
474
567
  end
475
568
 
@@ -483,12 +576,12 @@ module Google
483
576
  # Apis::StorageV1::StorageService and Apis::Core::DownloadCommand at
484
577
  # the end of this file.
485
578
  def download_file bucket_name, file_path, target_path, generation: nil,
486
- key: nil, range: nil, user_project: nil
487
- options = key_options key
579
+ key: nil, range: nil, user_project: nil, options: {}
580
+ options = key_options(key).merge(options)
488
581
  options = range_header options, range
489
582
 
490
583
  execute do
491
- service.get_object_with_response \
584
+ service.get_object \
492
585
  bucket_name, file_path,
493
586
  download_dest: target_path, generation: generation,
494
587
  user_project: user_project(user_project),
@@ -507,8 +600,16 @@ module Google
507
600
  if_metageneration_match: nil,
508
601
  if_metageneration_not_match: nil,
509
602
  predefined_acl: nil,
510
- user_project: nil
603
+ user_project: nil,
604
+ override_unlocked_retention: nil,
605
+ options: {}
511
606
  file_gapi ||= Google::Apis::StorageV1::Object.new
607
+
608
+ if options[:retries].nil?
609
+ is_idempotent = retry? if_metageneration_match: if_metageneration_match
610
+ options = is_idempotent ? {} : { retries: 0 }
611
+ end
612
+
512
613
  execute do
513
614
  service.patch_object bucket_name,
514
615
  file_path,
@@ -519,7 +620,9 @@ module Google
519
620
  if_metageneration_match: if_metageneration_match,
520
621
  if_metageneration_not_match: if_metageneration_not_match,
521
622
  predefined_acl: predefined_acl,
522
- user_project: user_project(user_project)
623
+ user_project: user_project(user_project),
624
+ override_unlocked_retention: override_unlocked_retention,
625
+ options: options
523
626
  end
524
627
  end
525
628
 
@@ -532,7 +635,13 @@ module Google
532
635
  if_generation_not_match: nil,
533
636
  if_metageneration_match: nil,
534
637
  if_metageneration_not_match: nil,
535
- user_project: nil
638
+ user_project: nil,
639
+ options: {}
640
+ if options[:retries].nil?
641
+ is_idempotent = retry? generation: generation, if_generation_match: if_generation_match
642
+ options = is_idempotent ? {} : { retries: 0 }
643
+ end
644
+
536
645
  execute do
537
646
  service.delete_object bucket_name, file_path,
538
647
  generation: generation,
@@ -540,40 +649,84 @@ module Google
540
649
  if_generation_not_match: if_generation_not_match,
541
650
  if_metageneration_match: if_metageneration_match,
542
651
  if_metageneration_not_match: if_metageneration_not_match,
543
- user_project: user_project(user_project)
652
+ user_project: user_project(user_project),
653
+ options: options
654
+ end
655
+ end
656
+
657
+ ##
658
+ # Restores a soft-deleted object.
659
+ def restore_file bucket_name,
660
+ file_path,
661
+ generation,
662
+ copy_source_acl: nil,
663
+ if_generation_match: nil,
664
+ if_generation_not_match: nil,
665
+ if_metageneration_match: nil,
666
+ if_metageneration_not_match: nil,
667
+ projection: nil,
668
+ user_project: nil,
669
+ fields: nil,
670
+ options: {}
671
+ if options[:retries].nil?
672
+ is_idempotent = retry? generation: generation, if_generation_match: if_generation_match
673
+ options = is_idempotent ? {} : { retries: 0 }
674
+ end
675
+
676
+ execute do
677
+ service.restore_object bucket_name, file_path, generation,
678
+ copy_source_acl: copy_source_acl,
679
+ if_generation_match: if_generation_match,
680
+ if_generation_not_match: if_generation_not_match,
681
+ if_metageneration_match: if_metageneration_match,
682
+ if_metageneration_not_match: if_metageneration_not_match,
683
+ projection: projection,
684
+ user_project: user_project(user_project),
685
+ fields: fields,
686
+ options: options
544
687
  end
545
688
  end
546
689
 
547
690
  ##
548
691
  # Retrieves a list of ACLs for the given file.
549
- def list_file_acls bucket_name, file_name, user_project: nil
692
+ def list_file_acls bucket_name, file_name, user_project: nil, options: {}
550
693
  execute do
551
694
  service.list_object_access_controls \
552
- bucket_name, file_name, user_project: user_project(user_project)
695
+ bucket_name, file_name, user_project: user_project(user_project),
696
+ options: options
553
697
  end
554
698
  end
555
699
 
556
700
  ##
557
701
  # Creates a new file ACL.
558
702
  def insert_file_acl bucket_name, file_name, entity, role,
559
- generation: nil, user_project: nil
703
+ generation: nil, user_project: nil,
704
+ options: {}
705
+ if options[:retries].nil?
706
+ options = options.merge({ retries: 0 })
707
+ end
560
708
  params = { entity: entity, role: role }.delete_if { |_k, v| v.nil? }
561
709
  new_acl = Google::Apis::StorageV1::ObjectAccessControl.new(**params)
562
710
  execute do
563
711
  service.insert_object_access_control \
564
712
  bucket_name, file_name, new_acl,
565
- generation: generation, user_project: user_project(user_project)
713
+ generation: generation, user_project: user_project(user_project),
714
+ options: options
566
715
  end
567
716
  end
568
717
 
569
718
  ##
570
719
  # Permanently deletes a file ACL.
571
720
  def delete_file_acl bucket_name, file_name, entity, generation: nil,
572
- user_project: nil
721
+ user_project: nil, options: {}
722
+ if options[:retries].nil?
723
+ options = options.merge({ retries: 0 })
724
+ end
573
725
  execute do
574
726
  service.delete_object_access_control \
575
727
  bucket_name, file_name, entity,
576
- generation: generation, user_project: user_project(user_project)
728
+ generation: generation, user_project: user_project(user_project),
729
+ options: options
577
730
  end
578
731
  end
579
732
 
@@ -581,32 +734,41 @@ module Google
581
734
  # Creates a new HMAC key for the specified service account.
582
735
  # Returns Google::Apis::StorageV1::HmacKey.
583
736
  def create_hmac_key service_account_email, project_id: nil,
584
- user_project: nil
737
+ user_project: nil, options: {}
738
+ if options[:retries].nil?
739
+ options = options.merge({ retries: 0 })
740
+ end
741
+
585
742
  execute do
586
743
  service.create_project_hmac_key \
587
744
  (project_id || @project), service_account_email,
588
- user_project: user_project(user_project)
745
+ user_project: user_project(user_project),
746
+ options: options
589
747
  end
590
748
  end
591
749
 
592
750
  ##
593
751
  # Deletes an HMAC key. Key must be in the INACTIVE state.
594
- def delete_hmac_key access_id, project_id: nil, user_project: nil
752
+ def delete_hmac_key access_id, project_id: nil, user_project: nil,
753
+ options: {}
595
754
  execute do
596
755
  service.delete_project_hmac_key \
597
756
  (project_id || @project), access_id,
598
- user_project: user_project(user_project)
757
+ user_project: user_project(user_project),
758
+ options: options
599
759
  end
600
760
  end
601
761
 
602
762
  ##
603
763
  # Retrieves an HMAC key's metadata.
604
764
  # Returns Google::Apis::StorageV1::HmacKeyMetadata.
605
- def get_hmac_key access_id, project_id: nil, user_project: nil
765
+ def get_hmac_key access_id, project_id: nil, user_project: nil,
766
+ options: {}
606
767
  execute do
607
768
  service.get_project_hmac_key \
608
769
  (project_id || @project), access_id,
609
- user_project: user_project(user_project)
770
+ user_project: user_project(user_project),
771
+ options: options
610
772
  end
611
773
  end
612
774
 
@@ -615,14 +777,15 @@ module Google
615
777
  # Returns Google::Apis::StorageV1::HmacKeysMetadata.
616
778
  def list_hmac_keys max: nil, token: nil, service_account_email: nil,
617
779
  project_id: nil, show_deleted_keys: nil,
618
- user_project: nil
780
+ user_project: nil, options: {}
619
781
  execute do
620
782
  service.list_project_hmac_keys \
621
783
  (project_id || @project),
622
784
  max_results: max, page_token: token,
623
785
  service_account_email: service_account_email,
624
786
  show_deleted_keys: show_deleted_keys,
625
- user_project: user_project(user_project)
787
+ user_project: user_project(user_project),
788
+ options: options
626
789
  end
627
790
  end
628
791
 
@@ -631,11 +794,44 @@ module Google
631
794
  # for valid states.
632
795
  # Returns Google::Apis::StorageV1::HmacKeyMetadata.
633
796
  def update_hmac_key access_id, hmac_key_metadata_object,
634
- project_id: nil, user_project: nil
797
+ project_id: nil, user_project: nil,
798
+ options: {}
635
799
  execute do
636
800
  service.update_project_hmac_key \
637
801
  (project_id || @project), access_id, hmac_key_metadata_object,
638
- user_project: user_project(user_project)
802
+ user_project: user_project(user_project),
803
+ options: options
804
+ end
805
+ end
806
+
807
+ ##
808
+ # Updates a bucket, including its ACL metadata.
809
+ def update_bucket bucket_name,
810
+ bucket_gapi = nil,
811
+ predefined_acl: nil,
812
+ predefined_default_acl: nil,
813
+ if_metageneration_match: nil,
814
+ if_metageneration_not_match: nil,
815
+ user_project: nil,
816
+ options: {}
817
+ bucket_gapi ||= Google::Apis::StorageV1::Bucket.new
818
+ bucket_gapi.acl = [] if predefined_acl
819
+ bucket_gapi.default_object_acl = [] if predefined_default_acl
820
+
821
+ if options[:retries].nil?
822
+ is_idempotent = retry? if_metageneration_match: if_metageneration_match
823
+ options = is_idempotent ? {} : { retries: 0 }
824
+ end
825
+
826
+ execute do
827
+ service.update_bucket bucket_name,
828
+ bucket_gapi,
829
+ predefined_acl: predefined_acl,
830
+ predefined_default_object_acl: predefined_default_acl,
831
+ if_metageneration_match: if_metageneration_match,
832
+ if_metageneration_not_match: if_metageneration_not_match,
833
+ user_project: user_project(user_project),
834
+ options: options
639
835
  end
640
836
  end
641
837
 
@@ -653,6 +849,18 @@ module Google
653
849
  "#{self.class}(#{@project})"
654
850
  end
655
851
 
852
+ ##
853
+ # Add custom Google extension headers to the requests that use the signed URLs.
854
+ def add_custom_headers headers
855
+ @service.request_options.header.merge! headers
856
+ end
857
+
858
+ ##
859
+ # Add custom Google extension header to the requests that use the signed URLs.
860
+ def add_custom_header header_name, header_value
861
+ @service.request_options.header[header_name] = header_value
862
+ end
863
+
656
864
  protected
657
865
 
658
866
  def user_project user_project
@@ -771,163 +979,11 @@ module Google
771
979
  rescue Google::Apis::Error => e
772
980
  raise Google::Cloud::Error.from_error(e)
773
981
  end
774
- end
775
- end
776
- end
777
-
778
- # rubocop:disable all
779
-
780
- # @private
781
- #
782
- # IMPORTANT: These monkey-patches of Apis::StorageV1::StorageService and
783
- # Apis::Core::DownloadCommand must be verified and updated (if needed) for
784
- # every upgrade of google-api-client.
785
- #
786
- # The purpose of these modifications is to provide access to response headers
787
- # (in particular, the Content-Encoding header) for the #download_file method,
788
- # above. If google-api-client is modified to expose response headers to its
789
- # clients, this code should be removed, and #download_file updated to use that
790
- # solution instead.
791
- #
792
- module Apis
793
- # @private
794
- module StorageV1
795
- # @private
796
- class StorageService
797
- # Returns a two-element array containing:
798
- # * The `result` that is the usual return type of #get_object.
799
- # * The `http_resp` from DownloadCommand#execute_once.
800
- def get_object_with_response(bucket, object, generation: nil, if_generation_match: nil, if_generation_not_match: nil, if_metageneration_match: nil, if_metageneration_not_match: nil, projection: nil, user_project: nil, fields: nil, quota_user: nil, user_ip: nil, download_dest: nil, options: nil, &block)
801
- if download_dest.nil?
802
- command = make_simple_command(:get, 'b/{bucket}/o/{object}', options)
803
- else
804
- command = make_download_command(:get, 'b/{bucket}/o/{object}', options)
805
- command.download_dest = download_dest
806
- end
807
- command.response_representation = Google::Apis::StorageV1::Object::Representation
808
- command.response_class = Google::Apis::StorageV1::Object
809
- command.params['bucket'] = bucket unless bucket.nil?
810
- command.params['object'] = object unless object.nil?
811
- command.query['generation'] = generation unless generation.nil?
812
- command.query['ifGenerationMatch'] = if_generation_match unless if_generation_match.nil?
813
- command.query['ifGenerationNotMatch'] = if_generation_not_match unless if_generation_not_match.nil?
814
- command.query['ifMetagenerationMatch'] = if_metageneration_match unless if_metageneration_match.nil?
815
- command.query['ifMetagenerationNotMatch'] = if_metageneration_not_match unless if_metageneration_not_match.nil?
816
- command.query['projection'] = projection unless projection.nil?
817
- command.query['userProject'] = user_project unless user_project.nil?
818
- command.query['fields'] = fields unless fields.nil?
819
- command.query['quotaUser'] = quota_user unless quota_user.nil?
820
- command.query['userIp'] = user_ip unless user_ip.nil?
821
- execute_or_queue_command_with_response(command, &block)
822
- end
823
-
824
- # Returns a two-element array containing:
825
- # * The `result` that is the usual return type of #execute_or_queue_command.
826
- # * The `http_resp` from DownloadCommand#execute_once.
827
- def execute_or_queue_command_with_response(command, &callback)
828
- batch_command = current_batch
829
- if batch_command
830
- raise "Can not combine services in a batch" if Thread.current[:google_api_batch_service] != self
831
- batch_command.add(command, &callback)
832
- nil
833
- else
834
- command.execute_with_response(client, &callback)
835
- end
836
- end
837
- end
838
- end
839
- # @private
840
- module Core
841
- # @private
842
- # Streaming/resumable media download support
843
- class DownloadCommand < ApiCommand
844
- # Returns a two-element array containing:
845
- # * The `result` that is the usual return type of #execute.
846
- # * The `http_resp` from #execute_once.
847
- def execute_with_response(client)
848
- prepare!
849
- begin
850
- Retriable.retriable tries: options.retries + 1,
851
- base_interval: 1,
852
- multiplier: 2,
853
- on: RETRIABLE_ERRORS do |try|
854
- # This 2nd level retriable only catches auth errors, and supports 1 retry, which allows
855
- # auth to be re-attempted without having to retry all sorts of other failures like
856
- # NotFound, etc
857
- auth_tries = (try == 1 && authorization_refreshable? ? 2 : 1)
858
- Retriable.retriable tries: auth_tries,
859
- on: [Google::Apis::AuthorizationError, Signet::AuthorizationError],
860
- on_retry: proc { |*| refresh_authorization } do
861
- execute_once_with_response(client).tap do |result|
862
- if block_given?
863
- yield result, nil
864
- end
865
- end
866
- end
867
- end
868
- rescue => e
869
- if block_given?
870
- yield nil, e
871
- else
872
- raise e
873
- end
874
- end
875
- ensure
876
- release!
877
- end
878
-
879
- # Returns a two-element array containing:
880
- # * The `result` that is the usual return type of #execute_once.
881
- # * The `http_resp`.
882
- def execute_once_with_response(client, &block)
883
- request_header = header.dup
884
- apply_request_options(request_header)
885
- download_offset = nil
886
-
887
- if @offset > 0
888
- logger.debug { sprintf('Resuming download from offset %d', @offset) }
889
- request_header[RANGE_HEADER] = sprintf('bytes=%d-', @offset)
890
- end
891
-
892
- http_res = client.get(url.to_s,
893
- query: query,
894
- header: request_header,
895
- follow_redirect: true) do |res, chunk|
896
- status = res.http_header.status_code.to_i
897
- next unless OK_STATUS.include?(status)
898
-
899
- download_offset ||= (status == 206 ? @offset : 0)
900
- download_offset += chunk.bytesize
901
-
902
- if download_offset - chunk.bytesize == @offset
903
- next_chunk = chunk
904
- else
905
- # Oh no! Requested a chunk, but received the entire content
906
- chunk_index = @offset - (download_offset - chunk.bytesize)
907
- next_chunk = chunk.byteslice(chunk_index..-1)
908
- next if next_chunk.nil?
909
- end
910
- # logger.debug { sprintf('Writing chunk (%d bytes, %d total)', chunk.length, bytes_read) }
911
- @download_io.write(next_chunk)
912
-
913
- @offset += next_chunk.bytesize
914
- end
915
-
916
- @download_io.flush
917
982
 
918
- if @close_io_on_finish
919
- result = nil
920
- else
921
- result = @download_io
922
- end
923
- check_status(http_res.status.to_i, http_res.header, http_res.body)
924
- success([result, http_res], &block)
925
- rescue => e
926
- @download_io.flush
927
- error(e, rethrow: true, &block)
983
+ def retry? query_params
984
+ query_params.any? { |_key, val| !val.nil? }
928
985
  end
929
986
  end
930
987
  end
931
988
  end
932
- # rubocop:enable all
933
989
  end