gcloud 0.11.0 → 0.12.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 (121) hide show
  1. checksums.yaml +8 -8
  2. data/AUTHENTICATION.md +3 -3
  3. data/CHANGELOG.md +92 -0
  4. data/OVERVIEW.md +3 -3
  5. data/lib/gcloud.rb +75 -25
  6. data/lib/gcloud/backoff.rb +5 -1
  7. data/lib/gcloud/bigquery.rb +25 -43
  8. data/lib/gcloud/bigquery/copy_job.rb +13 -13
  9. data/lib/gcloud/bigquery/data.rb +20 -16
  10. data/lib/gcloud/bigquery/dataset.rb +202 -177
  11. data/lib/gcloud/bigquery/dataset/access.rb +118 -104
  12. data/lib/gcloud/bigquery/dataset/list.rb +14 -18
  13. data/lib/gcloud/bigquery/extract_job.rb +12 -12
  14. data/lib/gcloud/bigquery/insert_response.rb +12 -14
  15. data/lib/gcloud/bigquery/job.rb +45 -57
  16. data/lib/gcloud/bigquery/job/list.rb +18 -24
  17. data/lib/gcloud/bigquery/load_job.rb +35 -27
  18. data/lib/gcloud/bigquery/project.rb +53 -73
  19. data/lib/gcloud/bigquery/query_data.rb +28 -35
  20. data/lib/gcloud/bigquery/query_job.rb +18 -18
  21. data/lib/gcloud/bigquery/schema.rb +359 -0
  22. data/lib/gcloud/bigquery/service.rb +506 -0
  23. data/lib/gcloud/bigquery/table.rb +185 -266
  24. data/lib/gcloud/bigquery/table/list.rb +15 -19
  25. data/lib/gcloud/bigquery/view.rb +126 -81
  26. data/lib/gcloud/datastore.rb +39 -27
  27. data/lib/gcloud/datastore/commit.rb +2 -2
  28. data/lib/gcloud/datastore/dataset.rb +8 -19
  29. data/lib/gcloud/datastore/dataset/lookup_results.rb +2 -4
  30. data/lib/gcloud/datastore/dataset/query_results.rb +0 -2
  31. data/lib/gcloud/datastore/entity.rb +7 -1
  32. data/lib/gcloud/datastore/errors.rb +5 -27
  33. data/lib/gcloud/datastore/grpc_utils.rb +4 -3
  34. data/lib/gcloud/datastore/key.rb +6 -0
  35. data/lib/gcloud/datastore/service.rb +18 -12
  36. data/lib/gcloud/datastore/transaction.rb +0 -10
  37. data/lib/gcloud/dns.rb +29 -19
  38. data/lib/gcloud/dns/change.rb +10 -15
  39. data/lib/gcloud/dns/change/list.rb +4 -4
  40. data/lib/gcloud/dns/importer.rb +1 -1
  41. data/lib/gcloud/dns/project.rb +32 -49
  42. data/lib/gcloud/dns/record.rb +8 -2
  43. data/lib/gcloud/dns/record/list.rb +4 -4
  44. data/lib/gcloud/dns/service.rb +167 -0
  45. data/lib/gcloud/dns/zone.rb +33 -52
  46. data/lib/gcloud/dns/zone/list.rb +12 -16
  47. data/lib/gcloud/errors.rb +31 -19
  48. data/lib/gcloud/logging.rb +50 -39
  49. data/lib/gcloud/logging/entry.rb +197 -24
  50. data/lib/gcloud/logging/entry/list.rb +0 -2
  51. data/lib/gcloud/logging/logger.rb +1 -1
  52. data/lib/gcloud/logging/metric.rb +3 -9
  53. data/lib/gcloud/logging/metric/list.rb +0 -2
  54. data/lib/gcloud/logging/project.rb +58 -54
  55. data/lib/gcloud/logging/resource_descriptor.rb +2 -2
  56. data/lib/gcloud/logging/resource_descriptor/list.rb +0 -2
  57. data/lib/gcloud/logging/service.rb +32 -23
  58. data/lib/gcloud/logging/sink.rb +8 -14
  59. data/lib/gcloud/logging/sink/list.rb +0 -2
  60. data/lib/gcloud/pubsub.rb +21 -16
  61. data/lib/gcloud/pubsub/policy.rb +204 -0
  62. data/lib/gcloud/pubsub/project.rb +26 -38
  63. data/lib/gcloud/pubsub/service.rb +39 -31
  64. data/lib/gcloud/pubsub/subscription.rb +56 -59
  65. data/lib/gcloud/pubsub/subscription/list.rb +4 -4
  66. data/lib/gcloud/pubsub/topic.rb +69 -66
  67. data/lib/gcloud/pubsub/topic/list.rb +0 -2
  68. data/lib/gcloud/pubsub/topic/{batch.rb → publisher.rb} +15 -2
  69. data/lib/gcloud/resource_manager.rb +27 -26
  70. data/lib/gcloud/resource_manager/manager.rb +19 -39
  71. data/lib/gcloud/resource_manager/policy.rb +211 -0
  72. data/lib/gcloud/resource_manager/project.rb +97 -121
  73. data/lib/gcloud/resource_manager/project/list.rb +7 -7
  74. data/lib/gcloud/resource_manager/project/updater.rb +4 -9
  75. data/lib/gcloud/resource_manager/service.rb +127 -0
  76. data/lib/gcloud/storage.rb +24 -42
  77. data/lib/gcloud/storage/bucket.rb +104 -192
  78. data/lib/gcloud/storage/bucket/acl.rb +47 -143
  79. data/lib/gcloud/storage/bucket/cors.rb +55 -11
  80. data/lib/gcloud/storage/bucket/list.rb +14 -14
  81. data/lib/gcloud/storage/errors.rb +3 -43
  82. data/lib/gcloud/storage/file.rb +114 -111
  83. data/lib/gcloud/storage/file/acl.rb +27 -113
  84. data/lib/gcloud/storage/file/list.rb +21 -21
  85. data/lib/gcloud/storage/project.rb +49 -59
  86. data/lib/gcloud/storage/service.rb +347 -0
  87. data/lib/gcloud/translate.rb +24 -14
  88. data/lib/gcloud/translate/api.rb +12 -21
  89. data/lib/gcloud/translate/detection.rb +5 -5
  90. data/lib/gcloud/translate/language.rb +1 -1
  91. data/lib/gcloud/translate/service.rb +80 -0
  92. data/lib/gcloud/translate/translation.rb +6 -6
  93. data/lib/gcloud/version.rb +1 -1
  94. data/lib/gcloud/vision.rb +24 -15
  95. data/lib/gcloud/vision/annotate.rb +24 -21
  96. data/lib/gcloud/vision/annotation.rb +9 -9
  97. data/lib/gcloud/vision/annotation/entity.rb +11 -11
  98. data/lib/gcloud/vision/annotation/face.rb +25 -25
  99. data/lib/gcloud/vision/annotation/properties.rb +8 -8
  100. data/lib/gcloud/vision/annotation/safe_search.rb +4 -4
  101. data/lib/gcloud/vision/annotation/text.rb +7 -7
  102. data/lib/gcloud/vision/annotation/vertex.rb +1 -1
  103. data/lib/gcloud/vision/image.rb +11 -11
  104. data/lib/gcloud/vision/location.rb +5 -2
  105. data/lib/gcloud/vision/project.rb +14 -16
  106. data/lib/gcloud/vision/service.rb +66 -0
  107. data/lib/google/api_client.rb +0 -0
  108. metadata +27 -24
  109. data/lib/gcloud/bigquery/connection.rb +0 -624
  110. data/lib/gcloud/bigquery/errors.rb +0 -68
  111. data/lib/gcloud/bigquery/table/schema.rb +0 -234
  112. data/lib/gcloud/dns/connection.rb +0 -173
  113. data/lib/gcloud/dns/errors.rb +0 -68
  114. data/lib/gcloud/resource_manager/connection.rb +0 -134
  115. data/lib/gcloud/resource_manager/errors.rb +0 -68
  116. data/lib/gcloud/storage/connection.rb +0 -444
  117. data/lib/gcloud/translate/connection.rb +0 -85
  118. data/lib/gcloud/translate/errors.rb +0 -68
  119. data/lib/gcloud/upload.rb +0 -95
  120. data/lib/gcloud/vision/connection.rb +0 -63
  121. data/lib/gcloud/vision/errors.rb +0 -69
