google-cloud-storage 1.4.0 → 1.5.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 68663d7f63e76435070cbcd4748022693d2561a5
4
- data.tar.gz: cb6ecfdfaadeb41ed569d08ca9c069edf67c0ea4
3
+ metadata.gz: 5b7f1798224baa310d43cdd64174d46389b6c66c
4
+ data.tar.gz: 5cd8d77373e98f5858c430aa07592ec316bf0ab1
5
5
  SHA512:
6
- metadata.gz: 1382c121c18b2cc7fa8a916895bec8c0a2b7c40a99b4fea1a54edc3562ba53b8e9f9538ea3e613f20c39572bdcc21cb2190d7a26da82240fe966901b24bf8ebb
7
- data.tar.gz: 78b666563914f310968e53d4701c78781ebedae1977e1f51f6f3874ee69d23e9dfcf0b235178d0e13a0437c22fd41a12e9210577e1aa23d0ca2937b4babb0500
6
+ metadata.gz: 6e8caa5b4112ae3f8d8aad56157f612006eb6bb3944668c9e2f491449cf46d9fe834703863c8e372b237ad800aaa67cc60fbb92bc11662650814693127b08945
7
+ data.tar.gz: 8b5272dfad3534f26db99f153bae01e2a25c5931eefe7897a4a8344bda30669a3f6525f4d85581d4277c0197a3f35fa3ff096d54e6f922c180c1a77508304d7f
@@ -488,6 +488,38 @@ module Google
488
488
  # files = bucket.files # Billed to "my-other-project"
489
489
  # ```
490
490
  #
491
+ # ## Configuring Pub/Sub notification subscriptions
492
+ #
493
+ # You can configure notifications to send Google Cloud Pub/Sub messages
494
+ # about changes to files in your buckets. For example, you can track files
495
+ # that are created and deleted in your bucket. Each notification contains
496
+ # information describing both the event that triggered it and the file that
497
+ # changed.
498
+ #
499
+ # You can send notifications to any Cloud Pub/Sub topic in any project for
500
+ # which your service account has sufficient permissions. As shown below, you
501
+ # need to explicitly grant permission to your service account to enable
502
+ # Google Cloud Storage to publish on behalf of your account. (Even if your
503
+ # current project created and owns the topic.)
504
+ #
505
+ # ```ruby
506
+ # require "google/cloud/pubsub"
507
+ # require "google/cloud/storage"
508
+ #
509
+ # pubsub = Google::Cloud::Pubsub.new
510
+ # topic = pubsub.create_topic "my-topic"
511
+ # topic.policy do |p|
512
+ # p.add "roles/pubsub.publisher",
513
+ # "serviceAccount:my-project" \
514
+ # "@gs-project-accounts.iam.gserviceaccount.com"
515
+ # end
516
+ #
517
+ # storage = Google::Cloud::Storage.new
518
+ # bucket = storage.bucket "my-bucket"
519
+ #
520
+ # notification = bucket.create_notification topic.name
521
+ # ```
522
+ #
491
523
  # ## Configuring retries and timeout
492
524
  #
493
525
  # You can configure how many times API requests may be automatically
@@ -19,6 +19,7 @@ require "google/cloud/storage/bucket/cors"
19
19
  require "google/cloud/storage/policy"
20
20
  require "google/cloud/storage/post_object"
21
21
  require "google/cloud/storage/file"
22
+ require "google/cloud/storage/notification"
22
23
  require "pathname"
23
24
 
24
25
  module Google
@@ -1137,6 +1138,147 @@ module Google
1137
1138
  gapi.permissions
1138
1139
  end
1139
1140
 
