lib/google/cloud/storage/bucket.rb in google-cloud-storage-1.1.0 vs lib/google/cloud/storage/bucket.rb in google-cloud-storage-1.2.0
- old
+ new
@@ -45,14 +45,46 @@
##
# @private The Google API Client object.
attr_accessor :gapi
##
+ # A boolean value or a project ID string for a requester pays
+ # bucket and its files. If this attribute is set to `true`, transit
+ # costs for operations on the bucket will be billed to the current
+ # project for this client. (See {Project#project} for the ID of the
+ # current project.) If this attribute is set to a project ID, and that
+ # project is authorized for the currently authenticated service account,
+ # transit costs will be billed to the that project. The default is
+ # `nil`.
+ #
+ # In general, this attribute should be set when first retrieving the
+ # bucket by providing the `user_project` option to {Project#bucket}.
+ #
+ # The requester pays feature is currently available only to whitelisted
+ # projects.
+ #
+ # See also {#requester_pays=} and {#requester_pays} to enable requester
+ # pays for a bucket.
+ #
+ # @example Setting a non-default project:
+ # require "google/cloud/storage"
+ #
+ # storage = Google::Cloud::Storage.new
+ #
+ # bucket = storage.bucket "other-project-bucket", user_project: true
+ # files = bucket.files # Billed to current project
+ # bucket.user_project = "my-other-project"
+ # files = bucket.files # Billed to "my-other-project"
+ #
+ attr_accessor :user_project
+
+ ##
# @private Create an empty Bucket object.
def initialize
@service = nil
@gapi = Google::Apis::StorageV1::Bucket.new
+ @user_project = nil
end
##
# The kind of item this is.
# For buckets, this is always `storage#bucket`.
@@ -292,17 +324,64 @@
@gapi.website.not_found_page = website_404
patch_gapi! :website
end
##
+ # Indicates that a client accessing the bucket or a file it contains
+ # must assume the transit costs related to the access. The requester
+ # must pass the `user_project` option to {Project#bucket} to indicate
+ # the project to which the access costs should be billed.
+ #
+ # This feature is currently available only to whitelisted projects.
+ #
+ # @return [Boolean, nil] Returns `true` if requester pays is enabled for
+ # the bucket.
+ #
+ def requester_pays
+ @gapi.billing.requester_pays if @gapi.billing
+ end
+ alias_method :requester_pays?, :requester_pays
+
+ ##
+ # Enables requester pays for the bucket. If enabled, a client accessing
+ # the bucket or a file it contains must assume the transit costs related
+ # to the access. The requester must pass the `user_project` option to
+ # {Project#bucket} to indicate the project to which the access costs
+ # should be billed.
+ #
+ # This feature is currently available only to whitelisted projects.
+ #
+ # @param [Boolean] new_requester_pays When set to `true`, requester pays
+ # is enabled for the bucket.
+ #
+ # @example Enable requester pays for a bucket:
+ # require "google/cloud/storage"
+ #
+ # storage = Google::Cloud::Storage.new
+ #
+ # bucket = storage.bucket "my-bucket"
+ #
+ # bucket.requester_pays = true # API call
+ # # Other projects must now provide `user_project` option when calling
+ # # Project#bucket to access this bucket.
+ #
+ def requester_pays= new_requester_pays
+ @gapi.billing ||= Google::Apis::StorageV1::Bucket::Billing.new
+ @gapi.billing.requester_pays = new_requester_pays
+ patch_gapi! :billing
+ end
+
+ ##
# Updates the bucket with changes made in the given block in a single
# PATCH request. The following attributes may be set: {#cors},
# {#logging_bucket=}, {#logging_prefix=}, {#versioning=},
- # {#website_main=}, and {#website_404=}. In addition, the #cors
- # configuration accessible in the block is completely mutable and will
- # be included in the request. (See {Bucket::Cors})
+ # {#website_main=}, {#website_404=}, and {#requester_pays=}.
#
+ # In addition, the #cors configuration accessible in the block is
+ # completely mutable and will be included in the request. (See
+ # {Bucket::Cors})
+ #
# @yield [bucket] a block yielding a delegate object for updating the
# file
#
# @example
# require "google/cloud/storage"
@@ -358,11 +437,11 @@
# bucket = storage.bucket "my-bucket"
# bucket.delete
#
def delete
ensure_service!
- service.delete_bucket name
+ service.delete_bucket name, user_project: user_project
true
end
##
# Retrieves a list of files matching the criteria.
@@ -412,20 +491,16 @@
# end
#
def files prefix: nil, delimiter: nil, token: nil, max: nil,
versions: nil
ensure_service!
- options = {
- prefix: prefix,
- delimiter: delimiter,
- token: token,
- max: max,
- versions: versions
- }
- gapi = service.list_files name, options
+ gapi = service.list_files name, prefix: prefix, delimiter: delimiter,
+ token: token, max: max,
+ versions: versions,
+ user_project: user_project
File::List.from_gapi gapi, service, name, prefix, delimiter, max,
- versions
+ versions, user_project: user_project
end
alias_method :find_files, :files
##
# Retrieves a file matching the path.
@@ -456,13 +531,14 @@
# file = bucket.file "path/to/my-file.ext"
# puts file.name
#
def file path, generation: nil, encryption_key: nil
ensure_service!
- options = { generation: generation, key: encryption_key }
- gapi = service.get_file name, path, options
- File.from_gapi gapi, service
+ gapi = service.get_file name, path, generation: generation,
+ key: encryption_key,
+ user_project: user_project
+ File.from_gapi gapi, service, user_project: user_project
rescue Google::Cloud::NotFoundError
nil
end
alias_method :find_file, :file
@@ -540,11 +616,11 @@
# @param [Symbol, String] storage_class Storage class of the file.
# Determines how the file is stored and determines the SLA and the
# cost of storage. Values include `:multi_regional`, `:regional`,
# `:nearline`, `:coldline`, `:standard`, and `:dra` (Durable Reduced
# Availability), as well as the strings returned by
- # {Bucket#storage_class}. For more information, see [Storage
+ # {#storage_class}. For more information, see [Storage
# Classes](https://cloud.google.com/storage/docs/storage-classes) and
# [Per-Object Storage
# Class](https://cloud.google.com/storage/docs/per-object-storage-class).
# The default value is the default storage class for the bucket.
# @param [String] encryption_key Optional. A customer-supplied, AES-256
@@ -599,11 +675,12 @@
options = { acl: File::Acl.predefined_rule_for(acl), md5: md5,
cache_control: cache_control, content_type: content_type,
content_disposition: content_disposition, crc32c: crc32c,
content_encoding: content_encoding, metadata: metadata,
content_language: content_language, key: encryption_key,
- storage_class: storage_class_for(storage_class) }
+ storage_class: storage_class_for(storage_class),
+ user_project: user_project }
ensure_io_or_file_exists! file
path ||= file.path if file.respond_to? :path
path ||= file if file.is_a? String
fail ArgumentError, "must provide path" if path.nil?
@@ -809,16 +886,15 @@
#
def post_object path, policy: nil, issuer: nil,
client_email: nil, signing_key: nil,
private_key: nil
ensure_service!
- options = { issuer: issuer, client_email: client_email,
- signing_key: signing_key, private_key: private_key,
- policy: policy }
signer = File::Signer.from_bucket self, path
- signer.post_object options
+ signer.post_object issuer: issuer, client_email: client_email,
+ signing_key: signing_key, private_key: private_key,
+ policy: policy
end
##
# The Bucket::Acl instance used to control access to the bucket.
#
@@ -948,11 +1024,11 @@
# end
#
def policy force: nil
warn "DEPRECATED: 'force' in Bucket#policy" unless force.nil?
ensure_service!
- gapi = service.get_bucket_policy name
+ gapi = service.get_bucket_policy name, user_project: user_project
policy = Policy.from_gapi gapi
return policy unless block_given?
yield policy
self.policy = policy
end
@@ -989,11 +1065,12 @@
#
# bucket.policy = policy # API call
#
def policy= new_policy
ensure_service!
- gapi = service.set_bucket_policy name, new_policy.to_gapi
+ gapi = service.set_bucket_policy name, new_policy.to_gapi,
+ user_project: user_project
Policy.from_gapi gapi
end
##
# Tests the specified permissions against the [Cloud
@@ -1022,11 +1099,12 @@
# permissions.include? "storage.buckets.delete" #=> false
#
def test_permissions *permissions
permissions = Array(permissions).flatten
ensure_service!
- gapi = service.test_bucket_permissions name, permissions
+ gapi = service.test_bucket_permissions name, permissions,
+ user_project: user_project
gapi.permissions
end
##
# Reloads the bucket with current data from the Storage service.
@@ -1036,14 +1114,15 @@
end
alias_method :refresh!, :reload!
##
# @private New Bucket from a Google API Client object.
- def self.from_gapi gapi, conn
+ def self.from_gapi gapi, service, user_project: nil
new.tap do |f|
f.gapi = gapi
- f.service = conn
+ f.service = service
+ f.user_project = user_project
end
end
protected
@@ -1059,10 +1138,11 @@
ensure_service!
patch_args = Hash[attributes.map do |attr|
[attr, @gapi.send(attr)]
end]
patch_gapi = Google::Apis::StorageV1::Bucket.new patch_args
- @gapi = service.patch_bucket name, patch_gapi
+ @gapi = service.patch_bucket name, patch_gapi,
+ user_project: user_project
end
##
# Raise an error if the file is not found.
def ensure_io_or_file_exists! file