@@ -0,0 +1,211 @@
1
+ # Copyright 2016 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
+ require "google/apis/cloudresourcemanager_v1beta1"
18
+
19
+ module Gcloud
20
+ module ResourceManager
21
+ ##
22
+ # # Policy
23
+ #
24
+ # Represents a Cloud IAM Policy for the Resource Manager service.
25
+ #
26
+ # A common pattern for updating a resource's metadata, such as its Policy,
27
+ # is to read the current data from the service, update the data locally, and
28
+ # then send the modified data for writing. This pattern may result in a
29
+ # conflict if two or more processes attempt the sequence simultaneously. IAM
30
+ # solves this problem with the {Gcloud::ResourceManager::Policy#etag}
31
+ # property, which is used to verify whether the policy has changed since the
32
+ # last request. When you make a request to with an `etag` value, Cloud IAM
33
+ # compares the `etag` value in the request with the existing `etag` value
34
+ # associated with the policy. It writes the policy only if the `etag` values
35
+ # match.
36
+ #
37
+ # When you update a policy, first read the policy (and its current `etag`)
38
+ # from the service, then modify the policy locally, and then write the
39
+ # modified policy to the service. See
40
+ # {Gcloud::ResourceManager::Project#policy} and
41
+ # {Gcloud::ResourceManager::Project#policy=}.
42
+ #
43
+ # @see https://cloud.google.com/iam/docs/managing-policies Managing policies
44
+ # @see https://cloud.google.com/resource-manager/reference/rest/v1beta1/projects/setIamPolicy
45
+ # projects.setIamPolicy
46
+ #
47
+ # @attr [String] etag Used to verify whether the policy has changed since
48
+ # the last request. The policy will be written only if the `etag` values
49
+ # match.
50
+ # @attr [Hash{String => Array<String>}] roles The bindings that associate
51
+ # roles with an array of members. See [Understanding
52
+ # Roles](https://cloud.google.com/iam/docs/understanding-roles) for a
53
+ # listing of primitive and curated roles.
54
+ # See [Binding](https://cloud.google.com/resource-manager/reference/rpc/google.iam.v1#binding)
55
+ # for a listing of values and patterns for members.
56
+ #
57
+ # @example
58
+ # require "gcloud"
59
+ #
60
+ # gcloud = Gcloud.new
61
+ # resource_manager = gcloud.resource_manager
62
+ # project = resource_manager.project "tokyo-rain-123"
63
+ #
64
+ # policy = project.policy # API call
65
+ #
66
+ # policy.remove "roles/owner", "user:owner@example.com" # Local call
67
+ # policy.add "roles/owner", "user:newowner@example.com" # Local call
68
+ # policy.roles["roles/viewer"] = ["allUsers"] # Local call
69
+ #
70
+ # project.policy = policy # API call
71
+ #
72
+ class Policy
73
+ ##
74
+ # Alias to the Google Client API module
75
+ API = Google::Apis::CloudresourcemanagerV1
76
+
77
+ attr_reader :etag, :roles
78
+
79
+ ##
80
+ # @private Creates a Policy object.
81
+ def initialize etag, roles
82
+ @etag = etag
83
+ @roles = roles
84
+ end
85
+
86
+ ##
87
+ # Convenience method for adding a member to a binding on this policy.
88
+ # See [Understanding
89
+ # Roles](https://cloud.google.com/iam/docs/understanding-roles) for a
90
+ # listing of primitive and curated roles.
91
+ # See [Binding](https://cloud.google.com/resource-manager/reference/rpc/google.iam.v1#binding)
92
+ # for a listing of values and patterns for members.
93
+ #
94
+ # @param [String] role_name A Cloud IAM role, such as `"roles/owner"`.
95
+ # @param [String] member A Cloud IAM identity, such as
96
+ # `"user:owner@example.com"`.
97
+ #
98
+ # @example
99
+ # require "gcloud"
100
+ #
101
+ # gcloud = Gcloud.new
102
+ # resource_manager = gcloud.resource_manager
103
+ # project = resource_manager.project "tokyo-rain-123"
104
+ #
105
+ # policy = project.policy # API call
106
+ #
107
+ # policy.add "roles/owner", "user:newowner@example.com" # Local call
108
+ #
109
+ # project.policy = policy # API call
110
+ #
111
+ def add role_name, member
112
+ role(role_name) << member
113
+ end
114
+
115
+ ##
116
+ # Convenience method for removing a member from a binding on this policy.
117
+ # See [Understanding
118
+ # Roles](https://cloud.google.com/iam/docs/understanding-roles) for a
119
+ # listing of primitive and curated roles.
120
+ # See [Binding](https://cloud.google.com/resource-manager/reference/rpc/google.iam.v1#binding)
121
+ # for a listing of values and patterns for members.
122
+ #
123
+ # @param [String] role_name A Cloud IAM role, such as `"roles/owner"`.
124
+ # @param [String] member A Cloud IAM identity, such as
125
+ # `"user:owner@example.com"`.
126
+ #
127
+ # @example
128
+ # require "gcloud"
129
+ #
130
+ # gcloud = Gcloud.new
131
+ # resource_manager = gcloud.resource_manager
132
+ # project = resource_manager.project "tokyo-rain-123"
133
+ #
134
+ # policy = project.policy # API call
135
+ #
136
+ # policy.remove "roles/owner", "user:owner@example.com" # Local call
137
+ #
138
+ # project.policy = policy # API call
139
+ #
140
+ def remove role_name, member
141
+ role(role_name).delete member
142
+ end
143
+
144
+ ##
145
+ # Convenience method returning the array of members bound to a role in
146
+ # this policy, or an empty array if no value is present for the role in
147
+ # {#roles}. See [Understanding
148
+ # Roles](https://cloud.google.com/iam/docs/understanding-roles) for a
149
+ # listing of primitive and curated roles. See
150
+ # [Binding](https://cloud.google.com/resource-manager/reference/rpc/google.iam.v1#binding)
151
+ # for a listing of values and patterns for members.
152
+ #
153
+ # @return [Array<String>] The members strings, or an empty array.
154
+ #
155
+ # @example
156
+ # require "gcloud"
157
+ #
158
+ # gcloud = Gcloud.new
159
+ # resource_manager = gcloud.resource_manager
160
+ # project = resource_manager.project "tokyo-rain-123"
161
+ #
162
+ # policy = project.policy
163
+ #
164
+ # policy.role("roles/viewer") << "user:viewer@example.com"
165
+ #
166
+ def role role_name
167
+ roles[role_name] ||= []
168
+ end
169
+
170
+ ##
171
+ # Returns a deep copy of the policy.
172
+ #
173
+ # @return [Policy]
174
+ #
175
+ def deep_dup
176
+ dup.tap do |p|
177
+ roles_dup = p.roles.each_with_object({}) do |(k, v), memo|
178
+ memo[k] = v.dup rescue value
179
+ end
180
+ p.instance_variable_set "@roles", roles_dup
181
+ end
182
+ end
183
+
184
+ ##
185
+ # @private Convert the Policy to a
186
+ # Google::Apis::CloudresourcemanagerV1::Policy.
187
+ def to_gapi
188
+ API::Policy.new(
189
+ etag: etag,
190
+ bindings: roles.keys.map do |role_name|
191
+ next if roles[role_name].empty?
192
+ API::Binding.new(
193
+ role: role_name,
194
+ members: roles[role_name]
195
+ )
196
+ end
197
+ )
198
+ end
199
+
200
+ ##
201
+ # @private New Policy from a
202
+ # Google::Apis::CloudresourcemanagerV1::Policy object.
203
+ def self.from_gapi gapi
204
+ roles = gapi.bindings.each_with_object({}) do |binding, memo|
205
+ memo[binding.role] = binding.members.to_a
206
+ end
207
+ new gapi.etag, roles
208
+ end
209
+ end
210
+ end
211
+ end
@@ -14,9 +14,9 @@
14
14
 