1141
+ ##
1142
+ # Retrieves the entire list of Pub/Sub notification subscriptions for
1143
+ # the bucket.
1144
+ #
1145
+ # @see https://cloud.google.com/storage/docs/pubsub-notifications Cloud
1146
+ # Pub/Sub Notifications for Google Cloud
1147
+ #
1148
+ # @return [Array<Google::Cloud::Storage::Notification>]
1149
+ #
1150
+ # @example
1151
+ # require "google/cloud/storage"
1152
+ #
1153
+ # storage = Google::Cloud::Storage.new
1154
+ #
1155
+ # bucket = storage.bucket "my-bucket"
1156
+ # notifications = bucket.notifications
1157
+ # notifications.each do |notification|
1158
+ # puts notification.id
1159
+ # end
1160
+ #
1161
+ def notifications
1162
+ ensure_service!
1163
+ gapi = service.list_notifications name, user_project: user_project
1164
+ Array(gapi.items).map do |gapi_object|
1165
+ Notification.from_gapi name, gapi_object, service,
1166
+ user_project: user_project
1167
+ end
1168
+ end
1169
+ alias_method :find_notifications, :notifications
1170
+
1171
+ ##
1172
+ # Retrieves a Pub/Sub notification subscription for the bucket.
1173
+ #
1174
+ # @see https://cloud.google.com/storage/docs/pubsub-notifications Cloud
1175
+ # Pub/Sub Notifications for Google Cloud
1176
+ #
1177
+ # @param [String] id The Notification ID.
1178
+ #
1179
+ # @return [Google::Cloud::Storage::Notification, nil] Returns nil if the
1180
+ # notification does not exist
1181
+ #
1182
+ # @example
1183
+ # require "google/cloud/storage"
1184
+ #
1185
+ # storage = Google::Cloud::Storage.new
1186
+ #
1187
+ # bucket = storage.bucket "my-bucket"
1188
+ #
1189
+ # notification = bucket.notification "1"
1190
+ # puts notification.id
1191
+ #
1192
+ def notification id
1193
+ ensure_service!
1194
+ gapi = service.get_notification name, id, user_project: user_project
1195
+ Notification.from_gapi name, gapi, service, user_project: user_project
1196
+ rescue Google::Cloud::NotFoundError
1197
+ nil
1198
+ end
1199
+ alias_method :find_notification, :notification
1200
+
1201
+
1202
+ ##
1203
+ # Creates a new Pub/Sub notification subscription for the bucket.
1204
+ #
1205
+ # @see https://cloud.google.com/storage/docs/pubsub-notifications Cloud
1206
+ # Pub/Sub Notifications for Google Cloud
1207
+ #
1208
+ # @param [String] topic The name of the Cloud PubSub topic to which the
1209
+ # notification subscription will publish.
1210
+ # @param [Hash(String => String)] custom_attrs The custom attributes for
1211
+ # the notification. An optional list of additional attributes to
1212
+ # attach to each Cloud Pub/Sub message published for the notification
1213
+ # subscription.
1214
+ # @param [Symbol, String] event_types The event types for the
1215
+ # notification subscription. If provided, messages will only be sent
1216
+ # for the listed event types. If empty, messages will be sent for all
1217
+ # event types.
1218
+ #
1219
+ # Acceptable values are:
1220
+ #
1221
+ # * `:finalize` - Sent when a new object (or a new generation of
1222
+ # an existing object) is successfully created in the bucket. This
1223
+ # includes copying or rewriting an existing object. A failed upload
1224
+ # does not trigger this event.
1225
+ # * `:update` - Sent when the metadata of an existing object changes.
1226
+ # * `:delete` - Sent when an object has been permanently deleted. This
1227
+ # includes objects that are overwritten or are deleted as part of
1228
+ # the bucket's lifecycle configuration. For buckets with object
1229
+ # versioning enabled, this is not sent when an object is archived
1230
+ # (see `OBJECT_ARCHIVE`), even if archival occurs via the
1231
+ # {File#delete} method.
1232
+ # * `:archive` - Only sent when the bucket has enabled object
1233
+ # versioning. This event indicates that the live version of an
1234
+ # object has become an archived version, either because it was
1235
+ # archived or because it was overwritten by the upload of an object
1236
+ # of the same name.
1237
+ # @param [String] prefix The file name prefix for the notification
1238
+ # subscription. If provided, the notification will only be applied to
1239
+ # file names that begin with this prefix.
1240
+ # @param [Symbol, String, Boolean] payload The desired content of the
1241
+ # Pub/Sub message payload. Acceptable values are:
1242
+ #
1243
+ # * `true` or `:json` - The Pub/Sub message payload will be a UTF-8
1244
+ # string containing the [resource
1245
+ # representation](https://cloud.google.com/storage/docs/json_api/v1/objects#resource-representations)
1246
+ # of the file's metadata.
1247
+ # * `false` or `:none` - No payload is included with the notification.
1248
+ #
1249
+ # The default value is `:json`.
1250
+ #
1251
+ # @return [Array<String>] The permissions held by the caller.
1252
+ #
1253
+ # @example
1254
+ # require "google/cloud/pubsub"
1255
+ # require "google/cloud/storage"
1256
+ #
1257
+ # pubsub = Google::Cloud::Pubsub.new
1258
+ # topic = pubsub.create_topic "my-topic"
1259
+ # topic.policy do |p|
1260
+ # p.add "roles/pubsub.publisher",
1261
+ # "serviceAccount:my-project" \
1262
+ # "@gs-project-accounts.iam.gserviceaccount.com"
1263
+ # end
1264
+ #
1265
+ # storage = Google::Cloud::Storage.new
1266
+ # bucket = storage.bucket "my-bucket"
1267
+ #
1268
+ # notification = bucket.create_notification topic.name
1269
+ #
1270
+ def create_notification topic, custom_attrs: nil, event_types: nil,
1271
+ prefix: nil, payload: nil
1272
+ ensure_service!
1273
+ options = { custom_attrs: custom_attrs, event_types: event_types,
1274
+ prefix: prefix, payload: payload,
1275
+ user_project: user_project }
1276
+
1277
+ gapi = service.insert_notification name, topic, options
1278
+ Notification.from_gapi name, gapi, service, user_project: user_project
1279
+ end
1280
+ alias_method :new_notification, :create_notification
1281
+
1140
1282
  ##
