gcloud 0.4.1 → 0.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.
Files changed (45) hide show
  1. checksums.yaml +8 -8
  2. data/CHANGELOG.md +15 -0
  3. data/OVERVIEW.md +38 -5
  4. data/lib/gcloud.rb +55 -4
  5. data/lib/gcloud/bigquery/data.rb +2 -0
  6. data/lib/gcloud/bigquery/dataset.rb +1 -1
  7. data/lib/gcloud/bigquery/dataset/list.rb +2 -0
  8. data/lib/gcloud/bigquery/job/list.rb +2 -0
  9. data/lib/gcloud/bigquery/project.rb +2 -9
  10. data/lib/gcloud/bigquery/table/list.rb +2 -0
  11. data/lib/gcloud/datastore.rb +23 -28
  12. data/lib/gcloud/datastore/connection.rb +3 -1
  13. data/lib/gcloud/datastore/dataset.rb +167 -22
  14. data/lib/gcloud/datastore/dataset/lookup_results.rb +2 -0
  15. data/lib/gcloud/datastore/dataset/query_results.rb +2 -0
  16. data/lib/gcloud/datastore/entity.rb +11 -11
  17. data/lib/gcloud/datastore/key.rb +33 -16
  18. data/lib/gcloud/dns/change/list.rb +2 -0
  19. data/lib/gcloud/dns/project.rb +1 -1
  20. data/lib/gcloud/dns/record/list.rb +2 -0
  21. data/lib/gcloud/dns/zone.rb +2 -2
  22. data/lib/gcloud/dns/zone/list.rb +2 -0
  23. data/lib/gcloud/gce.rb +0 -5
  24. data/lib/gcloud/pubsub.rb +65 -62
  25. data/lib/gcloud/pubsub/connection.rb +20 -2
  26. data/lib/gcloud/pubsub/project.rb +233 -72
  27. data/lib/gcloud/pubsub/subscription.rb +45 -13
  28. data/lib/gcloud/pubsub/subscription/list.rb +2 -0
  29. data/lib/gcloud/pubsub/topic.rb +66 -85
  30. data/lib/gcloud/pubsub/topic/list.rb +2 -0
  31. data/lib/gcloud/resource_manager.rb +244 -0
  32. data/lib/gcloud/resource_manager/connection.rb +124 -0
  33. data/lib/gcloud/resource_manager/credentials.rb +30 -0
  34. data/lib/gcloud/resource_manager/errors.rb +64 -0
  35. data/lib/gcloud/resource_manager/manager.rb +319 -0
  36. data/lib/gcloud/resource_manager/project.rb +529 -0
  37. data/lib/gcloud/resource_manager/project/list.rb +91 -0
  38. data/lib/gcloud/resource_manager/project/updater.rb +137 -0
  39. data/lib/gcloud/storage/bucket.rb +1 -1
  40. data/lib/gcloud/storage/bucket/cors.rb +2 -0
  41. data/lib/gcloud/storage/bucket/list.rb +2 -0
  42. data/lib/gcloud/storage/file/list.rb +2 -0
  43. data/lib/gcloud/storage/project.rb +1 -1
  44. data/lib/gcloud/version.rb +1 -1
  45. metadata +10 -2
@@ -101,6 +101,14 @@ module Gcloud
101
101
  )
102
102
  end
103
103
 
104
+ def test_topic_permissions topic_name, permissions, options = {}
105
+ @client.execute(
106
+ api_method: @pubsub.projects.topics.test_iam_permissions,
107
+ parameters: { resource: topic_path(topic_name, options) },
108
+ body_object: { permissions: permissions }
109
+ )
110
+ end
111
+
104
112
  ##
105
113
  # Creates a subscription on a given topic for a given subscriber.
106
114
  def create_subscription topic, subscription_name, options = {}
@@ -177,6 +185,16 @@ module Gcloud
177
185
  )
178
186
  end
179
187
 
188
+ def test_subscription_permissions subscription_name,
189
+ permissions, options = {}
190
+ @client.execute(
191
+ api_method: @pubsub.projects.subscriptions.test_iam_permissions,
192
+ parameters: {
193
+ resource: subscription_path(subscription_name, options) },
194
+ body_object: { permissions: permissions }
195
+ )
196
+ end
197
+
180
198
  ##
181
199
  # Adds one or more messages to the topic.
182
200
  # Returns NOT_FOUND if the topic does not exist.