15
15
 
16
16
  require "time"
17
- require "gcloud/resource_manager/errors"
18
17
  require "gcloud/resource_manager/project/list"
19
18
  require "gcloud/resource_manager/project/updater"
19
+ require "gcloud/resource_manager/policy"
20
20
 
21
21
  module Gcloud
22
22
  module ResourceManager
@@ -40,8 +40,8 @@ module Gcloud
40
40
  #
41
41
  class Project
42
42
  ##
43
- # @private The Connection object.
44
- attr_accessor :connection
43
+ # @private The Service object.
44
+ attr_accessor :service
45
45
 
46
46
  ##
47
47
  # @private The Google API Client object.
@@ -50,8 +50,8 @@ module Gcloud
50
50
  ##
51
51
  # @private Create an empty Project object.
52
52
  def initialize
53
- @connection = nil
54
- @gapi = {}
53
+ @service = nil
54
+ @gapi = Gcloud::ResourceManager::Service::API::Project.new
55
55
  end
56
56
 
57
57
  ##
@@ -60,21 +60,21 @@ module Gcloud
60
60
  # Trailing hyphens are prohibited. e.g. tokyo-rain-123
61
61
  #
62
62
  def project_id
63
- @gapi["projectId"]
63
+ @gapi.project_id
64
64
  end
