google-cloud-resource_manager 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.
@@ -0,0 +1,214 @@
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 "google/cloud/errors"
17
+ require "google/apis/cloudresourcemanager_v1"
18
+
19
+ module Google
20
+ module Cloud
21
+ module ResourceManager
22
+ ##
23
+ # # Policy
24
+ #
25
+ # Represents a Cloud IAM Policy for the Resource Manager service.
26
+ #
27
+ # A common pattern for updating a resource's metadata, such as its Policy,
28
+ # is to read the current data from the service, update the data locally,
29
+ # and then send the modified data for writing. This pattern may result in
30
+ # a conflict if two or more processes attempt the sequence simultaneously.
31
+ # IAM solves this problem with the
32
+ # {Google::Cloud::ResourceManager::Policy#etag} property, which is used to
33
+ # verify whether the policy has changed since the last request. When you
34
+ # make a request to with an `etag` value, Cloud IAM compares the `etag`
35
+ # value in the request with the existing `etag` value associated with the
36
+ # policy. It writes the policy only if the `etag` values match.
37
+ #
38
+ # When you update a policy, first read the policy (and its current `etag`)
39
+ # from the service, then modify the policy locally, and then write the
40
+ # modified policy to the service. See
41
+ # {Google::Cloud::ResourceManager::Project#policy} and
42
+ # {Google::Cloud::ResourceManager::Project#policy=}.
43
+ #
44
+ # @see https://cloud.google.com/iam/docs/managing-policies Managing
45
+ # policies
46
+ # @see https://cloud.google.com/resource-manager/reference/rest/v1beta1/projects/setIamPolicy
47
+ # projects.setIamPolicy
48
+ #
49
+ # @attr [String] etag Used to verify whether the policy has changed since
50
+ # the last request. The policy will be written only if the `etag` values
51
+ # match.
52
+ # @attr [Hash{String => Array<String>}] roles The bindings that associate
53
+ # roles with an array of members. See [Understanding
54
+ # Roles](https://cloud.google.com/iam/docs/understanding-roles) for a
55
+ # listing of primitive and curated roles. See
56
+ # [Binding](https://cloud.google.com/resource-manager/reference/rpc/google.iam.v1#binding)
57
+ # for a listing of values and patterns for members.
58
+ #
59
+ # @example
60
+ # require "google/cloud"
61
+ #
62
+ # gcloud = Google::Cloud.new
63
+ # resource_manager = gcloud.resource_manager
64
+ # project = resource_manager.project "tokyo-rain-123"
65
+ #
66
+ # policy = project.policy # API call
67
+ #
68
+ # policy.remove "roles/owner", "user:owner@example.com" # Local call
69
+ # policy.add "roles/owner", "user:newowner@example.com" # Local call
70
+ # policy.roles["roles/viewer"] = ["allUsers"] # Local call
71
+ #
72
+ # project.policy = policy # API call
73
+ #
74
+ class Policy
75
+ ##
76
+ # Alias to the Google Client API module
77
+ API = Google::Apis::CloudresourcemanagerV1
78
+
79
+ attr_reader :etag, :roles
80
+
81
+ ##
82
+ # @private Creates a Policy object.
83
+ def initialize etag, roles
84
+ @etag = etag
85
+ @roles = roles
86
+ end
87
+
88
+ ##
89
+ # Convenience method for adding a member to a binding on this policy.
90
+ # See [Understanding
91
+ # Roles](https://cloud.google.com/iam/docs/understanding-roles) for a
92
+ # listing of primitive and curated roles. See
93
+ # [Binding](https://cloud.google.com/resource-manager/reference/rpc/google.iam.v1#binding)
94
+ # for a listing of values and patterns for members.
95
+ #
96
+ # @param [String] role_name A Cloud IAM role, such as `"roles/owner"`.
97
+ # @param [String] member A Cloud IAM identity, such as
98
+ # `"user:owner@example.com"`.
99
+ #
100
+ # @example
101
+ # require "google/cloud"
102
+ #
103
+ # gcloud = Google::Cloud.new
104
+ # resource_manager = gcloud.resource_manager
105
+ # project = resource_manager.project "tokyo-rain-123"
106
+ #
107
+ # policy = project.policy # API call
108
+ #
109
+ # policy.add "roles/owner", "user:newowner@example.com" # Local call
110
+ #
111
+ # project.policy = policy # API call
112
+ #
113
+ def add role_name, member
114
+ role(role_name) << member
115
+ end
116
+
117
+ ##
118
+ # Convenience method for removing a member from a binding on this
119
+ # policy. See [Understanding
120
+ # Roles](https://cloud.google.com/iam/docs/understanding-roles) for a
121
+ # listing of primitive and curated roles. See
122
+ # [Binding](https://cloud.google.com/resource-manager/reference/rpc/google.iam.v1#binding)
123
+ # for a listing of values and patterns for members.
124
+ #
125
+ # @param [String] role_name A Cloud IAM role, such as `"roles/owner"`.
126
+ # @param [String] member A Cloud IAM identity, such as
127
+ # `"user:owner@example.com"`.
128
+ #
129
+ # @example
130
+ # require "google/cloud"
131
+ #
132
+ # gcloud = Google::Cloud.new
133
+ # resource_manager = gcloud.resource_manager
134
+ # project = resource_manager.project "tokyo-rain-123"
135
+ #
136
+ # policy = project.policy # API call
137
+ #
138
+ # policy.remove "roles/owner", "user:owner@example.com" # Local call
139
+ #
140
+ # project.policy = policy # API call
141
+ #
142
+ def remove role_name, member
143
+ role(role_name).delete member
144
+ end
145
+
146
+ ##
147
+ # Convenience method returning the array of members bound to a role in
148
+ # this policy, or an empty array if no value is present for the role in
149
+ # {#roles}. See [Understanding
150
+ # Roles](https://cloud.google.com/iam/docs/understanding-roles) for a
151
+ # listing of primitive and curated roles. See
152
+ # [Binding](https://cloud.google.com/resource-manager/reference/rpc/google.iam.v1#binding)
153
+ # for a listing of values and patterns for members.
154
+ #
155
+ # @return [Array<String>] The members strings, or an empty array.
156
+ #
157
+ # @example
158
+ # require "google/cloud"
159
+ #
160
+ # gcloud = Google::Cloud.new
161
+ # resource_manager = gcloud.resource_manager
162
+ # project = resource_manager.project "tokyo-rain-123"
163
+ #
164
+ # policy = project.policy
165
+ #
166
+ # policy.role("roles/viewer") << "user:viewer@example.com"
167
+ #
168
+ def role role_name
169
+ roles[role_name] ||= []
170
+ end
171
+
172
+ ##
173
+ # Returns a deep copy of the policy.
174
+ #
175
+ # @return [Policy]
176
+ #
177
+ def deep_dup
178
+ dup.tap do |p|
179
+ roles_dup = p.roles.each_with_object({}) do |(k, v), memo|
180
+ memo[k] = v.dup rescue value
181
+ end
182
+ p.instance_variable_set "@roles", roles_dup
183
+ end
184
+ end
185
+
186
+ ##
187
+ # @private Convert the Policy to a
188
+ # Google::Apis::CloudresourcemanagerV1::Policy.
189
+ def to_gapi
190
+ API::Policy.new(
191
+ etag: etag,
192
+ bindings: roles.keys.map do |role_name|
193
+ next if roles[role_name].empty?
194
+ API::Binding.new(
195
+ role: role_name,
196
+ members: roles[role_name]
197
+ )
198
+ end
199
+ )
200
+ end
201
+
202
+ ##
203
+ # @private New Policy from a
204
+ # Google::Apis::CloudresourcemanagerV1::Policy object.
205
+ def self.from_gapi gapi
206
+ roles = gapi.bindings.each_with_object({}) do |binding, memo|
207
+ memo[binding.role] = binding.members.to_a
208
+ end
209
+ new gapi.etag, roles
210
+ end
211
+ end
212
+ end
213
+ end
214
+ end
@@ -0,0 +1,486 @@
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 "time"
17
+ require "google/cloud/resource_manager/project/list"
18
+ require "google/cloud/resource_manager/project/updater"
19
+ require "google/cloud/resource_manager/policy"
20
+
21
+ module Google
22
+ module Cloud
23
+ module ResourceManager
24
+ ##
25
+ # # Project
26
+ #
27
+ # Project is a high-level Google Cloud Platform entity. It is a container
28
+ # for ACLs, APIs, AppEngine Apps, VMs, and other Google Cloud Platform
29
+ # resources.
30
+ #
31
+ # @example
32
+ # require "google/cloud"
33
+ #
34
+ # gcloud = Google::Cloud.new
35
+ # resource_manager = gcloud.resource_manager
36
+ # project = resource_manager.project "tokyo-rain-123"
37
+ # project.update do |p|
38
+ # p.name = "My Project"
39
+ # p.labels["env"] = "production"
40
+ # end
41
+ #
42
+ class Project
43
+ ##
44
+ # @private The Service object.
45
+ attr_accessor :service
46
+
47
+ ##
48
+ # @private The Google API Client object.
49
+ attr_accessor :gapi
50
+
51
+ ##
52
+ # @private Create an empty Project object.
53
+ def initialize
54
+ @service = nil
55
+ @gapi = Google::Cloud::ResourceManager::Service::API::Project.new
56
+ end
57
+
58
+ ##
59
+ # The unique, user-assigned ID of the project. It must be 6 to 30
60
+ # lowercase letters, digits, or hyphens. It must start with a letter.
61
+ # Trailing hyphens are prohibited. e.g. tokyo-rain-123
62
+ #
63
+ def project_id
64
+ @gapi.project_id
65
+ end
66
+
67
+ ##
68
+ # The number uniquely identifying the project. e.g. 415104041262
69
+ #
70
+ def project_number
71
+ @gapi.project_number
72
+ end
73
+
74
+ ##
75
+ # The user-assigned name of the project.
76
+ #
77
+ def name
78
+ @gapi.name
79
+ end
80
+
81
+ ##
82
+ # Updates the user-assigned name of the project. This field is optional
83
+ # and can remain unset.
84
+ #
85
+ # Allowed characters are: lowercase and uppercase letters, numbers,
86
+ # hyphen, single-quote, double-quote, space, and exclamation point.
87
+ #
88
+ # @example
89
+ # require "google/cloud"
90
+ #
91
+ # gcloud = Google::Cloud.new
92
+ # resource_manager = gcloud.resource_manager
93
+ # project = resource_manager.project "tokyo-rain-123"
94
+ # project.name = "My Project"
95
+ #
96
+ def name= new_name
97
+ ensure_service!
98
+ @gapi.name = new_name
99
+ @gapi = service.update_project @gapi
100
+ end
101
+
102
+ ##
103
+ # The labels associated with this project.
104
+ #
105
+ # Label keys must be between 1 and 63 characters long and must conform
106
+ # to the regular expression <code>[a-z]([-a-z0-9]*[a-z0-9])?</code>.
107
+ #
108
+ # Label values must be between 0 and 63 characters long and must conform
109
+ # to the regular expression <code>([a-z]([-a-z0-9]*[a-z0-9])?)?</code>.
110
+ #
111
+ # No more than 256 labels can be associated with a given resource.
112
+ # (`Hash`)
113
+ #
114
+ # @yield [labels] a block for setting labels
115
+ # @yieldparam [Hash] labels the hash accepting labels
116
+ #
117
+ # @example Labels are read-only and cannot be changed:
118
+ # require "google/cloud"
119
+ #
120
+ # gcloud = Google::Cloud.new
121
+ # resource_manager = gcloud.resource_manager
122
+ # project = resource_manager.project "tokyo-rain-123"
123
+ # project.labels["env"] #=> "dev" # read only
124
+ # project.labels["env"] = "production" # raises error
125
+ #
126
+ # @example Labels can be updated by passing a block, or with {#labels=}:
127
+ # require "google/cloud"
128
+ #
129
+ # gcloud = Google::Cloud.new
130
+ # resource_manager = gcloud.resource_manager
131
+ # project = resource_manager.project "tokyo-rain-123"
132
+ # project.labels do |labels|
133
+ # labels["env"] = "production"
134
+ # end
135
+ #
136
+ def labels
137
+ labels = @gapi.labels.to_h
138
+ if block_given?
139
+ yielded_labels = labels.dup
140
+ yield yielded_labels
141
+ self.labels = yielded_labels if yielded_labels != labels # changed
142
+ else
143
+ labels.freeze
144
+ end
145
+ end
146
+
147
+ ##
148
+ # Updates the labels associated with this project.
149
+ #
150
+ # Label keys must be between 1 and 63 characters long and must conform
151
+ # to the regular expression <code>[a-z]([-a-z0-9]*[a-z0-9])?</code>.
152
+ #
153
+ # Label values must be between 0 and 63 characters long and must conform
154
+ # to the regular expression <code>([a-z]([-a-z0-9]*[a-z0-9])?)?</code>.
155
+ #
156
+ # No more than 256 labels can be associated with a given resource.
157
+ # (`Hash`)
158
+ #
159
+ # @example
160
+ # require "google/cloud"
161
+ #
162
+ # gcloud = Google::Cloud.new
163
+ # resource_manager = gcloud.resource_manager
164
+ # project = resource_manager.project "tokyo-rain-123"
165
+ # project.labels = { "env" => "production" }
166
+ #
167
+ def labels= new_labels
168
+ ensure_service!
169
+ @gapi.labels = new_labels
170
+ @gapi = service.update_project @gapi
171
+ end
172
+
173
+ ##
174
+ # The time that this project was created.
175
+ #
176
+ def created_at
177
+ Time.parse @gapi.create_time
178
+ rescue
179
+ nil
180
+ end
181
+
182
+ ##
183
+ # The project lifecycle state.
184
+ #
185
+ # Possible values are:
186
+ # * `ACTIVE` - The normal and active state.
187
+ # * `DELETE_REQUESTED` - The project has been marked for deletion by the
188
+ # user (by invoking ##delete) or by the system (Google Cloud
189
+ # Platform). This can generally be reversed by invoking {#undelete}.
190
+ # * `DELETE_IN_PROGRESS` - The process of deleting the project has
191
+ # begun. Reversing the deletion is no longer possible.
192
+ # * `LIFECYCLE_STATE_UNSPECIFIED` - Unspecified state. This is only
193
+ # used/useful for distinguishing unset values.
194
+ #
195
+ def state
196
+ @gapi.lifecycle_state
197
+ end
198
+
199
+ ##
200
+ # Checks if the state is `ACTIVE`.
201
+ def active?
202
+ return false if state.nil?
203
+ "ACTIVE".casecmp(state).zero?
204
+ end
205
+
206
+ ##
207
+ # Checks if the state is `LIFECYCLE_STATE_UNSPECIFIED`.
208
+ def unspecified?
209
+ return false if state.nil?
210
+ "LIFECYCLE_STATE_UNSPECIFIED".casecmp(state).zero?
211
+ end
212
+
213
+ ##
214
+ # Checks if the state is `DELETE_REQUESTED`.
215
+ def delete_requested?
216
+ return false if state.nil?
217
+ "DELETE_REQUESTED".casecmp(state).zero?
218
+ end
219
+
220
+ ##
221
+ # Checks if the state is `DELETE_IN_PROGRESS`.
222
+ def delete_in_progress?
223
+ return false if state.nil?
224
+ "DELETE_IN_PROGRESS".casecmp(state).zero?
225
+ end
226
+
227
+ ##
228
+ # Updates the project in a single API call. See {Project::Updater}
229
+ #
230
+ # @yield [project] a block yielding a project delegate
231
+ # @yieldparam [Project::Updater] project the delegate object for
232
+ # updating the project
233
+ #
234
+ # @example
235
+ # require "google/cloud"
236
+ #
237
+ # gcloud = Google::Cloud.new
238
+ # resource_manager = gcloud.resource_manager
239
+ # project = resource_manager.project "tokyo-rain-123"
240
+ # project.update do |p|
241
+ # p.name = "My Project"
242
+ # p.labels["env"] = "production"
243
+ # end
244
+ #
245
+ def update
246
+ updater = Updater.from_project self
247
+ yield updater
248
+ if updater.gapi.to_h != @gapi.to_h # changed
249
+ @gapi = service.update_project updater.gapi
250
+ end
251
+ self
252
+ end
253
+
254
+ ##
255
+ # Reloads the project (with updated state) from the Google Cloud
256
+ # Resource Manager service.
257
+ #
258
+ # @example
259
+ # require "google/cloud"
260
+ #
261
+ # gcloud = Google::Cloud.new
262
+ # resource_manager = gcloud.resource_manager
263
+ # project = resource_manager.project "tokyo-rain-123"
264
+ # project.reload!
265
+ #
266
+ def reload!
267
+ @gapi = service.get_project project_id
268
+ end
269
+ alias_method :refresh!, :reload!
270
+
271
+ ##
272
+ # Marks the project for deletion. This method will only affect the
273
+ # project if the following criteria are met:
274
+ #
275
+ # * The project does not have a billing account associated with it.
276
+ # * The project has a lifecycle state of `ACTIVE`.
277
+ # * This method changes the project's lifecycle state from `ACTIVE` to
278
+ # `DELETE_REQUESTED`. The deletion starts at an unspecified time, at
279
+ # which point the lifecycle state changes to `DELETE_IN_PROGRESS`.
280
+ #
281
+ # Until the deletion completes, you can check the lifecycle state by
282
+ # calling #reload!, or by retrieving the project with Manager#project.
283
+ # The project remains visible to Manager#project and Manager#projects,
284
+ # but cannot be updated.
285
+ #
286
+ # After the deletion completes, the project is not retrievable by the
287
+ # Manager#project and Manager#projects methods.
288
+ #
289
+ # The caller must have modify permissions for this project.
290
+ #
291
+ # @example
292
+ # require "google/cloud"
293
+ #
294
+ # gcloud = Google::Cloud.new
295
+ # resource_manager = gcloud.resource_manager
296
+ # project = resource_manager.project "tokyo-rain-123"
297
+ # project.active? #=> true
298
+ # project.delete
299
+ # project.active? #=> false
300
+ # project.delete_requested? #=> true
301
+ #
302
+ def delete
303
+ service.delete_project project_id
304
+ reload!
305
+ true
306
+ end
307
+
308
+ ##
309
+ # Restores the project. You can only use this method for a project that
310
+ # has a lifecycle state of `DELETE_REQUESTED`. After deletion starts, as
311
+ # indicated by a lifecycle state of `DELETE_IN_PROGRESS`, the project
312
+ # cannot be restored.
313
+ #
314
+ # The caller must have modify permissions for this project.
315
+ #
316
+ # @example
317
+ # require "google/cloud"
318
+ #
319
+ # gcloud = Google::Cloud.new
320
+ # resource_manager = gcloud.resource_manager
321
+ # project = resource_manager.project "tokyo-rain-123"
322
+ # project.delete_requested? #=> true
323
+ # project.undelete
324
+ # project.delete_requested? #=> false
325
+ # project.active? #=> true
326
+ #
327
+ def undelete
328
+ service.undelete_project project_id
329
+ reload!
330
+ true
331
+ end
332
+
333
+ ##
334
+ # Gets and updates the [Cloud IAM](https://cloud.google.com/iam/) access
335
+ # control policy for this project.
336
+ #
337
+ # @see https://cloud.google.com/iam/docs/managing-policies Managing
338
+ # Policies
339
+ # @see https://cloud.google.com/resource-manager/reference/rest/v1beta1/projects/setIamPolicy
340
+ # projects.setIamPolicy
341
+ #
342
+ # @param [Boolean] force Force load the latest policy when `true`.
343
+ # Otherwise the policy will be memoized to reduce the number of API
344
+ # calls made. The default is `false`.
345
+ #
346
+ # @yield [policy] A block for updating the policy. The latest policy
347
+ # will be read from the service and passed to the block. After the
348
+ # block completes, the modified policy will be written to the service.
349
+ # @yieldparam [Policy] policy the current Cloud IAM Policy for this
350
+ # project
351
+ #
352
+ # @return [Policy] the current Cloud IAM Policy for this project
353
+ #
354
+ # @example Policy values are memoized to reduce the number of API calls:
355
+ # require "google/cloud"
356
+ #
357
+ # gcloud = Google::Cloud.new
358
+ # resource_manager = gcloud.resource_manager
359
+ # project = resource_manager.project "tokyo-rain-123"
360
+ #
361
+ # policy = project.policy # API call
362
+ # policy_2 = project.policy # No API call
363
+ #
364
+ # @example Use `force` to retrieve the latest policy from the service:
365
+ # require "google/cloud"
366
+ #
367
+ # gcloud = Google::Cloud.new
368
+ # resource_manager = gcloud.resource_manager
369
+ # project = resource_manager.project "tokyo-rain-123"
370
+ #
371
+ # policy = project.policy force: true # API call
372
+ # policy_2 = project.policy force: true # API call
373
+ #
374
+ # @example Update the policy by passing a block:
375
+ # require "google/cloud"
376
+ #
377
+ # gcloud = Google::Cloud.new
378
+ # resource_manager = gcloud.resource_manager
379
+ # project = resource_manager.project "tokyo-rain-123"
380
+ #
381
+ # policy = project.policy do |p|
382
+ # p.add "roles/owner", "user:owner@example.com"
383
+ # end # 2 API calls
384
+ #
385
+ def policy force: false
386
+ @policy = nil if force || block_given?
387
+ @policy ||= begin
388
+ ensure_service!
389
+ gapi = service.get_policy project_id
390
+ Policy.from_gapi gapi
391
+ end
392
+ return @policy unless block_given?
393
+ p = @policy.deep_dup
394
+ yield p
395
+ self.policy = p
396
+ end
397
+
398
+ ##
399
+ # Updates the [Cloud IAM](https://cloud.google.com/iam/) access control
400
+ # policy for this project. The policy should be read from {#policy}. See
401
+ # {Google::Cloud::ResourceManager::Policy} for an explanation of the
402
+ # policy `etag` property and how to modify policies.
403
+ #
404
+ # You can also update the policy by passing a block to {#policy}, which
405
+ # will call this method internally after the block completes.
406
+ #
407
+ # @see https://cloud.google.com/iam/docs/managing-policies Managing
408
+ # Policies
409
+ # @see https://cloud.google.com/resource-manager/reference/rest/v1beta1/projects/setIamPolicy
410
+ # projects.setIamPolicy
411
+ #
412
+ # @param [Policy] new_policy a new or modified Cloud IAM Policy for this
413
+ # project
414
+ #
415
+ # @example
416
+ # require "google/cloud"
417
+ #
418
+ # gcloud = Google::Cloud.new
419
+ # resource_manager = gcloud.resource_manager
420
+ # project = resource_manager.project "tokyo-rain-123"
421
+ #
422
+ # policy = project.policy # API call
423
+ #
424
+ # policy.add "roles/owner", "user:owner@example.com"
425
+ #
426
+ # project.policy = policy # API call
427
+ #
428
+ def policy= new_policy
429
+ ensure_service!
430
+ gapi = service.set_policy project_id, new_policy.to_gapi
431
+ # Convert symbols to strings for backwards compatibility.
432
+ # This will go away when we add a ResourceManager::Policy class.
433
+ @policy = Policy.from_gapi gapi
434
+ end
435
+
436
+ ##
437
+ # Tests the specified permissions against the [Cloud
438
+ # IAM](https://cloud.google.com/iam/) access control policy.
439
+ #
440
+ # @see https://cloud.google.com/iam/docs/managing-policies Managing
441
+ # Policies
442
+ #
443
+ # @param [String, Array<String>] permissions The set of permissions to
444
+ # check access for. Permissions with wildcards (such as `*` or
445
+ # `storage.*`) are not allowed.
446
+ #
447
+ # @return [Array<String>] The permissions that have access
448
+ #
449
+ # @example
450
+ # require "google/cloud"
451
+ #
452
+ # gcloud = Google::Cloud.new
453
+ # resource_manager = gcloud.resource_manager
454
+ # project = resource_manager.project "tokyo-rain-123"
455
+ # perms = project.test_permissions "resourcemanager.projects.get",
456
+ # "resourcemanager.projects.delete"
457
+ # perms.include? "resourcemanager.projects.get" #=> true
458
+ # perms.include? "resourcemanager.projects.delete" #=> false
459
+ #
460
+ def test_permissions *permissions
461
+ permissions = Array(permissions).flatten
462
+ ensure_service!
463
+ gapi = service.test_permissions project_id, permissions
464
+ gapi.permissions
465
+ end
466
+
467
+ ##
468
+ # @private New Change from a Google API Client object.
469
+ def self.from_gapi gapi, service
470
+ new.tap do |p|
471
+ p.gapi = gapi
472
+ p.service = service
473
+ end
474
+ end
475
+
476
+ protected
477
+
478
+ ##
479
+ # Raise an error unless an active service is available.
480
+ def ensure_service!
481
+ fail "Must have active connection" unless service
482
+ end
483
+ end
484
+ end
485
+ end
486
+ end