1141
1283
  # Reloads the bucket with current data from the Storage service.
1142
1284
  def reload!
@@ -121,13 +121,13 @@ module Google
121
121
  end
122
122
 
123
123
  def generate_signed_url issuer, signed_string, expires, query
124
- url = "#{ext_url}?GoogleAccessId=#{CGI.escape issuer}" \
124
+ url = "#{ext_url}?GoogleAccessId=#{url_escape issuer}" \
125
125
  "&Expires=#{expires}" \
126
- "&Signature=#{CGI.escape signed_string}"
126
+ "&Signature=#{url_escape signed_string}"
127
127
 
128
128
  if query
129
129
  query.each do |name, value|
130
- url << "&#{CGI.escape name}=#{CGI.escape value}"
130
+ url << "&#{url_escape name}=#{url_escape value}"
131
131
  end
132
132
  end
133
133
 
@@ -143,6 +143,10 @@ module Google
143
143
  flatten.reject! { |h| h.start_with? "x-goog-encryption-key" }
144
144
  flatten.sort.join
145
145
  end
146
+
147
+ def url_escape str
148
+ CGI.escape String str
149
+ end
146
150
  end
147
151
  end
148
152
  end
@@ -0,0 +1,212 @@
1
+ # Copyright 2017 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
+ require "google/cloud/errors"
16
+ require "google/apis/storage_v1"
17
+
18
+ module Google
19
+ module Cloud
20
+ module Storage
21
+ ##
22
+ # # Notification
23
+ #
24
+ # Represents a Pub/Sub notification subscription for a Cloud Storage
25
+ # bucket.
26
+ #
27
+ # @see https://cloud.google.com/storage/docs/pubsub-notifications Cloud
28
+ # Pub/Sub Notifications for Google Cloud
29
+ #
30
+ # @attr [String] bucket The name of the {Bucket} to which this
31
+ # notification belongs.
32
+ #
33
+ # @example
34
+ # require "google/cloud/pubsub"
35
+ # require "google/cloud/storage"
36
+ #
37
+ # pubsub = Google::Cloud::Pubsub.new
38
+ # topic = pubsub.create_topic "my-topic"
39
+ # topic.policy do |p|
40
+ # p.add "roles/pubsub.publisher",
41
+ # "serviceAccount:my-project" \
42
+ # "@gs-project-accounts.iam.gserviceaccount.com"
43
+ # end
44
+ #
45
+ # storage = Google::Cloud::Storage.new
46
+ # bucket = storage.bucket "my-bucket"
47
+ #
48
+ # notification = bucket.create_notification topic.name
49
+ #
50
+ class Notification
51
+ ##
52
+ # @private The Connection object.
53
+ attr_accessor :service
54
+
55
+ ##
56
+ # @private The Google API Client object.
57
+ attr_accessor :gapi
58
+
59
+ ##
60
+ # @private The project ID string for a requester pays bucket.
61
+ attr_accessor :user_project
62
+
63
+ attr_reader :bucket
64
+
65
+ ##
66
+ # @private Creates a Notification object.
67
+ def initialize
68
+ @bucket = nil
69
+ @service = nil
70
+ @gapi = nil
71
+ @user_project = nil
72
+ end
73
+
74
+ ##
75
+ # The kind of item this is.
76
+ # For notifications, this is always storage#notification.
77
+ def kind
78
+ @gapi.kind
79
+ end
80
+
81
+ ##
82
+ # The ID of the notification.
83
+ def id
84
+ @gapi.id
85
+ end
86
+
87
+ ##
88
+ # A URL that can be used to access the notification using the REST API.
89
+ def api_url
90
+ @gapi.self_link
91
+ end
92
+
93
+ ##
94
+ # The custom attributes of this notification. An optional list of
95
+ # additional attributes to attach to each Cloud Pub/Sub message
96
+ # published for this notification subscription.
97
+ def custom_attrs
98
+ @gapi.custom_attributes
99
+ end
100
+
101
+ ##
102
+ # The event types of this notification. If present, only send
103
+ # notifications about listed event types. If empty, sent notifications
104
+ # for all event types.
105
+ #
106
+ # The following is a list of event types currently supported by Cloud
107
+ # Storage:
108
+ #
109
+ # * `OBJECT_FINALIZE` - Sent when a new object (or a new generation of
110
+ # an existing object) is successfully created in the bucket. This
111
+ # includes copying or rewriting an existing object. A failed upload
112
+ # does not trigger this event.
113
+ # * `OBJECT_METADATA_UPDATE` - Sent when the metadata of an existing
114
+ # object changes.
115
+ # * `OBJECT_DELETE` - Sent when an object has been permanently deleted.
116
+ # This includes objects that are overwritten or are deleted as part of
117
+ # the bucket's lifecycle configuration. For buckets with object
118
+ # versioning enabled, this is not sent when an object is archived (see
119
+ # `OBJECT_ARCHIVE`), even if archival occurs via the {File#delete}
120
+ # method.
121
+ # * `OBJECT_ARCHIVE` - Only sent when a bucket has enabled object
122
+ # versioning. This event indicates that the live version of an object
123
+ # has become an archived version, either because it was archived or
124
+ # because it was overwritten by the upload of an object of the same
125
+ # name.
126
+ #
127
+ # Important: Additional event types may be released later. Client code
128
+ # should either safely ignore unrecognized event types, or else
129
+ # explicitly specify in their notification configuration which event
130
+ # types they are prepared to accept.
131
+ #
132
+ def event_types
133
+ @gapi.event_types
134
+ end
135
+
136
+ ##
137
+ # The file name prefix of this notification. If present, only apply
138
+ # this notification configuration to file names that begin with this
139
+ # prefix.
140
+ #
141
+ def prefix
142
+ @gapi.object_name_prefix
143
+ end
144
+
145
+ ##
146
+ # The desired content of the Pub/Sub message payload. Acceptable values
147
+ # are:
148
+ #
149
+ # * `JSON_API_V1` - The payload will be a UTF-8 string containing the
150
+ # [resource
151
+ # representation](https://cloud.google.com/storage/docs/json_api/v1/objects#resource-representations)
152
+ # of the file's metadata.
153
+ # * `NONE` - No payload is included with the notification.
154
+ #
155
+ def payload
156
+ @gapi.payload_format
157
+ end
158
+
159
+ ##
160
+ # The Cloud Pub/Sub topic to which this subscription publishes.
161
+ # Formatted as:
162
+ # `//pubsub.googleapis.com/projects/{project-id}/topics/{my-topic}`
163
+ def topic
164
+ @gapi.topic
165
+ end
166
+
167
+ ##
168
+ # Permanently deletes the notification.
169
+ #
170
+ # The API call to delete the notification may be retried under certain
171
+ # conditions. See {Google::Cloud#storage} to control this behavior.
172
+ #
173
+ # @return [Boolean] Returns `true` if the notification was deleted.
174
+ #
175
+ # @example
176
+ # require "google/cloud/storage"
177
+ #
178
+ # storage = Google::Cloud::Storage.new
179
+ #
180
+ # bucket = storage.bucket "my-bucket"
181
+ # notification = bucket.notification "1"
182
+ # notification.delete
183
+ #
184
+ def delete
185
+ ensure_service!
186
+ @service.delete_notification bucket, id, user_project: @user_project
187
+ true
188
+ end
189
+
190
+ ##
191
+ # @private New Notification from a
192
+ # Google::Apis::StorageV1::Notification object.
193
+ def self.from_gapi bucket_name, gapi, service, user_project: nil
194
+ new.tap do |f|
195
+ f.instance_variable_set :@bucket, bucket_name
196
+ f.gapi = gapi
197
+ f.service = service
198
+ f.user_project = user_project
199
+ end
200
+ end
201
+
202
+ protected
203
+
204
+ ##
205
+ # Raise an error unless an active service is available.
206
+ def ensure_service!
207
+ fail "Must have active connection" unless service
208
+ end
209
+ end
210
+ end
211
+ end
212
+ end
@@ -206,6 +206,52 @@ module Google
206
206
  end