65
65
 
66
66
  ##
67
67
  # The number uniquely identifying the project. e.g. 415104041262
68
68
  #
69
69
  def project_number
70
- @gapi["projectNumber"]
70
+ @gapi.project_number
71
71
  end
72
72
 
73
73
  ##
74
74
  # The user-assigned name of the project.
75
75
  #
76
76
  def name
77
- @gapi["name"]
77
+ @gapi.name
78
78
  end
79
79
 
80
80
  ##
@@ -93,14 +93,9 @@ module Gcloud
93
93
  # project.name = "My Project"
94
94
  #
95
95
  def name= new_name
96
- ensure_connection!
97
- @gapi["name"] = new_name
98
- resp = connection.update_project @gapi
99
- if resp.success?
100
- @gapi = resp.data
101
- else
102
- fail ApiError.from_response(resp)
103
- end
96
+ ensure_service!
97
+ @gapi.name = new_name
98
+ @gapi = service.update_project @gapi
104
99
  end
105
100
 
106
101
  ##
@@ -138,8 +133,7 @@ module Gcloud
138
133
  # end
139
134
  #
140
135
  def labels
141
- labels = @gapi["labels"]
142
- labels = labels.to_hash if labels.respond_to? :to_hash
136
+ labels = @gapi.labels.to_h
143
137
  if block_given?
