gcloud 0.12.2 → 0.20.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.
- checksums.yaml +5 -13
- data/lib/gcloud.rb +27 -456
- data/lib/gcloud/bigquery.rb +2 -382
- data/lib/gcloud/datastore.rb +2 -576
- data/lib/gcloud/dns.rb +2 -321
- data/lib/gcloud/logging.rb +1 -322
- data/lib/gcloud/pubsub.rb +2 -476
- data/lib/gcloud/resource_manager.rb +2 -273
- data/lib/gcloud/storage.rb +2 -440
- data/lib/gcloud/translate.rb +1 -250
- data/lib/gcloud/version.rb +2 -2
- data/lib/gcloud/vision.rb +1 -501
- metadata +36 -332
- data/AUTHENTICATION.md +0 -75
- data/CHANGELOG.md +0 -382
- data/OVERVIEW.md +0 -259
- data/lib/gcloud/backoff.rb +0 -150
- data/lib/gcloud/bigquery/copy_job.rb +0 -97
- data/lib/gcloud/bigquery/credentials.rb +0 -29
- data/lib/gcloud/bigquery/data.rb +0 -239
- data/lib/gcloud/bigquery/dataset.rb +0 -753
- data/lib/gcloud/bigquery/dataset/access.rb +0 -507
- data/lib/gcloud/bigquery/dataset/list.rb +0 -169
- data/lib/gcloud/bigquery/extract_job.rb +0 -117
- data/lib/gcloud/bigquery/insert_response.rb +0 -81
- data/lib/gcloud/bigquery/job.rb +0 -299
- data/lib/gcloud/bigquery/job/list.rb +0 -172
- data/lib/gcloud/bigquery/load_job.rb +0 -202
- data/lib/gcloud/bigquery/project.rb +0 -475
- data/lib/gcloud/bigquery/query_data.rb +0 -234
- data/lib/gcloud/bigquery/query_job.rb +0 -137
- data/lib/gcloud/bigquery/schema.rb +0 -359
- data/lib/gcloud/bigquery/service.rb +0 -506
- data/lib/gcloud/bigquery/table.rb +0 -1141
- data/lib/gcloud/bigquery/table/list.rb +0 -180
- data/lib/gcloud/bigquery/view.rb +0 -475
- data/lib/gcloud/credentials.rb +0 -129
- data/lib/gcloud/datastore/commit.rb +0 -148
- data/lib/gcloud/datastore/credentials.rb +0 -35
- data/lib/gcloud/datastore/cursor.rb +0 -76
- data/lib/gcloud/datastore/dataset.rb +0 -660
- data/lib/gcloud/datastore/dataset/lookup_results.rb +0 -219
- data/lib/gcloud/datastore/dataset/query_results.rb +0 -386
- data/lib/gcloud/datastore/entity.rb +0 -449
- data/lib/gcloud/datastore/errors.rb +0 -41
- data/lib/gcloud/datastore/gql_query.rb +0 -211
- data/lib/gcloud/datastore/grpc_utils.rb +0 -132
- data/lib/gcloud/datastore/key.rb +0 -281
- data/lib/gcloud/datastore/properties.rb +0 -128
- data/lib/gcloud/datastore/query.rb +0 -348
- data/lib/gcloud/datastore/service.rb +0 -167
- data/lib/gcloud/datastore/transaction.rb +0 -362
- data/lib/gcloud/dns/change.rb +0 -158
- data/lib/gcloud/dns/change/list.rb +0 -173
- data/lib/gcloud/dns/credentials.rb +0 -29
- data/lib/gcloud/dns/importer.rb +0 -183
- data/lib/gcloud/dns/project.rb +0 -247
- data/lib/gcloud/dns/record.rb +0 -170
- data/lib/gcloud/dns/record/list.rb +0 -174
- data/lib/gcloud/dns/service.rb +0 -167
- data/lib/gcloud/dns/zone.rb +0 -759
- data/lib/gcloud/dns/zone/list.rb +0 -168
- data/lib/gcloud/dns/zone/transaction.rb +0 -176
- data/lib/gcloud/errors.rb +0 -206
- data/lib/gcloud/gce.rb +0 -56
- data/lib/gcloud/grpc_utils.rb +0 -87
- data/lib/gcloud/logging/credentials.rb +0 -29
- data/lib/gcloud/logging/entry.rb +0 -465
- data/lib/gcloud/logging/entry/http_request.rb +0 -141
- data/lib/gcloud/logging/entry/list.rb +0 -177
- data/lib/gcloud/logging/entry/operation.rb +0 -90
- data/lib/gcloud/logging/logger.rb +0 -307
- data/lib/gcloud/logging/metric.rb +0 -169
- data/lib/gcloud/logging/metric/list.rb +0 -172
- data/lib/gcloud/logging/project.rb +0 -642
- data/lib/gcloud/logging/resource.rb +0 -84
- data/lib/gcloud/logging/resource_descriptor.rb +0 -137
- data/lib/gcloud/logging/resource_descriptor/list.rb +0 -174
- data/lib/gcloud/logging/service.rb +0 -267
- data/lib/gcloud/logging/sink.rb +0 -227
- data/lib/gcloud/logging/sink/list.rb +0 -171
- data/lib/gcloud/pubsub/credentials.rb +0 -29
- data/lib/gcloud/pubsub/message.rb +0 -94
- data/lib/gcloud/pubsub/policy.rb +0 -204
- data/lib/gcloud/pubsub/project.rb +0 -482
- data/lib/gcloud/pubsub/received_message.rb +0 -160
- data/lib/gcloud/pubsub/service.rb +0 -334
- data/lib/gcloud/pubsub/subscription.rb +0 -565
- data/lib/gcloud/pubsub/subscription/list.rb +0 -208
- data/lib/gcloud/pubsub/topic.rb +0 -511
- data/lib/gcloud/pubsub/topic/list.rb +0 -174
- data/lib/gcloud/pubsub/topic/publisher.rb +0 -85
- data/lib/gcloud/resource_manager/credentials.rb +0 -30
- data/lib/gcloud/resource_manager/manager.rb +0 -266
- data/lib/gcloud/resource_manager/policy.rb +0 -211
- data/lib/gcloud/resource_manager/project.rb +0 -484
- data/lib/gcloud/resource_manager/project/list.rb +0 -167
- data/lib/gcloud/resource_manager/project/updater.rb +0 -130
- data/lib/gcloud/resource_manager/service.rb +0 -127
- data/lib/gcloud/storage/bucket.rb +0 -775
- data/lib/gcloud/storage/bucket/acl.rb +0 -810
- data/lib/gcloud/storage/bucket/cors.rb +0 -153
- data/lib/gcloud/storage/bucket/list.rb +0 -172
- data/lib/gcloud/storage/credentials.rb +0 -29
- data/lib/gcloud/storage/errors.rb +0 -65
- data/lib/gcloud/storage/file.rb +0 -842
- data/lib/gcloud/storage/file/acl.rb +0 -425
- data/lib/gcloud/storage/file/list.rb +0 -191
- data/lib/gcloud/storage/file/verifier.rb +0 -67
- data/lib/gcloud/storage/project.rb +0 -316
- data/lib/gcloud/storage/service.rb +0 -347
- data/lib/gcloud/translate/api.rb +0 -241
- data/lib/gcloud/translate/detection.rb +0 -137
- data/lib/gcloud/translate/language.rb +0 -69
- data/lib/gcloud/translate/service.rb +0 -80
- data/lib/gcloud/translate/translation.rb +0 -112
- data/lib/gcloud/vision/annotate.rb +0 -224
- data/lib/gcloud/vision/annotation.rb +0 -455
- data/lib/gcloud/vision/annotation/entity.rb +0 -234
- data/lib/gcloud/vision/annotation/face.rb +0 -1750
- data/lib/gcloud/vision/annotation/properties.rb +0 -245
- data/lib/gcloud/vision/annotation/safe_search.rb +0 -161
- data/lib/gcloud/vision/annotation/text.rb +0 -236
- data/lib/gcloud/vision/annotation/vertex.rb +0 -108
- data/lib/gcloud/vision/credentials.rb +0 -29
- data/lib/gcloud/vision/image.rb +0 -590
- data/lib/gcloud/vision/location.rb +0 -115
- data/lib/gcloud/vision/project.rb +0 -278
- data/lib/gcloud/vision/service.rb +0 -66
- data/lib/google/api/annotations.rb +0 -14
- data/lib/google/api/http.rb +0 -30
- data/lib/google/api/label.rb +0 -24
- data/lib/google/api/monitored_resource.rb +0 -25
- data/lib/google/datastore/v1beta3/datastore.rb +0 -115
- data/lib/google/datastore/v1beta3/datastore_services.rb +0 -33
- data/lib/google/datastore/v1beta3/entity.rb +0 -63
- data/lib/google/datastore/v1beta3/query.rb +0 -128
- data/lib/google/devtools/cloudtrace/v1/trace.rb +0 -78
- data/lib/google/devtools/cloudtrace/v1/trace_services.rb +0 -32
- data/lib/google/example/library/v1/library.rb +0 -91
- data/lib/google/example/library/v1/library_services.rb +0 -40
- data/lib/google/iam/v1/iam_policy.rb +0 -33
- data/lib/google/iam/v1/iam_policy_services.rb +0 -30
- data/lib/google/iam/v1/policy.rb +0 -25
- data/lib/google/logging/type/http_request.rb +0 -28
- data/lib/google/logging/type/log_severity.rb +0 -27
- data/lib/google/logging/v2/log_entry.rb +0 -44
- data/lib/google/logging/v2/logging.rb +0 -56
- data/lib/google/logging/v2/logging_config.rb +0 -59
- data/lib/google/logging/v2/logging_config_services.rb +0 -32
- data/lib/google/logging/v2/logging_metrics.rb +0 -51
- data/lib/google/logging/v2/logging_metrics_services.rb +0 -32
- data/lib/google/logging/v2/logging_services.rb +0 -31
- data/lib/google/longrunning/operations.rb +0 -50
- data/lib/google/longrunning/operations_services.rb +0 -29
- data/lib/google/protobuf/descriptor.rb +0 -0
- data/lib/google/pubsub/v1/pubsub.rb +0 -129
- data/lib/google/pubsub/v1/pubsub_services.rb +0 -56
- data/lib/google/pubsub/v1beta2/pubsub.rb +0 -126
- data/lib/google/pubsub/v1beta2/pubsub_services.rb +0 -56
- data/lib/google/rpc/code.rb +0 -32
- data/lib/google/rpc/error_details.rb +0 -61
- data/lib/google/rpc/status.rb +0 -19
- data/lib/google/type/color.rb +0 -20
- data/lib/google/type/date.rb +0 -18
- data/lib/google/type/dayofweek.rb +0 -23
- data/lib/google/type/latlng.rb +0 -17
- data/lib/google/type/money.rb +0 -18
- data/lib/google/type/timeofday.rb +0 -19
@@ -1,153 +0,0 @@
|
|
1
|
-
# Copyright 2015 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 "delegate"
|
17
|
-
|
18
|
-
module Gcloud
|
19
|
-
module Storage
|
20
|
-
class Bucket
|
21
|
-
##
|
22
|
-
# # Bucket Cors
|
23
|
-
#
|
24
|
-
# A special-case Array for managing the website CORS rules for a bucket.
|
25
|
-
# Accessed via {Bucket#cors}.
|
26
|
-
#
|
27
|
-
# @see https://cloud.google.com/storage/docs/cross-origin Cross-Origin
|
28
|
-
# Resource Sharing (CORS)
|
29
|
-
#
|
30
|
-
# @example
|
31
|
-
# require "gcloud"
|
32
|
-
#
|
33
|
-
# gcloud = Gcloud.new
|
34
|
-
# storage = gcloud.storage
|
35
|
-
# bucket = storage.bucket "my-todo-app"
|
36
|
-
#
|
37
|
-
# bucket = storage.bucket "my-bucket"
|
38
|
-
# bucket.cors do |c|
|
39
|
-
# # Remove the last CORS rule from the array
|
40
|
-
# c.pop
|
41
|
-
# # Remove all existing rules with the https protocol
|
42
|
-
# c.delete_if { |r| r.origin.include? "http://example.com" }
|
43
|
-
# c.add_rule ["http://example.org", "https://example.org"],
|
44
|
-
# ["GET", "POST", "DELETE"],
|
45
|
-
# response_headers: ["X-My-Custom-Header"],
|
46
|
-
# max_age: 3600
|
47
|
-
# end
|
48
|
-
#
|
49
|
-
class Cors < DelegateClass(::Array)
|
50
|
-
##
|
51
|
-
# @private
|
52
|
-
# Initialize a new CORS rules builder with existing CORS rules, if any.
|
53
|
-
def initialize rules = []
|
54
|
-
super rules
|
55
|
-
@original = to_gapi.map(&:to_json)
|
56
|
-
end
|
57
|
-
|
58
|
-
# @private
|
59
|
-
def changed?
|
60
|
-
@original != to_gapi.map(&:to_json)
|
61
|
-
end
|
62
|
-
|
63
|
-
##
|
64
|
-
# Add a CORS rule to the CORS rules for a bucket. Accepts options for
|
65
|
-
# setting preflight response headers. Preflight requests and responses
|
66
|
-
# are required if the request method and headers are not both [simple
|
67
|
-
# methods](http://www.w3.org/TR/cors/#simple-method) and [simple
|
68
|
-
# headers](http://www.w3.org/TR/cors/#simple-header).
|
69
|
-
#
|
70
|
-
# @param [String, Array<String>] origin The
|
71
|
-
# [origin](http://tools.ietf.org/html/rfc6454) or origins permitted
|
72
|
-
# for cross origin resource sharing with the bucket. Note: "*" is
|
73
|
-
# permitted in the list of origins, and means "any Origin".
|
74
|
-
# @param [String, Array<String>] methods The list of HTTP methods
|
75
|
-
# permitted in cross origin resource sharing with the bucket. (GET,
|
76
|
-
# OPTIONS, POST, etc) Note: "*" is permitted in the list of methods,
|
77
|
-
# and means "any method".
|
78
|
-
# @param [String, Array<String>] headers The list of header field names
|
79
|
-
# to send in the Access-Control-Allow-Headers header in the preflight
|
80
|
-
# response. Indicates the custom request headers that may be used in
|
81
|
-
# the actual request.
|
82
|
-
# @param [Integer] max_age The value to send in the
|
83
|
-
# Access-Control-Max-Age header in the preflight response. Indicates
|
84
|
-
# how many seconds the results of a preflight request can be cached in
|
85
|
-
# a preflight result cache. The default value is `1800` (30 minutes.)
|
86
|
-
#
|
87
|
-
# @example
|
88
|
-
# require "gcloud"
|
89
|
-
#
|
90
|
-
# gcloud = Gcloud.new
|
91
|
-
# storage = gcloud.storage
|
92
|
-
#
|
93
|
-
# bucket = storage.create_bucket "my-bucket" do |c|
|
94
|
-
# c.add_rule ["http://example.org", "https://example.org"],
|
95
|
-
# "*",
|
96
|
-
# response_headers: ["X-My-Custom-Header"],
|
97
|
-
# max_age: 300
|
98
|
-
# end
|
99
|
-
#
|
100
|
-
def add_rule origin, methods, headers: nil, max_age: nil
|
101
|
-
push Rule.new(origin, methods, headers: headers, max_age: max_age)
|
102
|
-
end
|
103
|
-
|
104
|
-
# @private
|
105
|
-
def to_gapi
|
106
|
-
map(&:to_gapi)
|
107
|
-
end
|
108
|
-
|
109
|
-
# @private
|
110
|
-
def self.from_gapi gapi_list
|
111
|
-
rules = Array(gapi_list).map { |gapi| Rule.from_gapi gapi }
|
112
|
-
new rules
|
113
|
-
end
|
114
|
-
|
115
|
-
# @private
|
116
|
-
def freeze
|
117
|
-
each(&:freeze)
|
118
|
-
super
|
119
|
-
end
|
120
|
-
|
121
|
-
class Rule
|
122
|
-
attr_accessor :origin, :methods, :headers, :max_age
|
123
|
-
|
124
|
-
def initialize origin, methods, headers: nil, max_age: nil
|
125
|
-
@origin = Array(origin)
|
126
|
-
@methods = Array(methods)
|
127
|
-
@headers = Array(headers)
|
128
|
-
@max_age = (max_age||1800)
|
129
|
-
end
|
130
|
-
|
131
|
-
def to_gapi
|
132
|
-
Google::Apis::StorageV1::Bucket::CorsConfiguration.new(
|
133
|
-
origin: Array(origin).dup, http_method: Array(methods).dup,
|
134
|
-
response_header: Array(headers).dup, max_age_seconds: max_age
|
135
|
-
)
|
136
|
-
end
|
137
|
-
|
138
|
-
def self.from_gapi gapi
|
139
|
-
new gapi.origin.dup, gapi.http_method.dup, \
|
140
|
-
headers: gapi.response_header.dup, max_age: gapi.max_age_seconds
|
141
|
-
end
|
142
|
-
|
143
|
-
def freeze
|
144
|
-
@origin.freeze
|
145
|
-
@methods.freeze
|
146
|
-
@headers.freeze
|
147
|
-
super
|
148
|
-
end
|
149
|
-
end
|
150
|
-
end
|
151
|
-
end
|
152
|
-
end
|
153
|
-
end
|
@@ -1,172 +0,0 @@
|
|
1
|
-
# Copyright 2015 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 "delegate"
|
17
|
-
|
18
|
-
module Gcloud
|
19
|
-
module Storage
|
20
|
-
class Bucket
|
21
|
-
##
|
22
|
-
# Bucket::List is a special case Array with additional values.
|
23
|
-
class List < DelegateClass(::Array)
|
24
|
-
##
|
25
|
-
# If not empty, indicates that there are more buckets
|
26
|
-
# that match the request and this value should be passed to
|
27
|
-
# the next {Gcloud::Storage::Project#buckets} to continue.
|
28
|
-
attr_accessor :token
|
29
|
-
|
30
|
-
##
|
31
|
-
# @private Create a new Bucket::List with an array of values.
|
32
|
-
def initialize arr = []
|
33
|
-
super arr
|
34
|
-
end
|
35
|
-
|
36
|
-
##
|
37
|
-
# Whether there is a next page of buckets.
|
38
|
-
#
|
39
|
-
# @return [Boolean]
|
40
|
-
#
|
41
|
-
# @example
|
42
|
-
# require "gcloud"
|
43
|
-
#
|
44
|
-
# gcloud = Gcloud.new
|
45
|
-
# storage = gcloud.storage
|
46
|
-
#
|
47
|
-
# buckets = storage.buckets
|
48
|
-
# if buckets.next?
|
49
|
-
# next_buckets = buckets.next
|
50
|
-
# end
|
51
|
-
#
|
52
|
-
def next?
|
53
|
-
!token.nil?
|
54
|
-
end
|
55
|
-
|
56
|
-
##
|
57
|
-
# Retrieve the next page of buckets.
|
58
|
-
#
|
59
|
-
# @return [Bucket::List]
|
60
|
-
#
|
61
|
-
# @example
|
62
|
-
# require "gcloud"
|
63
|
-
#
|
64
|
-
# gcloud = Gcloud.new
|
65
|
-
# storage = gcloud.storage
|
66
|
-
#
|
67
|
-
# buckets = storage.buckets
|
68
|
-
# if buckets.next?
|
69
|
-
# next_buckets = buckets.next
|
70
|
-
# end
|
71
|
-
#
|
72
|
-
def next
|
73
|
-
return nil unless next?
|
74
|
-
ensure_service!
|
75
|
-
options = { prefix: @prefix, token: @token, max: @max }
|
76
|
-
gapi = @service.list_buckets options
|
77
|
-
Bucket::List.from_gapi gapi, @service, @prefix, @max
|
78
|
-
end
|
79
|
-
|
80
|
-
##
|
81
|
-
# Retrieves all buckets by repeatedly loading {#next} until {#next?}
|
82
|
-
# returns `false`. Calls the given block once for each bucket, which is
|
83
|
-
# passed as the parameter.
|
84
|
-
#
|
85
|
-
# An Enumerator is returned if no block is given.
|
86
|
-
#
|
87
|
-
# This method may make several API calls until all buckets are
|
88
|
-
# retrieved. Be sure to use as narrow a search criteria as possible.
|
89
|
-
# Please use with caution.
|
90
|
-
#
|
91
|
-
# @param [Integer] request_limit The upper limit of API requests to make
|
92
|
-
# to load all buckets. Default is no limit.
|
93
|
-
# @yield [bucket] The block for accessing each bucket.
|
94
|
-
# @yieldparam [Bucket] bucket The bucket object.
|
95
|
-
#
|
96
|
-
# @return [Enumerator]
|
97
|
-
#
|
98
|
-
# @example Iterating each bucket by passing a block:
|
99
|
-
# require "gcloud"
|
100
|
-
#
|
101
|
-
# gcloud = Gcloud.new
|
102
|
-
# storage = gcloud.storage
|
103
|
-
#
|
104
|
-
# buckets = storage.buckets
|
105
|
-
# buckets.all do |bucket|
|
106
|
-
# puts bucket.name
|
107
|
-
# end
|
108
|
-
#
|
109
|
-
# @example Using the enumerator by not passing a block:
|
110
|
-
# require "gcloud"
|
111
|
-
#
|
112
|
-
# gcloud = Gcloud.new
|
113
|
-
# storage = gcloud.storage
|
114
|
-
#
|
115
|
-
# buckets = storage.buckets
|
116
|
-
# all_names = buckets.all.map do |bucket|
|
117
|
-
# bucket.name
|
118
|
-
# end
|
119
|
-
#
|
120
|
-
# @example Limit the number of API calls made:
|
121
|
-
# require "gcloud"
|
122
|
-
#
|
123
|
-
# gcloud = Gcloud.new
|
124
|
-
# storage = gcloud.storage
|
125
|
-
#
|
126
|
-
# buckets = storage.buckets
|
127
|
-
# buckets.all(request_limit: 10) do |bucket|
|
128
|
-
# puts bucket.name
|
129
|
-
# end
|
130
|
-
#
|
131
|
-
def all request_limit: nil
|
132
|
-
request_limit = request_limit.to_i if request_limit
|
133
|
-
unless block_given?
|
134
|
-
return enum_for(:all, request_limit: request_limit)
|
135
|
-
end
|
136
|
-
results = self
|
137
|
-
loop do
|
138
|
-
results.each { |r| yield r }
|
139
|
-
if request_limit
|
140
|
-
request_limit -= 1
|
141
|
-
break if request_limit < 0
|
142
|
-
end
|
143
|
-
break unless results.next?
|
144
|
-
results = results.next
|
145
|
-
end
|
146
|
-
end
|
147
|
-
|
148
|
-
##
|
149
|
-
# @private New Bucket::List from a Google API Client
|
150
|
-
# Google::Apis::StorageV1::Buckets object.
|
151
|
-
def self.from_gapi gapi_list, service, prefix = nil, max = nil
|
152
|
-
buckets = new(Array(gapi_list.items).map do |gapi_object|
|
153
|
-
Bucket.from_gapi gapi_object, service
|
154
|
-
end)
|
155
|
-
buckets.instance_variable_set :@token, gapi_list.next_page_token
|
156
|
-
buckets.instance_variable_set :@service, service
|
157
|
-
buckets.instance_variable_set :@prefix, prefix
|
158
|
-
buckets.instance_variable_set :@max, max
|
159
|
-
buckets
|
160
|
-
end
|
161
|
-
|
162
|
-
protected
|
163
|
-
|
164
|
-
##
|
165
|
-
# Raise an error unless an active connection is available.
|
166
|
-
def ensure_service!
|
167
|
-
fail "Must have active connection" unless @service
|
168
|
-
end
|
169
|
-
end
|
170
|
-
end
|
171
|
-
end
|
172
|
-
end
|
@@ -1,29 +0,0 @@
|
|
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/credentials"
|
17
|
-
|
18
|
-
module Gcloud
|
19
|
-
module Storage
|
20
|
-
##
|
21
|
-
# @private Represents the OAuth 2.0 signing logic for Storage.
|
22
|
-
class Credentials < Gcloud::Credentials
|
23
|
-
SCOPE = ["https://www.googleapis.com/auth/devstorage.full_control"]
|
24
|
-
PATH_ENV_VARS = %w(STORAGE_KEYFILE GCLOUD_KEYFILE GOOGLE_CLOUD_KEYFILE)
|
25
|
-
JSON_ENV_VARS = %w(STORAGE_KEYFILE_JSON GCLOUD_KEYFILE_JSON
|
26
|
-
GOOGLE_CLOUD_KEYFILE_JSON)
|
27
|
-
end
|
28
|
-
end
|
29
|
-
end
|
@@ -1,65 +0,0 @@
|
|
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/errors"
|
17
|
-
|
18
|
-
module Gcloud
|
19
|
-
module Storage
|
20
|
-
##
|
21
|
-
# # FileVerificationError
|
22
|
-
#
|
23
|
-
# Raised when a File download fails the verification.
|
24
|
-
class FileVerificationError < Gcloud::Error
|
25
|
-
##
|
26
|
-
# The type of digest that failed verification,
|
27
|
-
# :md5 or :crc32c.
|
28
|
-
attr_accessor :type
|
29
|
-
|
30
|
-
##
|
31
|
-
# The value of the digest on the gcloud-ruby file.
|
32
|
-
attr_accessor :gcloud_digest
|
33
|
-
|
34
|
-
##
|
35
|
-
# The value of the digest on the downloaded file.
|
36
|
-
attr_accessor :local_digest
|
37
|
-
|
38
|
-
# @private
|
39
|
-
def self.for_md5 gcloud_digest, local_digest
|
40
|
-
new("The downloaded file failed MD5 verification.").tap do |e|
|
41
|
-
e.type = :md5
|
42
|
-
e.gcloud_digest = gcloud_digest
|
43
|
-
e.local_digest = local_digest
|
44
|
-
end
|
45
|
-
end
|
46
|
-
|
47
|
-
# @private
|
48
|
-
def self.for_crc32c gcloud_digest, local_digest
|
49
|
-
new("The downloaded file failed CRC32c verification.").tap do |e|
|
50
|
-
e.type = :crc32c
|
51
|
-
e.gcloud_digest = gcloud_digest
|
52
|
-
e.local_digest = local_digest
|
53
|
-
end
|
54
|
-
end
|
55
|
-
end
|
56
|
-
|
57
|
-
##
|
58
|
-
# # SignedUrlUnavailable Error
|
59
|
-
#
|
60
|
-
# This is raised when File#signed_url is unable to generate a URL due to
|
61
|
-
# missing credentials needed to create the URL.
|
62
|
-
class SignedUrlUnavailable < Gcloud::Error
|
63
|
-
end
|
64
|
-
end
|
65
|
-
end
|
data/lib/gcloud/storage/file.rb
DELETED
@@ -1,842 +0,0 @@
|
|
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/storage/file/acl"
|
17
|
-
require "gcloud/storage/file/list"
|
18
|
-
require "gcloud/storage/file/verifier"
|
19
|
-
|
20
|
-
module Gcloud
|
21
|
-
module Storage
|
22
|
-
##
|
23
|
-
# # File
|
24
|
-
#
|
25
|
-
# Represents a File
|
26
|
-
# ([Object](https://cloud.google.com/storage/docs/json_api/v1/objects)) that
|
27
|
-
# belongs to a {Bucket}. Files (Objects) are
|
28
|
-
# the individual pieces of data that you store in Google Cloud Storage. A
|
29
|
-
# file can be up to 5 TB in size. Files have two components:
|
30
|
-
# data and metadata. The data component is the data from an external file or
|
31
|
-
# other data source that you want to store in Google Cloud Storage. The
|
32
|
-
# metadata component is a collection of name-value pairs that describe
|
33
|
-
# various qualities of the data.
|
34
|
-
#
|
35
|
-
# @see https://cloud.google.com/storage/docs/concepts-techniques Concepts
|
36
|
-
# and Techniques
|
37
|
-
#
|
38
|
-
# @example
|
39
|
-
# require "gcloud"
|
40
|
-
#
|
41
|
-
# gcloud = Gcloud.new
|
42
|
-
# storage = gcloud.storage
|
43
|
-
#
|
44
|
-
# bucket = storage.bucket "my-bucket"
|
45
|
-
#
|
46
|
-
# file = bucket.file "path/to/my-file.ext"
|
47
|
-
# file.download "path/to/downloaded/file.ext"
|
48
|
-
#
|
49
|
-
class File
|
50
|
-
##
|
51
|
-
# @private The Connection object.
|
52
|
-
attr_accessor :service
|
53
|
-
|
54
|
-
##
|
55
|
-
# @private The Google API Client object.
|
56
|
-
attr_accessor :gapi
|
57
|
-
|
58
|
-
##
|
59
|
-
# @private Create an empty File object.
|
60
|
-
def initialize
|
61
|
-
@service = nil
|
62
|
-
@gapi = Google::Apis::StorageV1::Object.new
|
63
|
-
end
|
64
|
-
|
65
|
-
##
|
66
|
-
# The kind of item this is.
|
67
|
-
# For files, this is always storage#object.
|
68
|
-
def kind
|
69
|
-
@gapi.kind
|
70
|
-
end
|
71
|
-
|
72
|
-
##
|
73
|
-
# The ID of the file.
|
74
|
-
def id
|
75
|
-
@gapi.id
|
76
|
-
end
|
77
|
-
|
78
|
-
##
|
79
|
-
# The name of this file.
|
80
|
-
def name
|
81
|
-
@gapi.name
|
82
|
-
end
|
83
|
-
|
84
|
-
##
|
85
|
-
# The name of the {Bucket} containing this file.
|
86
|
-
def bucket
|
87
|
-
@gapi.bucket
|
88
|
-
end
|
89
|
-
|
90
|
-
##
|
91
|
-
# The content generation of this file.
|
92
|
-
# Used for object versioning.
|
93
|
-
def generation
|
94
|
-
@gapi.generation
|
95
|
-
end
|
96
|
-
|
97
|
-
##
|
98
|
-
# The version of the metadata for this file at this generation.
|
99
|
-
# Used for preconditions and for detecting changes in metadata.
|
100
|
-
# A metageneration number is only meaningful in the context of a
|
101
|
-
# particular generation of a particular file.
|
102
|
-
def metageneration
|
103
|
-
@gapi.metageneration
|
104
|
-
end
|
105
|
-
|
106
|
-
##
|
107
|
-
# A URL that can be used to access the file using the REST API.
|
108
|
-
def api_url
|
109
|
-
@gapi.self_link
|
110
|
-
end
|
111
|
-
|
112
|
-
##
|
113
|
-
# A URL that can be used to download the file using the REST API.
|
114
|
-
def media_url
|
115
|
-
@gapi.media_link
|
116
|
-
end
|
117
|
-
|
118
|
-
##
|
119
|
-
# Content-Length of the data in bytes.
|
120
|
-
def size
|
121
|
-
@gapi.size.to_i if @gapi.size
|
122
|
-
end
|
123
|
-
|
124
|
-
##
|
125
|
-
# Creation time of the file.
|
126
|
-
def created_at
|
127
|
-
@gapi.time_created
|
128
|
-
end
|
129
|
-
|
130
|
-
##
|
131
|
-
# The creation or modification time of the file.
|
132
|
-
# For buckets with versioning enabled, changing an object's
|
133
|
-
# metadata does not change this property.
|
134
|
-
def updated_at
|
135
|
-
@gapi.updated
|
136
|
-
end
|
137
|
-
|
138
|
-
##
|
139
|
-
# MD5 hash of the data; encoded using base64.
|
140
|
-
def md5
|
141
|
-
@gapi.md5_hash
|
142
|
-
end
|
143
|
-
|
144
|
-
##
|
145
|
-
# The CRC32c checksum of the data, as described in
|
146
|
-
# [RFC 4960, Appendix B](http://tools.ietf.org/html/rfc4960#appendix-B).
|
147
|
-
# Encoded using base64 in big-endian byte order.
|
148
|
-
def crc32c
|
149
|
-
@gapi.crc32c
|
150
|
-
end
|
151
|
-
|
152
|
-
##
|
153
|
-
# HTTP 1.1 Entity tag for the file.
|
154
|
-
def etag
|
155
|
-
@gapi.etag
|
156
|
-
end
|
157
|
-
|
158
|
-
##
|
159
|
-
# The [Cache-Control](https://tools.ietf.org/html/rfc7234#section-5.2)
|
160
|
-
# directive for the file data.
|
161
|
-
def cache_control
|
162
|
-
@gapi.cache_control
|
163
|
-
end
|
164
|
-
|
165
|
-
##
|
166
|
-
# Updates the
|
167
|
-
# [Cache-Control](https://tools.ietf.org/html/rfc7234#section-5.2)
|
168
|
-
# directive for the file data.
|
169
|
-
def cache_control= cache_control
|
170
|
-
@gapi.cache_control = cache_control
|
171
|
-
patch_gapi! :cache_control
|
172
|
-
end
|
173
|
-
|
174
|
-
##
|
175
|
-
# The [Content-Disposition](https://tools.ietf.org/html/rfc6266) of the
|
176
|
-
# file data.
|
177
|
-
def content_disposition
|
178
|
-
@gapi.content_disposition
|
179
|
-
end
|
180
|
-
|
181
|
-
##
|
182
|
-
# Updates the [Content-Disposition](https://tools.ietf.org/html/rfc6266)
|
183
|
-
# of the file data.
|
184
|
-
def content_disposition= content_disposition
|
185
|
-
@gapi.content_disposition = content_disposition
|
186
|
-
patch_gapi! :content_disposition
|
187
|
-
end
|
188
|
-
|
189
|
-
##
|
190
|
-
# The [Content-Encoding
|
191
|
-
# ](https://tools.ietf.org/html/rfc7231#section-3.1.2.2) of the file data.
|
192
|
-
def content_encoding
|
193
|
-
@gapi.content_encoding
|
194
|
-
end
|
195
|
-
|
196
|
-
##
|
197
|
-
# Updates the [Content-Encoding
|
198
|
-
# ](https://tools.ietf.org/html/rfc7231#section-3.1.2.2) of the file data.
|
199
|
-
def content_encoding= content_encoding
|
200
|
-
@gapi.content_encoding = content_encoding
|
201
|
-
patch_gapi! :content_encoding
|
202
|
-
end
|
203
|
-
|
204
|
-
##
|
205
|
-
# The [Content-Language](http://tools.ietf.org/html/bcp47) of the file
|
206
|
-
# data.
|
207
|
-
def content_language
|
208
|
-
@gapi.content_language
|
209
|
-
end
|
210
|
-
|
211
|
-
##
|
212
|
-
# Updates the [Content-Language](http://tools.ietf.org/html/bcp47) of the
|
213
|
-
# file data.
|
214
|
-
def content_language= content_language
|
215
|
-
@gapi.content_language = content_language
|
216
|
-
patch_gapi! :content_language
|
217
|
-
end
|
218
|
-
|
219
|
-
##
|
220
|
-
# The [Content-Type](https://tools.ietf.org/html/rfc2616#section-14.17) of
|
221
|
-
# the file data.
|
222
|
-
def content_type
|
223
|
-
@gapi.content_type
|
224
|
-
end
|
225
|
-
|
226
|
-
##
|
227
|
-
# Updates the
|
228
|
-
# [Content-Type](https://tools.ietf.org/html/rfc2616#section-14.17) of the
|
229
|
-
# file data.
|
230
|
-
def content_type= content_type
|
231
|
-
@gapi.content_type = content_type
|
232
|
-
patch_gapi! :content_type
|
233
|
-
end
|
234
|
-
|
235
|
-
##
|
236
|
-
# A hash of custom, user-provided web-safe keys and arbitrary string
|
237
|
-
# values that will returned with requests for the file as "x-goog-meta-"
|
238
|
-
# response headers.
|
239
|
-
def metadata
|
240
|
-
m = @gapi.metadata
|
241
|
-
m = m.to_h if m.respond_to? :to_h
|
242
|
-
m.dup.freeze
|
243
|
-
end
|
244
|
-
|
245
|
-
##
|
246
|
-
# Updates the hash of custom, user-provided web-safe keys and arbitrary
|
247
|
-
# string values that will returned with requests for the file as
|
248
|
-
# "x-goog-meta-" response headers.
|
249
|
-
def metadata= metadata
|
250
|
-
@gapi.metadata = metadata
|
251
|
-
patch_gapi! :metadata
|
252
|
-
end
|
253
|
-
|
254
|
-
##
|
255
|
-
# An [RFC 4648](https://tools.ietf.org/html/rfc4648#section-4)
|
256
|
-
# Base64-encoded string of the SHA256 hash of the [customer-supplied
|
257
|
-
# encryption key](https://cloud.google.com/storage/docs/encryption#customer-supplied).
|
258
|
-
# You can use this SHA256 hash to uniquely identify the AES-256 encryption
|
259
|
-
# key required to decrypt this file.
|
260
|
-
def encryption_key_sha256
|
261
|
-
return nil unless @gapi.customer_encryption
|
262
|
-
Base64.decode64 @gapi.customer_encryption.key_sha256
|
263
|
-
end
|
264
|
-
|
265
|
-
##
|
266
|
-
# Updates the file with changes made in the given block in a single
|
267
|
-
# PATCH request. The following attributes may be set: {#cache_control=},
|
268
|
-
# {#content_disposition=}, {#content_encoding=}, {#content_language=},
|
269
|
-
# {#content_type=}, and {#metadata=}. The {#metadata} hash accessible in
|
270
|
-
# the block is completely mutable and will be included in the request.
|
271
|
-
#
|
272
|
-
# @yield [file] a block yielding a delegate object for updating the file
|
273
|
-
#
|
274
|
-
# @example
|
275
|
-
# require "gcloud"
|
276
|
-
#
|
277
|
-
# gcloud = Gcloud.new
|
278
|
-
# storage = gcloud.storage
|
279
|
-
#
|
280
|
-
# bucket = storage.bucket "my-bucket"
|
281
|
-
#
|
282
|
-
# file = bucket.file "path/to/my-file.ext"
|
283
|
-
#
|
284
|
-
# file.update do |f|
|
285
|
-
# f.cache_control = "private, max-age=0, no-cache"
|
286
|
-
# f.content_disposition = "inline; filename=filename.ext"
|
287
|
-
# f.content_encoding = "deflate"
|
288
|
-
# f.content_language = "de"
|
289
|
-
# f.content_type = "application/json"
|
290
|
-
# f.metadata["player"] = "Bob"
|
291
|
-
# f.metadata["score"] = "10"
|
292
|
-
# end
|
293
|
-
#
|
294
|
-
def update
|
295
|
-
updater = Updater.new gapi
|
296
|
-
yield updater
|
297
|
-
updater.check_for_changed_metadata!
|
298
|
-
patch_gapi! updater.updates unless updater.updates.empty?
|
299
|
-
end
|
300
|
-
|
301
|
-
##
|
302
|
-
# Download the file's contents to a local file.
|
303
|
-
#
|
304
|
-
# By default, the download is verified by calculating the MD5 digest.
|
305
|
-
#
|
306
|
-
# If a [customer-supplied encryption
|
307
|
-
# key](https://cloud.google.com/storage/docs/encryption#customer-supplied)
|
308
|
-
# was used with {Bucket#create_file}, the `encryption_key` and
|
309
|
-
# `encryption_key_sha256` options must be provided.
|
310
|
-
#
|
311
|
-
# @param [String] path The path on the local file system to write the data
|
312
|
-
# to. The path provided must be writable.
|
313
|
-
# @param [Symbol] verify The verification algoruthm used to ensure the
|
314
|
-
# downloaded file contents are correct. Default is `:md5`.
|
315
|
-
#
|
316
|
-
# Acceptable values are:
|
317
|
-
#
|
318
|
-
# * `md5` - Verify file content match using the MD5 hash.
|
319
|
-
# * `crc32c` - Verify file content match using the CRC32c hash.
|
320
|
-
# * `all` - Perform all available file content verification.
|
321
|
-
# * `none` - Don't perform file content verification.
|
322
|
-
#
|
323
|
-
# @param [String] encryption_key Optional. The customer-supplied, AES-256
|
324
|
-
# encryption key used to encrypt the file, if one was provided to
|
325
|
-
# {Bucket#create_file}. Must be provided if `encryption_key_sha256` is
|
326
|
-
# provided.
|
327
|
-
# @param [String] encryption_key_sha256 Optional. The SHA256 hash of the
|
328
|
-
# customer-supplied, AES-256 encryption key used to encrypt the file, if
|
329
|
-
# one was provided to {Bucket#create_file}. Must be provided if
|
330
|
-
# `encryption_key` is provided.
|
331
|
-
#
|
332
|
-
# @return [File] Returns a `::File` object on the local file system
|
333
|
-
#
|
334
|
-
# @example
|
335
|
-
# require "gcloud"
|
336
|
-
#
|
337
|
-
# gcloud = Gcloud.new
|
338
|
-
# storage = gcloud.storage
|
339
|
-
#
|
340
|
-
# bucket = storage.bucket "my-bucket"
|
341
|
-
#
|
342
|
-
# file = bucket.file "path/to/my-file.ext"
|
343
|
-
# file.download "path/to/downloaded/file.ext"
|
344
|
-
#
|
345
|
-
# @example Use the CRC32c digest by passing :crc32c.
|
346
|
-
# require "gcloud"
|
347
|
-
#
|
348
|
-
# gcloud = Gcloud.new
|
349
|
-
# storage = gcloud.storage
|
350
|
-
#
|
351
|
-
# bucket = storage.bucket "my-bucket"
|
352
|
-
#
|
353
|
-
# file = bucket.file "path/to/my-file.ext"
|
354
|
-
# file.download "path/to/downloaded/file.ext", verify: :crc32c
|
355
|
-
#
|
356
|
-
# @example Use the MD5 and CRC32c digests by passing :all.
|
357
|
-
# require "gcloud"
|
358
|
-
#
|
359
|
-
# gcloud = Gcloud.new
|
360
|
-
# storage = gcloud.storage
|
361
|
-
#
|
362
|
-
# bucket = storage.bucket "my-bucket"
|
363
|
-
#
|
364
|
-
# file = bucket.file "path/to/my-file.ext"
|
365
|
-
# file.download "path/to/downloaded/file.ext", verify: :all
|
366
|
-
#
|
367
|
-
# @example Disable the download verification by passing :none.
|
368
|
-
# require "gcloud"
|
369
|
-
#
|
370
|
-
# gcloud = Gcloud.new
|
371
|
-
# storage = gcloud.storage
|
372
|
-
#
|
373
|
-
# bucket = storage.bucket "my-bucket"
|
374
|
-
#
|
375
|
-
# file = bucket.file "path/to/my-file.ext"
|
376
|
-
# file.download "path/to/downloaded/file.ext", verify: :none
|
377
|
-
#
|
378
|
-
def download path, verify: :md5, encryption_key: nil,
|
379
|
-
encryption_key_sha256: nil
|
380
|
-
ensure_service!
|
381
|
-
service.download_file \
|
382
|
-
bucket, name, path,
|
383
|
-
key: encryption_key, key_sha256: encryption_key_sha256
|
384
|
-
verify_file! ::File.new(path), verify
|
385
|
-
end
|
386
|
-
|
387
|
-
##
|
388
|
-
# Copy the file to a new location.
|
389
|
-
#
|
390
|
-
# If a [customer-supplied encryption
|
391
|
-
# key](https://cloud.google.com/storage/docs/encryption#customer-supplied)
|
392
|
-
# was used with {Bucket#create_file}, the `encryption_key` and
|
393
|
-
# `encryption_key_sha256` options must be provided.
|
394
|
-
#
|
395
|
-
# @param [String] dest_bucket_or_path Either the bucket to copy the file
|
396
|
-
# to, or the path to copy the file to in the current bucket.
|
397
|
-
# @param [String] dest_path If a bucket was provided in the first
|
398
|
-
# parameter, this contains the path to copy the file to in the given
|
399
|
-
# bucket.
|
400
|
-
# @param [String] acl A predefined set of access controls to apply to new
|
401
|
-
# file.
|
402
|
-
#
|
403
|
-
# Acceptable values are:
|
404
|
-
#
|
405
|
-
# * `auth`, `auth_read`, `authenticated`, `authenticated_read`,
|
406
|
-
# `authenticatedRead` - File owner gets OWNER access, and
|
407
|
-
# allAuthenticatedUsers get READER access.
|
408
|
-
# * `owner_full`, `bucketOwnerFullControl` - File owner gets OWNER
|
409
|
-
# access, and project team owners get OWNER access.
|
410
|
-
# * `owner_read`, `bucketOwnerRead` - File owner gets OWNER access, and
|
411
|
-
# project team owners get READER access.
|
412
|
-
# * `private` - File owner gets OWNER access.
|
413
|
-
# * `project_private`, `projectPrivate` - File owner gets OWNER access,
|
414
|
-
# and project team members get access according to their roles.
|
415
|
-
# * `public`, `public_read`, `publicRead` - File owner gets OWNER
|
416
|
-
# access, and allUsers get READER access.
|
417
|
-
# @param [Integer] generation Select a specific revision of the file to
|
418
|
-
# copy. The default is the latest version.
|
419
|
-
# @param [String] encryption_key Optional. The customer-supplied, AES-256
|
420
|
-
# encryption key used to encrypt the file, if one was provided to
|
421
|
-
# {Bucket#create_file}. Must be provided if `encryption_key_sha256` is
|
422
|
-
# provided.
|
423
|
-
# @param [String] encryption_key_sha256 Optional. The SHA256 hash of the
|
424
|
-
# customer-supplied, AES-256 encryption key used to encrypt the file, if
|
425
|
-
# one was provided to {Bucket#create_file}. Must be provided if
|
426
|
-
# `encryption_key` is provided.
|
427
|
-
#
|
428
|
-
# @return [Gcloud::Storage::File]
|
429
|
-
#
|
430
|
-
# @example The file can be copied to a new path in the current bucket:
|
431
|
-
# require "gcloud"
|
432
|
-
#
|
433
|
-
# gcloud = Gcloud.new
|
434
|
-
# storage = gcloud.storage
|
435
|
-
#
|
436
|
-
# bucket = storage.bucket "my-bucket"
|
437
|
-
#
|
438
|
-
# file = bucket.file "path/to/my-file.ext"
|
439
|
-
# file.copy "path/to/destination/file.ext"
|
440
|
-
#
|
441
|
-
# @example The file can also be copied to a different bucket:
|
442
|
-
# require "gcloud"
|
443
|
-
#
|
444
|
-
# gcloud = Gcloud.new
|
445
|
-
# storage = gcloud.storage
|
446
|
-
#
|
447
|
-
# bucket = storage.bucket "my-bucket"
|
448
|
-
#
|
449
|
-
# file = bucket.file "path/to/my-file.ext"
|
450
|
-
# file.copy "new-destination-bucket",
|
451
|
-
# "path/to/destination/file.ext"
|
452
|
-
#
|
453
|
-
# @example The file can also be copied by specifying a generation:
|
454
|
-
# file.copy "copy/of/previous/generation/file.ext",
|
455
|
-
# generation: 123456
|
456
|
-
#
|
457
|
-
def copy dest_bucket_or_path, dest_path = nil, acl: nil, generation: nil,
|
458
|
-
encryption_key: nil, encryption_key_sha256: nil
|
459
|
-
ensure_service!
|
460
|
-
options = { acl: acl, generation: generation,
|
461
|
-
key: encryption_key, key_sha256: encryption_key_sha256 }
|
462
|
-
dest_bucket, dest_path, options = fix_copy_args dest_bucket_or_path,
|
463
|
-
dest_path, options
|
464
|
-
|
465
|
-
gapi = service.copy_file bucket, name,
|
466
|
-
dest_bucket, dest_path, options
|
467
|
-
File.from_gapi gapi, service
|
468
|
-
end
|
469
|
-
|
470
|
-
##
|
471
|
-
# Permanently deletes the file.
|
472
|
-
#
|
473
|
-
# @return [Boolean] Returns `true` if the file was deleted.
|
474
|
-
#
|
475
|
-
# @example
|
476
|
-
# require "gcloud"
|
477
|
-
#
|
478
|
-
# gcloud = Gcloud.new
|
479
|
-
# storage = gcloud.storage
|
480
|
-
#
|
481
|
-
# bucket = storage.bucket "my-bucket"
|
482
|
-
#
|
483
|
-
# file = bucket.file "path/to/my-file.ext"
|
484
|
-
# file.delete
|
485
|
-
#
|
486
|
-
def delete
|
487
|
-
ensure_service!
|
488
|
-
service.delete_file bucket, name
|
489
|
-
true
|
490
|
-
end
|
491
|
-
|
492
|
-
##
|
493
|
-
# Public URL to access the file. If the file is not public, requests to
|
494
|
-
# the URL will return an error. (See {File::Acl#public!} and
|
495
|
-
# {Bucket::DefaultAcl#public!}) To share a file that is not public see
|
496
|
-
# {#signed_url}.
|
497
|
-
#
|
498
|
-
# @see https://cloud.google.com/storage/docs/access-public-data Accessing
|
499
|
-
# Public Data
|
500
|
-
#
|
501
|
-
# @param [String] protocol The protocol to use for the URL. Default is
|
502
|
-
# `HTTPS`.
|
503
|
-
#
|
504
|
-
# @example
|
505
|
-
# require "gcloud"
|
506
|
-
#
|
507
|
-
# gcloud = Gcloud.new
|
508
|
-
# storage = gcloud.storage
|
509
|
-
#
|
510
|
-
# bucket = storage.bucket "my-todo-app"
|
511
|
-
# file = bucket.file "avatars/heidi/400x400.png"
|
512
|
-
# public_url = file.public_url
|
513
|
-
#
|
514
|
-
# @example Generate the URL with a protocol other than HTTPS:
|
515
|
-
# require "gcloud"
|
516
|
-
#
|
517
|
-
# gcloud = Gcloud.new
|
518
|
-
# storage = gcloud.storage
|
519
|
-
#
|
520
|
-
# bucket = storage.bucket "my-todo-app"
|
521
|
-
# file = bucket.file "avatars/heidi/400x400.png"
|
522
|
-
# public_url = file.public_url protocol: "http"
|
523
|
-
#
|
524
|
-
def public_url protocol: :https
|
525
|
-
"#{protocol}://storage.googleapis.com/#{bucket}/#{name}"
|
526
|
-
end
|
527
|
-
alias_method :url, :public_url
|
528
|
-
|
529
|
-
##
|
530
|
-
# Access without authentication can be granted to a File for a specified
|
531
|
-
# period of time. This URL uses a cryptographic signature
|
532
|
-
# of your credentials to access the file.
|
533
|
-
#
|
534
|
-
# Generating a URL requires service account credentials, either by
|
535
|
-
# connecting with a service account when calling {Gcloud.storage}, or by
|
536
|
-
# passing in the service account `issuer` and `signing_key` values.
|
537
|
-
# Although the private key can be passed as a string for convenience,
|
538
|
-
# creating and storing an instance of `OpenSSL::PKey::RSA` is more
|
539
|
-
# efficient when making multiple calls to `signed_url`.
|
540
|
-
#
|
541
|
-
# A SignedUrlUnavailable is raised if the service account credentials are
|
542
|
-
# missing. Service account credentials are acquired by following the steps
|
543
|
-
# in [Service Account Authentication](
|
544
|
-
# https://cloud.google.com/storage/docs/authentication#service_accounts).
|
545
|
-
#
|
546
|
-
# @see https://cloud.google.com/storage/docs/access-control#Signed-URLs
|
547
|
-
# Access Control Signed URLs guide
|
548
|
-
#
|
549
|
-
# @param [String] method The HTTP verb to be used with the signed URL.
|
550
|
-
# Signed URLs can be used
|
551
|
-
# with `GET`, `HEAD`, `PUT`, and `DELETE` requests. Default is `GET`.
|
552
|
-
# @param [Integer] expires The number of seconds until the URL expires.
|
553
|
-
# Default is 300/5 minutes.
|
554
|
-
# @param [String] content_type When provided, the client (browser) must
|
555
|
-
# send this value in the HTTP header. e.g. `text/plain`
|
556
|
-
# @param [String] content_md5 The MD5 digest value in base64. If you
|
557
|
-
# provide this in the string, the client (usually a browser) must
|
558
|
-
# provide this HTTP header with this same value in its request.
|
559
|
-
# @param [String] issuer Service Account's Client Email.
|
560
|
-
# @param [String] client_email Service Account's Client Email.
|
561
|
-
# @param [OpenSSL::PKey::RSA, String] signing_key Service Account's
|
562
|
-
# Private Key.
|
563
|
-
# @param [OpenSSL::PKey::RSA, String] private_key Service Account's
|
564
|
-
# Private Key.
|
565
|
-
#
|
566
|
-
# @example
|
567
|
-
# require "gcloud"
|
568
|
-
#
|
569
|
-
# gcloud = Gcloud.new
|
570
|
-
# storage = gcloud.storage
|
571
|
-
#
|
572
|
-
# bucket = storage.bucket "my-todo-app"
|
573
|
-
# file = bucket.file "avatars/heidi/400x400.png"
|
574
|
-
# shared_url = file.signed_url
|
575
|
-
#
|
576
|
-
# @example Any of the option parameters may be specified:
|
577
|
-
# require "gcloud"
|
578
|
-
#
|
579
|
-
# gcloud = Gcloud.new
|
580
|
-
# storage = gcloud.storage
|
581
|
-
#
|
582
|
-
# bucket = storage.bucket "my-todo-app"
|
583
|
-
# file = bucket.file "avatars/heidi/400x400.png"
|
584
|
-
# shared_url = file.signed_url method: "GET",
|
585
|
-
# expires: 300 # 5 minutes from now
|
586
|
-
#
|
587
|
-
# @example Using the `issuer` and `signing_key` options:
|
588
|
-
# require "gcloud/storage"
|
589
|
-
#
|
590
|
-
# storage = Gcloud.storage
|
591
|
-
#
|
592
|
-
# bucket = storage.bucket "my-todo-app"
|
593
|
-
# file = bucket.file "avatars/heidi/400x400.png"
|
594
|
-
# key = OpenSSL::PKey::RSA.new "-----BEGIN PRIVATE KEY-----\n..."
|
595
|
-
# shared_url = file.signed_url issuer: "service-account@gcloud.com",
|
596
|
-
# signing_key: key
|
597
|
-
#
|
598
|
-
def signed_url method: nil, expires: nil, content_type: nil,
|
599
|
-
content_md5: nil, issuer: nil, client_email: nil,
|
600
|
-
signing_key: nil, private_key: nil
|
601
|
-
ensure_service!
|
602
|
-
options = { method: method, expires: expires,
|
603
|
-
content_type: content_type, content_md5: content_md5,
|
604
|
-
issuer: issuer, client_email: client_email,
|
605
|
-
signing_key: signing_key, private_key: private_key }
|
606
|
-
signer = File::Signer.new self
|
607
|
-
signer.signed_url options
|
608
|
-
end
|
609
|
-
|
610
|
-
##
|
611
|
-
# The {File::Acl} instance used to control access to the file.
|
612
|
-
#
|
613
|
-
# A file has owners, writers, and readers. Permissions can be granted to
|
614
|
-
# an individual user's email address, a group's email address, as well as
|
615
|
-
# many predefined lists.
|
616
|
-
#
|
617
|
-
# @see https://cloud.google.com/storage/docs/access-control Access Control
|
618
|
-
# guide
|
619
|
-
#
|
620
|
-
# @example Grant access to a user by pre-pending `"user-"` to an email:
|
621
|
-
# require "gcloud"
|
622
|
-
#
|
623
|
-
# gcloud = Gcloud.new
|
624
|
-
# storage = gcloud.storage
|
625
|
-
#
|
626
|
-
# bucket = storage.bucket "my-todo-app"
|
627
|
-
# file = bucket.file "avatars/heidi/400x400.png"
|
628
|
-
#
|
629
|
-
# email = "heidi@example.net"
|
630
|
-
# file.acl.add_reader "user-#{email}"
|
631
|
-
#
|
632
|
-
# @example Grant access to a group by pre-pending `"group-"` to an email:
|
633
|
-
# require "gcloud"
|
634
|
-
#
|
635
|
-
# gcloud = Gcloud.new
|
636
|
-
# storage = gcloud.storage
|
637
|
-
#
|
638
|
-
# bucket = storage.bucket "my-todo-app"
|
639
|
-
# file = bucket.file "avatars/heidi/400x400.png"
|
640
|
-
#
|
641
|
-
# email = "authors@example.net"
|
642
|
-
# file.acl.add_reader "group-#{email}"
|
643
|
-
#
|
644
|
-
# @example Or, grant access via a predefined permissions list:
|
645
|
-
# require "gcloud"
|
646
|
-
#
|
647
|
-
# gcloud = Gcloud.new
|
648
|
-
# storage = gcloud.storage
|
649
|
-
#
|
650
|
-
# bucket = storage.bucket "my-todo-app"
|
651
|
-
# file = bucket.file "avatars/heidi/400x400.png"
|
652
|
-
#
|
653
|
-
# file.acl.public!
|
654
|
-
#
|
655
|
-
def acl
|
656
|
-
@acl ||= File::Acl.new self
|
657
|
-
end
|
658
|
-
|
659
|
-
##
|
660
|
-
# Reloads the file with current data from the Storage service.
|
661
|
-
def reload!
|
662
|
-
ensure_service!
|
663
|
-
@gapi = service.get_file bucket, name
|
664
|
-
end
|
665
|
-
alias_method :refresh!, :reload!
|
666
|
-
|
667
|
-
##
|
668
|
-
# @private URI of the location and file name in the format of
|
669
|
-
# <code>gs://my-bucket/file-name.json</code>.
|
670
|
-
def to_gs_url
|
671
|
-
"gs://#{bucket}/#{name}"
|
672
|
-
end
|
673
|
-
|
674
|
-
##
|
675
|
-
# @private New File from a Google API Client object.
|
676
|
-
def self.from_gapi gapi, service
|
677
|
-
new.tap do |f|
|
678
|
-
f.gapi = gapi
|
679
|
-
f.service = service
|
680
|
-
end
|
681
|
-
end
|
682
|
-
|
683
|
-
protected
|
684
|
-
|
685
|
-
##
|
686
|
-
# Raise an error unless an active service is available.
|
687
|
-
def ensure_service!
|
688
|
-
fail "Must have active connection" unless service
|
689
|
-
end
|
690
|
-
|
691
|
-
def patch_gapi! *attributes
|
692
|
-
attributes.flatten!
|
693
|
-
return if attributes.empty?
|
694
|
-
ensure_service!
|
695
|
-
patch_args = Hash[attributes.map do |attr|
|
696
|
-
[attr, @gapi.send(attr)]
|
697
|
-
end]
|
698
|
-
patch_gapi = Google::Apis::StorageV1::Object.new patch_args
|
699
|
-
@gapi = service.patch_file bucket, name, patch_gapi
|
700
|
-
end
|
701
|
-
|
702
|
-
def fix_copy_args dest_bucket, dest_path, options = {}
|
703
|
-
if dest_path.respond_to?(:to_hash) && options.empty?
|
704
|
-
options = dest_path
|
705
|
-
dest_path = nil
|
706
|
-
end
|
707
|
-
if dest_path.nil?
|
708
|
-
dest_path = dest_bucket
|
709
|
-
dest_bucket = bucket
|
710
|
-
end
|
711
|
-
dest_bucket = dest_bucket.name if dest_bucket.respond_to? :name
|
712
|
-
options[:acl] = File::Acl.predefined_rule_for options[:acl]
|
713
|
-
[dest_bucket, dest_path, options]
|
714
|
-
end
|
715
|
-
|
716
|
-
def verify_file! file, verify = :md5
|
717
|
-
verify_md5 = verify == :md5 || verify == :all
|
718
|
-
verify_crc32c = verify == :crc32c || verify == :all
|
719
|
-
Verifier.verify_md5! self, file if verify_md5
|
720
|
-
Verifier.verify_crc32c! self, file if verify_crc32c
|
721
|
-
file
|
722
|
-
end
|
723
|
-
|
724
|
-
##
|
725
|
-
# @private Create a signed_url for a file.
|
726
|
-
class Signer
|
727
|
-
def initialize file
|
728
|
-
@file = file
|
729
|
-
end
|
730
|
-
|
731
|
-
##
|
732
|
-
# The external path to the file.
|
733
|
-
def ext_path
|
734
|
-
"/#{@file.bucket}/#{@file.name}"
|
735
|
-
end
|
736
|
-
|
737
|
-
##
|
738
|
-
# The external url to the file.
|
739
|
-
def ext_url
|
740
|
-
"https://storage.googleapis.com#{ext_path}"
|
741
|
-
end
|
742
|
-
|
743
|
-
def apply_option_defaults options
|
744
|
-
adjusted_expires = (Time.now.utc + (options[:expires] || 300)).to_i
|
745
|
-
options[:expires] = adjusted_expires
|
746
|
-
options[:method] ||= "GET"
|
747
|
-
options
|
748
|
-
end
|
749
|
-
|
750
|
-
def signature_str options
|
751
|
-
[options[:method], options[:content_md5],
|
752
|
-
options[:content_type], options[:expires],
|
753
|
-
ext_path].join "\n"
|
754
|
-
end
|
755
|
-
|
756
|
-
def determine_signing_key options = {}
|
757
|
-
options[:signing_key] || options[:private_key] ||
|
758
|
-
@file.service.credentials.signing_key
|
759
|
-
end
|
760
|
-
|
761
|
-
def determine_issuer options = {}
|
762
|
-
options[:issuer] || options[:client_email] ||
|
763
|
-
@file.service.credentials.issuer
|
764
|
-
end
|
765
|
-
|
766
|
-
def signed_url options
|
767
|
-
options = apply_option_defaults options
|
768
|
-
|
769
|
-
i = determine_issuer options
|
770
|
-
s = determine_signing_key options
|
771
|
-
|
772
|
-
fail SignedUrlUnavailable unless i && s
|
773
|
-
|
774
|
-
sig = generate_signature s, options
|
775
|
-
generate_signed_url i, sig, options[:expires]
|
776
|
-
end
|
777
|
-
|
778
|
-
def generate_signature signing_key, options = {}
|
779
|
-
unless signing_key.respond_to? :sign
|
780
|
-
signing_key = OpenSSL::PKey::RSA.new signing_key
|
781
|
-
end
|
782
|
-
signing_key.sign OpenSSL::Digest::SHA256.new, signature_str(options)
|
783
|
-
end
|
784
|
-
|
785
|
-
def generate_signed_url issuer, signed_string, expires
|
786
|
-
signature = Base64.strict_encode64(signed_string).delete("\n")
|
787
|
-
"#{ext_url}?GoogleAccessId=#{CGI.escape issuer}" \
|
788
|
-
"&Expires=#{expires}" \
|
789
|
-
"&Signature=#{CGI.escape signature}"
|
790
|
-
end
|
791
|
-
end
|
792
|
-
|
793
|
-
##
|
794
|
-
# Yielded to a block to accumulate changes for a patch request.
|
795
|
-
class Updater < File
|
796
|
-
attr_reader :updates
|
797
|
-
##
|
798
|
-
# Create an Updater object.
|
799
|
-
def initialize gapi
|
800
|
-
@updates = []
|
801
|
-
@gapi = gapi
|
802
|
-
end
|
803
|
-
|
804
|
-
##
|
805
|
-
# A hash of custom, user-provided web-safe keys and arbitrary string
|
806
|
-
# values that will returned with requests for the file as "x-goog-meta-"
|
807
|
-
# response headers.
|
808
|
-
def metadata
|
809
|
-
# do not freeze metadata
|
810
|
-
@metadata ||= @gapi.metadata.to_h.dup
|
811
|
-
end
|
812
|
-
|
813
|
-
##
|
814
|
-
# Updates the hash of custom, user-provided web-safe keys and arbitrary
|
815
|
-
# string values that will returned with requests for the file as
|
816
|
-
# "x-goog-meta-" response headers.
|
817
|
-
def metadata= metadata
|
818
|
-
@metadata = metadata
|
819
|
-
@gapi.metadata = @metadata
|
820
|
-
patch_gapi! :metadata
|
821
|
-
end
|
822
|
-
|
823
|
-
##
|
824
|
-
# @private Make sure any metadata changes are saved
|
825
|
-
def check_for_changed_metadata!
|
826
|
-
return if @metadata == @gapi.metadata
|
827
|
-
@gapi.metadata = @metadata
|
828
|
-
patch_gapi! :metadata
|
829
|
-
end
|
830
|
-
|
831
|
-
protected
|
832
|
-
|
833
|
-
##
|
834
|
-
# Queue up all the updates instead of making them.
|
835
|
-
def patch_gapi! attribute
|
836
|
-
@updates << attribute
|
837
|
-
@updates.uniq!
|
838
|
-
end
|
839
|
-
end
|
840
|
-
end
|
841
|
-
end
|
842
|
-
end
|