207
207
  end
208
208
 
209
+ ##
210
+ # Retrieves a list of Pub/Sub notification subscriptions for a bucket.
211
+ def list_notifications bucket_name, user_project: nil
212
+ execute do
213
+ service.list_notifications bucket_name,
214
+ user_project: user_project(user_project)
215
+ end
216
+ end
217
+
218
+ ##
219
+ # Creates a new Pub/Sub notification subscription for a bucket.
220
+ def insert_notification bucket_name, topic_name, custom_attrs: nil,
221
+ event_types: nil, prefix: nil, payload: nil,
222
+ user_project: nil
223
+ new_notification = Google::Apis::StorageV1::Notification.new({
224
+ custom_attributes: custom_attrs,
225
+ event_types: event_types(event_types),
226
+ object_name_prefix: prefix,
227
+ payload_format: payload_format(payload),
228
+ topic: topic_path(topic_name) }.delete_if { |_k, v| v.nil? })
229
+
230
+ execute do
231
+ service.insert_notification \
232
+ bucket_name, new_notification,
233
+ user_project: user_project(user_project)
234
+ end
235
+ end
236
+
237
+ ##
238
+ # Retrieves a Pub/Sub notification subscription for a bucket.
239
+ def get_notification bucket_name, notification_id, user_project: nil
240
+ execute do
241
+ service.get_notification bucket_name, notification_id,
242
+ user_project: user_project(user_project)
243
+ end
244
+ end
245
+
246
+ ##
247
+ # Deletes a new Pub/Sub notification subscription for a bucket.
248
+ def delete_notification bucket_name, notification_id, user_project: nil
249
+ execute do
250
+ service.delete_notification bucket_name, notification_id,
251
+ user_project: user_project(user_project)
252
+ end
253
+ end
254
+
209
255
  ##