144
138
  yielded_labels = labels.dup
145
139
  yield yielded_labels
@@ -170,21 +164,16 @@ module Gcloud
170
164
  # project.labels = { "env" => "production" }
171
165
  #
172
166
  def labels= new_labels
173
- ensure_connection!
174
- @gapi["labels"] = new_labels
175
- resp = connection.update_project @gapi
176
- if resp.success?
177
- @gapi = resp.data
178
- else
179
- fail ApiError.from_response(resp)
180
- end
167
+ ensure_service!
168
+ @gapi.labels = new_labels
169
+ @gapi = service.update_project @gapi
181
170
  end
182
171
 
183
172
  ##
184
173
  # The time that this project was created.
185
174
  #
186
175
  def created_at
187
- Time.parse @gapi["createTime"]
176
+ Time.parse @gapi.create_time
188
177
  rescue
189
178
  nil
190
179
  end
@@ -194,16 +183,16 @@ module Gcloud
194
183
  #
195
184
  # Possible values are:
196
185
  # * `ACTIVE` - The normal and active state.
197
- # * `LIFECYCLE_STATE_UNSPECIFIED` - Unspecified state. This is only
198
- # used/useful for distinguishing unset values.
199
186
  # * `DELETE_REQUESTED` - The project has been marked for deletion by the
200
- # user (by invoking DeleteProject) or by the system (Google Cloud
201
- # Platform). This can generally be reversed by invoking UndeleteProject.
187
+ # user (by invoking ##delete) or by the system (Google Cloud
188
+ # Platform). This can generally be reversed by invoking {#undelete}.
202
189
  # * `DELETE_IN_PROGRESS` - The process of deleting the project has begun.
203
190
  # Reversing the deletion is no longer possible.
191
+ # * `LIFECYCLE_STATE_UNSPECIFIED` - Unspecified state. This is only
192
+ # used/useful for distinguishing unset values.
204
193
  #
205
194
  def state
206
- @gapi["lifecycleState"]
195
+ @gapi.lifecycle_state
207
196
  end
208
197
 
209
198
  ##
@@ -255,12 +244,10 @@ module Gcloud
255
244
  def update
256
245
  updater = Updater.from_project self
257
246
  yield updater
258
- resp = connection.update_project updater.gapi
259
- if resp.success?
260
- @gapi = resp.data
261
- else
262
- fail ApiError.from_response(resp)
247
+ if updater.gapi.to_h != @gapi.to_h # changed
248
+ @gapi = service.update_project updater.gapi
263
249
  end
250
+ self
264
251
  end
265
252
 
266
253
  ##
@@ -276,12 +263,7 @@ module Gcloud
276
263
  # project.reload!