@@ -188,7 +206,7 @@ module Gcloud
188
206
  end
189
207
  @client.execute(
190
208
  api_method: @pubsub.projects.topics.publish,
191
- parameters: { topic: topic },
209
+ parameters: { topic: topic_path(topic) },
192
210
  body_object: { messages: gapi_msgs }
193
211
  )
194
212
  end
@@ -264,7 +282,7 @@ module Gcloud
264
282
  endpoint = options[:endpoint]
265
283
  attributes = hashify options[:attributes]
266
284
 
267
- data = { topic: topic }
285
+ data = { topic: topic_path(topic) }
268
286
  data[:ackDeadlineSeconds] = deadline if deadline
269
287
  if endpoint
270
288
  data[:pushConfig] = { pushEndpoint: endpoint,
@@ -80,42 +80,6 @@ module Gcloud
80
80
 
81
81
  ##
82
82
  # Retrieves topic by name.
83
- # The difference between this method and Project#topic is that this
84
- # method makes an API call to Pub/Sub to verify the topic exists.
85
- #
86
- # === Parameters
87
- #
88
- # +topic_name+::
89
- # Name of a topic. (+String+)
90
- #
91
- # === Returns
92
- #
93
- # Gcloud::Pubsub::Topic or nil if topic does not exist
94
- #
95
- # === Example
96
- #
97
- # require "gcloud"
98
- #
99
- # gcloud = Gcloud.new
100
- # pubsub = gcloud.pubsub
101
- # topic = pubsub.get_topic "my-topic"
102
- #
103
- def get_topic topic_name
104
- ensure_connection!
105
- resp = connection.get_topic topic_name
106
- if resp.success?
107
- Topic.from_gapi resp.data, connection
108
- else
109
- return nil if resp.data["error"]["code"] == 404
110
- fail ApiError.from_response(resp)
111
- end
112
- end
113
- alias_method :find_topic, :get_topic
114
-
115
- ##
116
- # Retrieves topic by name.
117
- # The difference between this method and Project#get_topic is that this
118
- # method does not make an API call to Pub/Sub to verify the topic exists.
119
83
  #
120
84
  # === Parameters
121
85
  #
@@ -124,16 +88,24 @@ module Gcloud
124
88
  # +options+::
125
89
  # An optional Hash for controlling additional behavior. (+Hash+)
126
90
  # <code>options[:autocreate]</code>::
127
- # Flag to control whether the topic should be created when needed.
128
- # The default value is +true+. (+Boolean+)
91
+ # Flag to control whether the requested topic will be created if it does
92
+ # not exist. Ignored if +skip_lookup+ is +true+. The default value is
93
+ # +false+. (+Boolean+)
129
94
  # <code>options[:project]</code>::
130
95
  # If the topic belongs to a project other than the one currently
131
96
  # connected to, the alternate project ID can be specified here.
132
97
  # (+String+)
98
+ # <code>options[:skip_lookup]</code>::
99
+ # Optionally create a Topic object without verifying the topic resource
100
+ # exists on the Pub/Sub service. Calls made on this object will raise
101
+ # errors if the topic resource does not exist. Default is +false+.
102
+ # (+Boolean+)
133
103
  #
134
104
  # === Returns
135
105
  #
136
- # Gcloud::Pubsub::Topic
106
+ # Gcloud::Pubsub::Topic or nil if topic does not exist. Will return a
107
+ # newly created Gcloud::Pubsub::Topic if the topic does not exist and
108
+ # +autocreate+ is set to +true+.
137
109
  #
138
110
  # === Examples
139
111
  #
@@ -142,25 +114,24 @@ module Gcloud
142
114
  # gcloud = Gcloud.new
143
115
  # pubsub = gcloud.pubsub
144
116
  # topic = pubsub.topic "existing-topic"
145
- # msg = topic.publish "This is the first API call to Pub/Sub."
146
117
  #
147
- # By default the topic will be created in Pub/Sub when needed.
118
+ # By default +nil+ will be returned if the topic does not exist.
119
+ # the topic will be created in Pub/Sub when needed.
148
120
  #
149
121
  # require "gcloud"
150
122
  #
151
123
  # gcloud = Gcloud.new
152
124
  # pubsub = gcloud.pubsub
153
- # topic = pubsub.topic "non-existing-topic"
154
- # msg = topic.publish "This will create the topic in Pub/Sub."
125
+ # topic = pubsub.topic "non-existing-topic" #=> nil
155
126
  #
156
- # Setting the +autocomplete+ flag to false will not create the topic.
127
+ # The topic will be created if the topic does not exist and the
128
+ # +autocreate+ option is set to true.
157
129
  #
158
130
  # require "gcloud"
159
131
  #
160
132
  # gcloud = Gcloud.new
161
133
  # pubsub = gcloud.pubsub
162
- # topic = pubsub.topic "non-existing-topic"
163
- # msg = topic.publish "This raises." #=> Gcloud::Pubsub::NotFoundError
134
+ # topic = pubsub.topic "non-existing-topic", autocreate: true
164
135
  #
165
136
  # A topic in a different project can be created using the +project+ flag.
166
137
  #
@@ -170,11 +141,30 @@ module Gcloud
170
141
  # pubsub = gcloud.pubsub
171
142
  # topic = pubsub.topic "another-topic", project: "another-project"
172
143
  #
144
+ # The lookup against the Pub/Sub service can be skipped using the
145
+ # +skip_lookup+ option:
146
+ #
147
+ # require "gcloud"
148
+ #
149
+ # gcloud = Gcloud.new
150
+ # pubsub = gcloud.pubsub
151
+ # topic = pubsub.topic "another-topic", skip_lookup: true
152
+ #
173
153
  def topic topic_name, options = {}
174
154
  ensure_connection!
175
-
176
- Topic.new_lazy topic_name, connection, options
155
+ if options[:skip_lookup]
156
+ return Topic.new_lazy(topic_name, connection, options)
157
+ end
158
+ resp = connection.get_topic topic_name
159
+ return Topic.from_gapi(resp.data, connection) if resp.success?
160
+ if resp.status == 404
161
+ return create_topic(topic_name) if options[:autocreate]
162
+ return nil
163
+ end
164
+ fail ApiError.from_response(resp)
177
165
  end
166
+ alias_method :get_topic, :topic
167
+ alias_method :find_topic, :topic
178
168
 
179
169
  ##
180
170
  # Creates a new topic.
@@ -224,7 +214,7 @@ module Gcloud
224
214
  #
225
215
  # === Returns
226
216
  #
227
- # Array of Gcloud::Pubsub::Topic (Gcloud::Pubsub::Topic::List)
217
+ # Array of Gcloud::Pubsub::Topic (See Gcloud::Pubsub::Topic::List)
228
218
  #
229
219
  # === Examples
230
220
  #
@@ -271,46 +261,189 @@ module Gcloud
271
261
  alias_method :list_topics, :topics
272
262
 
273
263
  ##
274
- # Retrieves subscription by name.
275
- # The difference between this method and Project#get_subscription is
276
- # that this method does not make an API call to Pub/Sub to verify the
277
- # subscription exists.
264
+ # Publishes one or more messages to the given topic.
278
265
  #
279
266
  # === Parameters
280
267
  #
268
+ # +topic_name+::
269
+ # Name of a topic. (+String+)
270
+ # +data+::
271
+ # The message data. (+String+)
272
+ # +attributes+::
273
+ # Optional attributes for the message. (+Hash+)
274
+ # <code>attributes[:autocreate]</code>::
275
+ # Flag to control whether the provided topic will be created if it does
276
+ # not exist.
277
+ #
278
+ # === Returns
279
+ #
280
+ # Message object when called without a block,
281
+ # Array of Message objects when called with a block
282
+ #
283
+ # === Examples
284
+ #
285
+ # require "gcloud"
286
+ #
287
+ # gcloud = Gcloud.new
288
+ # pubsub = gcloud.pubsub
289
+ #
290
+ # msg = pubsub.publish "my-topic", "new-message"
291
+ #
292
+ # Additionally, a message can be published with attributes:
293
+ #
294
+ # require "gcloud"
295
+ #
296
+ # gcloud = Gcloud.new
297
+ # pubsub = gcloud.pubsub
298
+ #
299
+ # msg = pubsub.publish "my-topic", "new-message", foo: :bar,
300
+ # this: :that
301
+ #
302
+ # Multiple messages can be published at the same time by passing a block:
303
+ #
304
+ # require "gcloud"
305
+ #
306
+ # gcloud = Gcloud.new
307
+ # pubsub = gcloud.pubsub
308
+ #
309
+ # msgs = pubsub.publish "my-topic" do |batch|
310
+ # batch.publish "new-message-1", foo: :bar
311
+ # batch.publish "new-message-2", foo: :baz
312
+ # batch.publish "new-message-3", foo: :bif
313
+ # end
314
+ #
315
+ # Additionally, the topic will be created if the topic does previously not
316
+ # exist and the +autocreate+ option is provided.
317
+ #
318
+ # require "gcloud"
319
+ #
320
+ # gcloud = Gcloud.new
321
+ # pubsub = gcloud.pubsub
322
+ #
323
+ # msg = pubsub.publish "new-topic", "new-message", autocreate: true
324
+ #
325
+ # A note about auto-creating the topic: Any message published to a topic
326
+ # without a subscription will be lost.
327
+ #
328
+ def publish topic_name, data = nil, attributes = {}
329
+ # Fix parameters
330
+ if data.is_a?(::Hash) && attributes.empty?
331
+ attributes = data
332
+ data = nil
333
+ end
334
+ # extract autocreate option
335
+ autocreate = attributes.delete :autocreate
336
+ ensure_connection!
337
+ batch = Topic::Batch.new data, attributes
338
+ yield batch if block_given?
339
+ return nil if batch.messages.count.zero?
340
+ publish_batch_messages topic_name, batch, autocreate
341
+ end
342
+
343
+ ##
344
+ # Creates a new Subscription object for the provided topic.
345
+ #
346
+ # === Parameters
347
+ #
348
+ # +topic_name+::
349
+ # Name of a topic. (+String+)
281
350
  # +subscription_name+::
282
- # Name of a subscription. (+String+)
351
+ # Name of the new subscription. Must start with a letter, and contain
352
+ # only letters ([A-Za-z]), numbers ([0-9], dashes (-), underscores (_),
353
+ # periods (.), tildes (~), plus (+) or percent signs (%). It must be
354
+ # between 3 and 255 characters in length, and it must not start with
355
+ # "goog". (+String+)
356
+ # +options+::
357
+ # An optional Hash for controlling additional behavior. (+Hash+)
358
+ # <code>options[:deadline]</code>::
359
+ # The maximum number of seconds after a subscriber receives a message
360
+ # before the subscriber should acknowledge the message. (+Integer+)
361
+ # <code>options[:endpoint]</code>::
362
+ # A URL locating the endpoint to which messages should be pushed.
363
+ # e.g. "https://example.com/push" (+String+)
364
+ # <code>attributes[:autocreate]</code>::
365
+ # Flag to control whether the topic will be created if it does not
366
+ # exist.
283
367
  #
284
368
  # === Returns
285
369
  #
286
370
  # Gcloud::Pubsub::Subscription
287
371
  #
288
- # === Example
372
+ # === Examples
289
373
  #
290
374
  # require "gcloud"
291
375
  #
292
376
  # gcloud = Gcloud.new
293
377
  # pubsub = gcloud.pubsub
294
378
  #
295
- # subscription = pubsub.get_subscription "my-topic-subscription"
296
- # puts subscription.name
379
+ # sub = pubsub.subscribe "my-topic", "my-topic-sub"
380
+ # puts sub.name # => "my-topic-sub"
381
+ #
382
+ # The name is optional, and will be generated if not given.
383
+ #
384
+ # require "gcloud"
385
+ #
386
+ # gcloud = Gcloud.new
387
+ # pubsub = gcloud.pubsub
388
+ #
389
+ # sub = pubsub.subscribe "my-topic"
390
+ # puts sub.name # => "generated-sub-name"
391
+ #
392
+ # The subscription can be created that waits two minutes for
393
+ # acknowledgement and pushed all messages to an endpoint
394
+ #
395
+ # require "gcloud"
396
+ #
397
+ # gcloud = Gcloud.new
398
+ # pubsub = gcloud.pubsub
297
399
  #
298
- def subscription subscription_name
400
+ # sub = pubsub.subscribe "my-topic", "my-topic-sub",
401
+ # deadline: 120,
402
+ # endpoint: "https://example.com/push"
403
+ #
404
+ # Additionally, the topic will be created if the topic does previously not
405
+ # exist and the +autocreate+ option is provided.
406
+ #
407
+ # require "gcloud"
408
+ #
409
+ # gcloud = Gcloud.new
410
+ # pubsub = gcloud.pubsub
411
+ #
412
+ # sub = pubsub.subscribe "new-topic", "new-topic-sub", autocreate: true
413
+ #
414
+ def subscribe topic_name, subscription_name, options = {}
299
415
  ensure_connection!
300
-
301
- Subscription.new_lazy subscription_name, connection
416
+ resp = connection.create_subscription topic_name,
417
+ subscription_name, options
418
+ return Subscription.from_gapi(resp.data, connection) if resp.success?
419
+ if options[:autocreate] && resp.status == 404
420
+ create_topic topic_name
421
+ return subscribe(topic_name, subscription_name,
422
+ options.merge(autocreate: false))
423
+ end
424
+ fail ApiError.from_response(resp)
302
425
  end
426
+ alias_method :create_subscription, :subscribe
427
+ alias_method :new_subscription, :subscribe
303
428
 
304
429
  ##
305
430
  # Retrieves subscription by name.
306
- # The difference between this method and Project#subscription is that
307
- # this method makes an API call to Pub/Sub to verify the subscription
308
- # exists.
309
431
  #
310
432
  # === Parameters
311
433
  #
312
434
  # +subscription_name+::
313
435
  # Name of a subscription. (+String+)
436
+ # +options+::
437
+ # An optional Hash for controlling additional behavior. (+Hash+)
438
+ # <code>options[:project]</code>::
439
+ # If the subscription belongs to a project other than the one currently
440
+ # connected to, the alternate project ID can be specified here.
441
+ # (+String+)
442
+ # <code>options[:skip_lookup]</code>::
443
+ # Optionally create a Subscription object without verifying the
444
+ # subscription resource exists on the Pub/Sub service. Calls made on
445
+ # this object will raise errors if the service resource does not exist.
446
+ # Default is +false+. (+Boolean+)
314
447
  #
315
448
  # === Returns
316
449
  #
@@ -323,19 +456,33 @@ module Gcloud
323
456
  # gcloud = Gcloud.new
324
457
  # pubsub = gcloud.pubsub
325
458
  #
326
- # subscription = pubsub.get_subscription "my-topic-subscription"
459
+ # subscription = pubsub.subscription "my-sub"
460
+ # puts subscription.name
461
+ #
462
+ # The lookup against the Pub/Sub service can be skipped using the
463
+ # +skip_lookup+ option:
464
+ #
465
+ # require "gcloud"
466
+ #
467
+ # gcloud = Gcloud.new
468
+ # pubsub = gcloud.pubsub
469
+ #
470
+ # # No API call is made to retrieve the subscription information.
471
+ # subscription = pubsub.subscription "my-sub", skip_lookup: true
327
472
  # puts subscription.name
328
473
  #
329
- def get_subscription subscription_name
474
+ def subscription subscription_name, options = {}
330
475
  ensure_connection!
331
- resp = connection.get_subscription subscription_name
332
- if resp.success?
333
- Subscription.from_gapi resp.data, connection
334
- else
335
- nil
476
+ if options[:skip_lookup]
477
+ return Subscription.new_lazy(subscription_name, connection, options)
336
478
  end
479
+ resp = connection.get_subscription subscription_name
480
+ return Subscription.from_gapi(resp.data, connection) if resp.success?
481
+ return nil if resp.status == 404
482
+ fail ApiError.from_response(resp)
337
483
  end
338
- alias_method :find_subscription, :get_subscription
484
+ alias_method :get_subscription, :subscription
485
+ alias_method :find_subscription, :subscription
339
486
 
340
487
  ##
341
488
  # Retrieves a list of subscriptions for the given project.
@@ -356,7 +503,7 @@ module Gcloud
356
503
  # === Returns
357
504
  #
358
505
  # Array of Gcloud::Pubsub::Subscription
359
- # (Gcloud::Pubsub::Subscription::List)
506
+ # (See Gcloud::Pubsub::Subscription::List)
360
507
  #
361
508
  # === Examples
362
509
  #
@@ -409,6 +556,20 @@ module Gcloud
409
556
  def ensure_connection!
410
557
  fail "Must have active connection" unless connection
411
558
  end
559
+
560
+ ##
561
+ # Call the publish API with arrays of data data and attrs.
562
+ def publish_batch_messages topic_name, batch, autocreate = false
563
+ resp = connection.publish topic_name, batch.messages
564
+ if resp.success?
565
+ batch.to_gcloud_messages resp.data["messageIds"]
566
+ elsif autocreate && resp.status == 404
567
+ create_topic topic_name
568
+ publish_batch_messages topic_name, batch, false
569
+ else
570
+ fail ApiError.from_response(resp)
571
+ end
572
+ end
412
573
  end
413
574
  end
414
575
  end