210
256
  # Retrieves a list of files matching the criteria.
211
257
  def list_files bucket_name, delimiter: nil, max: nil, token: nil,
@@ -419,6 +465,42 @@ module Google
419
465
  options
420
466
  end
421
467
 
468
+ def topic_path topic_name
469
+ return topic_name if topic_name.to_s.include? "/"
470
+ "//pubsub.googleapis.com/projects/#{project}/topics/#{topic_name}"
471
+ end
472
+
473
+ # Pub/Sub notification subscription event_types
474
+ def event_types arr
475
+ arr.map { |x| event_type x } if arr
476
+ end
477
+
478
+ # Pub/Sub notification subscription event_types
479
+ def event_type str
480
+ { "object_finalize" => "OBJECT_FINALIZE",
481
+ "finalize" => "OBJECT_FINALIZE",
482
+ "create" => "OBJECT_FINALIZE",
483
+ "object_metadata_update" => "OBJECT_METADATA_UPDATE",
484
+ "object_update" => "OBJECT_METADATA_UPDATE",
485
+ "metadata_update" => "OBJECT_METADATA_UPDATE",
486
+ "update" => "OBJECT_METADATA_UPDATE",
487
+ "object_delete" => "OBJECT_DELETE",
488
+ "delete" => "OBJECT_DELETE",
489
+ "object_archive" => "OBJECT_ARCHIVE",
490
+ "archive" => "OBJECT_ARCHIVE" }[str.to_s.downcase]
491
+ end
492
+
493
+ # Pub/Sub notification subscription payload_format
494
+ # Defaults to "JSON_API_V1"
495
+ def payload_format str_or_bool
496
+ return "JSON_API_V1" if str_or_bool.nil?
497
+ { "json_api_v1" => "JSON_API_V1",
498
+ "json" => "JSON_API_V1",
499
+ "true" => "JSON_API_V1",
500
+ "none" => "NONE",
501
+ "false" => "NONE" }[str_or_bool.to_s.downcase]
502
+ end
503
+
422
504
  def execute