277
264
  #
278
265
  def reload!
279
- resp = connection.get_project project_id
280
- if resp.success?
281
- @gapi = resp.data
282
- else
283
- fail ApiError.from_response(resp)
284
- end
266
+ @gapi = service.get_project project_id
285
267
  end
286
268
  alias_method :refresh!, :reload!
287
269
 
@@ -317,13 +299,9 @@ module Gcloud
317
299
  # project.delete_requested? #=> true
318
300
  #
319
301
  def delete
320
- resp = connection.delete_project project_id
321
- if resp.success?
322
- reload!
323
- true
324
- else
325
- fail ApiError.from_response(resp)
326
- end
302
+ service.delete_project project_id
303
+ reload!
304
+ true
327
305
  end
328
306
 
329
307
  ##
@@ -346,85 +324,92 @@ module Gcloud
346
324
  # project.active? #=> true
347
325
  #
348
326
  def undelete
349
- resp = connection.undelete_project project_id
350
- if resp.success?
351
- reload!
352
- true
353
- else
354
- fail ApiError.from_response(resp)
355
- end
327
+ service.undelete_project project_id
328
+ reload!
329
+ true
356
330
  end
357
331
 
358
332
  ##
359
- # Gets the [Cloud IAM](https://cloud.google.com/iam/) access control
360
- # policy. Returns a hash that conforms to the following structure:
361
- #
362
- # {
363
- # "bindings" => [{
364
- # "role" => "roles/viewer",
365
- # "members" => ["serviceAccount:your-service-account"]
366
- # }],
367
- # "version" => 0,
368
- # "etag" => "CAE="
369
- # }
333
+ # Gets and updates the [Cloud IAM](https://cloud.google.com/iam/) access
334
+ # control policy for this project.
370
335
  #
371
336
  # @see https://cloud.google.com/iam/docs/managing-policies Managing
372
337
  # Policies
338
+ # @see https://cloud.google.com/resource-manager/reference/rest/v1beta1/projects/setIamPolicy
339
+ # projects.setIamPolicy
373
340
  #
374
341
  # @param [Boolean] force Force load the latest policy when `true`.
375
342
  # Otherwise the policy will be memoized to reduce the number of API
376
343
  # calls made. The default is `false`.
377
344
  #
378
- # @return [Hash] See description
345
+ # @yield [policy] A block for updating the policy. The latest policy will
346
+ # be read from the service and passed to the block. After the block
347
+ # completes, the modified policy will be written to the service.
348
+ # @yieldparam [Policy] policy the current Cloud IAM Policy for this
349
+ # project
350
+ #
351
+ # @return [Policy] the current Cloud IAM Policy for this project
379
352
  #
380
- # @example Policy values are memoized by default:
353
+ # @example Policy values are memoized to reduce the number of API calls:
381
354
  # require "gcloud"
382
355
  #
383
356
  # gcloud = Gcloud.new
384
357
  # resource_manager = gcloud.resource_manager
385
358
  # project = resource_manager.project "tokyo-rain-123"
386
- # policy = project.policy
387
359
  #
388
- # puts policy["bindings"]
389
- # puts policy["version"]
390
- # puts policy["etag"]
360
+ # policy = project.policy # API call
361
+ # policy_2 = project.policy # No API call
391
362
  #
392
- # @example Use the `force` option to retrieve the latest policy:
363
+ # @example Use `force` to retrieve the latest policy from the service:
393
364
  # require "gcloud"
394
365
  #
395
366
  # gcloud = Gcloud.new
396
367
  # resource_manager = gcloud.resource_manager
397
368
  # project = resource_manager.project "tokyo-rain-123"
398
- # policy = project.policy force: true
369
+ #
370
+ # policy = project.policy force: true # API call
371
+ # policy_2 = project.policy force: true # API call
372
+ #
373
+ # @example Update the policy by passing a block:
374
+ # require "gcloud"
375
+ #
376
+ # gcloud = Gcloud.new
377
+ # resource_manager = gcloud.resource_manager
378
+ # project = resource_manager.project "tokyo-rain-123"
379
+ #
380
+ # policy = project.policy do |p|
381
+ # p.add "roles/owner", "user:owner@example.com"
382
+ # end # 2 API calls
399
383
  #
400
384
  def policy force: false
401
- @policy = nil if force
385
+ @policy = nil if force || block_given?
402
386
  @policy ||= begin