423
505
  yield
424
506
  rescue Google::Apis::Error => e
@@ -16,7 +16,7 @@
16
16
  module Google
17
17
  module Cloud
18
18
  module Storage
19
- VERSION = "1.4.0"
19
+ VERSION = "1.5.0"
20
20
  end
21
21
  end
22
22
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: google-cloud-storage
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.4.0
4
+ version: 1.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Mike Moore
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2017-08-02 00:00:00.000000000 Z
12
+ date: 2017-09-26 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: google-cloud-core
@@ -203,6 +203,7 @@ files:
203
203
  - lib/google/cloud/storage/file/list.rb
204
204
  - lib/google/cloud/storage/file/signer.rb
205
205
  - lib/google/cloud/storage/file/verifier.rb
206
+ - lib/google/cloud/storage/notification.rb
206
207
  - lib/google/cloud/storage/policy.rb
207
208
  - lib/google/cloud/storage/post_object.rb
208
209
  - lib/google/cloud/storage/project.rb
@@ -228,7 +229,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
228
229
  version: '0'
229
230
  requirements: []
230
231
  rubyforge_project:
231
- rubygems_version: 2.6.12
232
+ rubygems_version: 2.6.13
232
233
  signing_key:
233
234
  specification_version: 4
234
235
  summary: API Client library for Google Cloud Storage