403
- ensure_connection!
404
- resp = connection.get_policy project_id
405
- fail ApiError.from_response(resp) unless resp.success?
406
- policy = resp.data
407
- policy = policy.to_hash if policy.respond_to? :to_hash
408
- policy
387
+ ensure_service!
388
+ gapi = service.get_policy project_id
389
+ Policy.from_gapi gapi
409
390
  end
391
+ return @policy unless block_given?
392
+ p = @policy.deep_dup
393
+ yield p
394
+ self.policy = p
410
395
  end
411
396
 
412
397
  ##
413
- # Sets the [Cloud IAM](https://cloud.google.com/iam/) access control
414
- # policy.
398
+ # Updates the [Cloud IAM](https://cloud.google.com/iam/) access control
399
+ # policy for this project. The policy should be read from {#policy}.
400
+ # See {Gcloud::ResourceManager::Policy} for an explanation of the policy
401
+ # `etag` property and how to modify policies.
402
+ #
403
+ # You can also update the policy by passing a block to {#policy}, which
404
+ # will call this method internally after the block completes.
415
405
  #
416
406
  # @see https://cloud.google.com/iam/docs/managing-policies Managing
417
407
  # Policies
408
+ # @see https://cloud.google.com/resource-manager/reference/rest/v1beta1/projects/setIamPolicy
409
+ # projects.setIamPolicy
418
410
  #
419
- # @param [String] new_policy A hash that conforms to the following
420
- # structure:
421
- #
422
- # {
423
- # "bindings" => [{
424
- # "role" => "roles/viewer",
425
- # "members" => ["serviceAccount:your-service-account"]
426
- # }]
427
- # }
411
+ # @param [Policy] new_policy a new or modified Cloud IAM Policy for this
412
+ # project
428
413
  #
429
414
  # @example
430
415
  # require "gcloud"
@@ -433,23 +418,18 @@ module Gcloud
433
418
  # resource_manager = gcloud.resource_manager
434
419
  # project = resource_manager.project "tokyo-rain-123"
435
420
  #
436
- # viewer_policy = {
437
- # "bindings" => [{
438
- # "role" => "roles/viewer",
439
- # "members" => ["serviceAccount:your-service-account"]
440
- # }]
441
- # }
442
- # project.policy = viewer_policy
421
+ # policy = project.policy # API call
422
+ #
423
+ # policy.add "roles/owner", "user:owner@example.com"
424
+ #
425
+ # project.policy = policy # API call
443
426
  #
444
427
  def policy= new_policy
445
- ensure_connection!
446
- resp = connection.set_policy project_id, new_policy
447
- if resp.success?
448
- @policy = resp.data
449
- @policy = @policy.to_hash if @policy.respond_to? :to_hash
450
- else
451
- fail ApiError.from_response(resp)
452
- end
428
+ ensure_service!
429
+ gapi = service.set_policy project_id, new_policy.to_gapi
430
+ # Convert symbols to strings for backwards compatibility.
431
+ # This will go away when we add a ResourceManager::Policy class.
432
+ @policy = Policy.from_gapi gapi
453
433
  end
454
434
 
455
435
  ##
@@ -478,30 +458,26 @@ module Gcloud
478
458
  #
479
459
  def test_permissions *permissions
480
460
  permissions = Array(permissions).flatten
481
- ensure_connection!
482
- resp = connection.test_permissions project_id, permissions
483
- if resp.success?
484
- Array(resp.data["permissions"])
485
- else
486
- fail ApiError.from_response(resp)
487
- end
461
+ ensure_service!
462
+ gapi = service.test_permissions project_id, permissions
463
+ gapi.permissions
488
464
  end
489
465
 
490
466
  ##
491
467
  # @private New Change from a Google API Client object.
492
- def self.from_gapi gapi, connection
468
+ def self.from_gapi gapi, service
493
469
  new.tap do |p|
494
470
  p.gapi = gapi
495
- p.connection = connection
471
+ p.service = service
496
472
  end
497
473
  end
498
474
 
499
475
  protected
500
476
 
501
477
  ##
502
- # Raise an error unless an active connection is available.
503
- def ensure_connection!
504
- fail "Must have active connection" unless connection
478
+ # Raise an error unless an active service is available.
479
+ def ensure_service!
480
+ fail "Must have active connection" unless service
505
481
  end
506
482
  end
507
483
  end