google-cloud-bigquery 1.21.1 → 1.27.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -341,14 +341,19 @@ module Google
341
341
  # the update to comply with ETag-based optimistic concurrency control.
342
342
  #
343
343
  # @param [Hash<String, String>] new_labels A hash containing key/value
344
- # pairs.
345
- #
346
- # * Label keys and values can be no longer than 63 characters.
347
- # * Label keys and values can contain only lowercase letters, numbers,
348
- # underscores, hyphens, and international characters.
349
- # * Label keys and values cannot exceed 128 bytes in size.
350
- # * Label keys must begin with a letter.
351
- # * Label keys must be unique within a model.
344
+ # pairs. The labels applied to a resource must meet the following requirements:
345
+ #
346
+ # * Each resource can have multiple labels, up to a maximum of 64.
347
+ # * Each label must be a key-value pair.
348
+ # * Keys have a minimum length of 1 character and a maximum length of
349
+ # 63 characters, and cannot be empty. Values can be empty, and have
350
+ # a maximum length of 63 characters.
351
+ # * Keys and values can contain only lowercase letters, numeric characters,
352
+ # underscores, and dashes. All characters must use UTF-8 encoding, and
353
+ # international characters are allowed.
354
+ # * The key portion of a label must be unique. However, you can use the
355
+ # same key with multiple resources.
356
+ # * Keys must start with a lowercase letter or international character.
352
357
  #
353
358
  # @example
354
359
  # require "google/cloud/bigquery"
@@ -482,6 +487,146 @@ module Google
482
487
  Array @gapi_json[:trainingRuns]
483
488
  end
484
489
 
490
+ ##
491
+ # Exports the model to Google Cloud Storage asynchronously, immediately
492
+ # returning an {ExtractJob} that can be used to track the progress of the
493
+ # export job. The caller may poll the service by repeatedly calling
494
+ # {Job#reload!} and {Job#done?} to detect when the job is done, or
495
+ # simply block until the job is done by calling #{Job#wait_until_done!}.
496
+ # See also {#extract}.
497
+ #
498
+ # The geographic location for the job ("US", "EU", etc.) can be set via
499
+ # {ExtractJob::Updater#location=} in a block passed to this method. If
500
+ # the model is a full resource representation (see {#resource_full?}),
501
+ # the location of the job will automatically be set to the location of
502
+ # the model.
503
+ #
504
+ # @see https://cloud.google.com/bigquery-ml/docs/exporting-models
505
+ # Exporting models
506
+ #
507
+ # @param [String] extract_url The Google Storage URI to which BigQuery
508
+ # should extract the model. This value should be end in an object name
509
+ # prefix, since multiple objects will be exported.
510
+ # @param [String] format The exported file format. The default value is
511
+ # `ml_tf_saved_model`.
512
+ #
513
+ # The following values are supported:
514
+ #
515
+ # * `ml_tf_saved_model` - TensorFlow SavedModel
516
+ # * `ml_xgboost_booster` - XGBoost Booster
517
+ # @param [String] job_id A user-defined ID for the extract job. The ID
518
+ # must contain only letters (a-z, A-Z), numbers (0-9), underscores
519
+ # (_), or dashes (-). The maximum length is 1,024 characters. If
520
+ # `job_id` is provided, then `prefix` will not be used.
521
+ #
522
+ # See [Generating a job
523
+ # ID](https://cloud.google.com/bigquery/docs/managing-jobs#generate-jobid).
524
+ # @param [String] prefix A string, usually human-readable, that will be
525
+ # prepended to a generated value to produce a unique job ID. For
526
+ # example, the prefix `daily_import_job_` can be given to generate a
527
+ # job ID such as `daily_import_job_12vEDtMQ0mbp1Mo5Z7mzAFQJZazh`. The
528
+ # prefix must contain only letters (a-z, A-Z), numbers (0-9),
529
+ # underscores (_), or dashes (-). The maximum length of the entire ID
530
+ # is 1,024 characters. If `job_id` is provided, then `prefix` will not
531
+ # be used.
532
+ # @param [Hash] labels A hash of user-provided labels associated with
533
+ # the job. You can use these to organize and group your jobs.
534
+ #
535
+ # The labels applied to a resource must meet the following requirements:
536
+ #
537
+ # * Each resource can have multiple labels, up to a maximum of 64.
538
+ # * Each label must be a key-value pair.
539
+ # * Keys have a minimum length of 1 character and a maximum length of
540
+ # 63 characters, and cannot be empty. Values can be empty, and have
541
+ # a maximum length of 63 characters.
542
+ # * Keys and values can contain only lowercase letters, numeric characters,
543
+ # underscores, and dashes. All characters must use UTF-8 encoding, and
544
+ # international characters are allowed.
545
+ # * The key portion of a label must be unique. However, you can use the
546
+ # same key with multiple resources.
547
+ # * Keys must start with a lowercase letter or international character.
548
+ #
549
+ # @yield [job] a job configuration object
550
+ # @yieldparam [Google::Cloud::Bigquery::ExtractJob::Updater] job a job
551
+ # configuration object for setting additional options.
552
+ #
553
+ # @return [Google::Cloud::Bigquery::ExtractJob]
554
+ #
555
+ # @example
556
+ # require "google/cloud/bigquery"
557
+ #
558
+ # bigquery = Google::Cloud::Bigquery.new
559
+ # dataset = bigquery.dataset "my_dataset"
560
+ # model = dataset.model "my_model"
561
+ #
562
+ # extract_job = model.extract_job "gs://my-bucket/#{model.model_id}"
563
+ #
564
+ # extract_job.wait_until_done!
565
+ # extract_job.done? #=> true
566
+ #
567
+ # @!group Data
568
+ #
569
+ def extract_job extract_url, format: nil, job_id: nil, prefix: nil, labels: nil
570
+ ensure_service!
571
+ options = { format: format, job_id: job_id, prefix: prefix, labels: labels }
572
+ updater = ExtractJob::Updater.from_options service, model_ref, extract_url, options
573
+ updater.location = location if location # may be model reference
574
+
575
+ yield updater if block_given?
576
+
577
+ job_gapi = updater.to_gapi
578
+ gapi = service.extract_table job_gapi
579
+ Job.from_gapi gapi, service
580
+ end
581
+
582
+ ##
583
+ # Exports the model to Google Cloud Storage using a synchronous method
584
+ # that blocks for a response. Timeouts and transient errors are generally
585
+ # handled as needed to complete the job. See also {#extract_job}.
586
+ #
587
+ # The geographic location for the job ("US", "EU", etc.) can be set via
588
+ # {ExtractJob::Updater#location=} in a block passed to this method. If
589
+ # the model is a full resource representation (see {#resource_full?}),
590
+ # the location of the job will automatically be set to the location of
591
+ # the model.
592
+ #
593
+ # @see https://cloud.google.com/bigquery-ml/docs/exporting-models
594
+ # Exporting models
595
+ #
596
+ # @param [String] extract_url The Google Storage URI to which BigQuery
597
+ # should extract the model. This value should be end in an object name
598
+ # prefix, since multiple objects will be exported.
599
+ # @param [String] format The exported file format. The default value is
600
+ # `ml_tf_saved_model`.
601
+ #
602
+ # The following values are supported:
603
+ #
604
+ # * `ml_tf_saved_model` - TensorFlow SavedModel
605
+ # * `ml_xgboost_booster` - XGBoost Booster
606
+ # @yield [job] a job configuration object
607
+ # @yieldparam [Google::Cloud::Bigquery::ExtractJob::Updater] job a job
608
+ # configuration object for setting additional options.
609
+ #
610
+ # @return [Boolean] Returns `true` if the extract operation succeeded.
611
+ #
612
+ # @example
613
+ # require "google/cloud/bigquery"
614
+ #
615
+ # bigquery = Google::Cloud::Bigquery.new
616
+ # dataset = bigquery.dataset "my_dataset"
617
+ # model = dataset.model "my_model"
618
+ #
619
+ # model.extract "gs://my-bucket/#{model.model_id}"
620
+ #
621
+ # @!group Data
622
+ #
623
+ def extract extract_url, format: nil, &block
624
+ job = extract_job extract_url, format: format, &block
625
+ job.wait_until_done!
626
+ ensure_job_succeeded! job
627
+ true
628
+ end
629
+
485
630
  ##
486
631
  # Permanently deletes the model.
487
632
  #
@@ -734,6 +879,17 @@ module Google
734
879
  def ensure_full_data!
735
880
  reload! unless resource_full?
736
881
  end
882
+
883
+ def ensure_job_succeeded! job
884
+ return unless job.failed?
885
+ begin
886
+ # raise to activate ruby exception cause handling
887
+ raise job.gapi_error
888
+ rescue StandardError => e
889
+ # wrap Google::Apis::Error with Google::Cloud::Error
890
+ raise Google::Cloud::Error.from_error(e)
891
+ end
892
+ end
737
893
  end
738
894
  end
739
895
  end
@@ -0,0 +1,431 @@
1
+ # Copyright 2020 Google LLC
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
+ # https://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/apis/bigquery_v2"
17
+
18
+ module Google
19
+ module Cloud
20
+ module Bigquery
21
+ ##
22
+ # # Policy
23
+ #
24
+ # Represents a Cloud IAM Policy for BigQuery resources.
25
+ #
26
+ # A Policy is a collection of bindings. A {Policy::Binding} binds one or more members to a single role. Member
27
+ # strings can describe user accounts, service accounts, Google groups, and domains. A role string represents a
28
+ # named list of permissions; each role can be an IAM predefined role or a user-created custom role.
29
+ #
30
+ # @see https://cloud.google.com/iam/docs/managing-policies Managing Policies
31
+ # @see https://cloud.google.com/bigquery/docs/table-access-controls-intro Controlling access to tables
32
+ #
33
+ # @attr [String] etag Used to check if the policy has changed since the last request. When you make a request with
34
+ # an `etag` value, Cloud IAM compares the `etag` value in the request with the existing `etag` value associated
35
+ # with the policy. It writes the policy only if the `etag` values match.
36
+ # @attr [Array<Binding>] bindings The bindings in the policy, which may be mutable or frozen depending on the
37
+ # context. See [Understanding Roles](https://cloud.google.com/iam/docs/understanding-roles) for a list of
38
+ # primitive and curated roles. See [BigQuery Table ACL
39
+ # permissions](https://cloud.google.com/bigquery/docs/table-access-controls-intro#permissions) for a list of
40
+ # values and patterns for members.
41
+ #
42
+ # @example
43
+ # require "google/cloud/bigquery"
44
+ #
45
+ # bigquery = Google::Cloud::Bigquery.new
46
+ # dataset = bigquery.dataset "my_dataset"
47
+ # table = dataset.table "my_table"
48
+ # policy = table.policy
49
+ #
50
+ # policy.frozen? #=> true
51
+ # binding_owner = policy.bindings.find { |b| b.role == "roles/owner" }
52
+ #
53
+ # binding_owner.role #=> "roles/owner"
54
+ # binding_owner.members #=> ["user:owner@example.com"]
55
+ # binding_owner.frozen? #=> true
56
+ # binding_owner.members.frozen? #=> true
57
+ #
58
+ # @example Update mutable bindings in the policy.
59
+ # require "google/cloud/bigquery"
60
+ #
61
+ # bigquery = Google::Cloud::Bigquery.new
62
+ # dataset = bigquery.dataset "my_dataset"
63
+ # table = dataset.table "my_table"
64
+ #
65
+ # table.update_policy do |p|
66
+ # p.grant role: "roles/viewer", members: "user:viewer@example.com"
67
+ # p.revoke role: "roles/editor", members: "user:editor@example.com"
68
+ # p.revoke role: "roles/owner"
69
+ # end
70
+ #
71
+ # @example Iterate over frozen bindings.
72
+ # require "google/cloud/bigquery"
73
+ #
74
+ # bigquery = Google::Cloud::Bigquery.new
75
+ # dataset = bigquery.dataset "my_dataset"
76
+ # table = dataset.table "my_table"
77
+ # policy = table.policy
78
+ #
79
+ # policy.frozen? #=> true
80
+ # policy.bindings.each do |b|
81
+ # puts b.role
82
+ # puts b.members
83
+ # end
84
+ #
85
+ # @example Update mutable bindings.
86
+ # require "google/cloud/bigquery"
87
+ #
88
+ # bigquery = Google::Cloud::Bigquery.new
89
+ # dataset = bigquery.dataset "my_dataset"
90
+ # table = dataset.table "my_table"
91
+ #
92
+ # table.update_policy do |p|
93
+ # p.bindings.each do |b|
94
+ # b.members.delete_if { |m| m.include? "@example.com" }
95
+ # end
96
+ # end
97
+ #
98
+ class Policy
99
+ attr_reader :etag, :bindings
100
+
101
+ # @private
102
+ def initialize etag, bindings
103
+ @etag = etag.freeze
104
+ @bindings = bindings
105
+ end
106
+
107
+ ##
108
+ # Convenience method adding or updating a binding in the policy. See [Understanding
109
+ # Roles](https://cloud.google.com/iam/docs/understanding-roles) for a list of primitive and curated roles. See
110
+ # [BigQuery Table ACL
111
+ # permissions](https://cloud.google.com/bigquery/docs/table-access-controls-intro#permissions) for a list of
112
+ # values and patterns for members.
113
+ #
114
+ # @param [String] role The role that is bound to members in the binding. For example, `roles/viewer`,
115
+ # `roles/editor`, or `roles/owner`. Required.
116
+ # @param [String, Array<String>] members Specifies the identities requesting access for a Cloud Platform
117
+ # resource. `members` can have the following values. Required.
118
+ #
119
+ # * `allUsers`: A special identifier that represents anyone who is on the internet; with or without a Google
120
+ # account.
121
+ # * `allAuthenticatedUsers`: A special identifier that represents anyone who is authenticated with a Google
122
+ # account or a service account.
123
+ # * `user:<emailid>`: An email address that represents a specific Google account. For example,
124
+ # `alice@example.com`.
125
+ # * `serviceAccount:<emailid>`: An email address that represents a service account. For example,
126
+ # `my-other-app@appspot.gserviceaccount.com`.
127
+ # * `group:<emailid>`: An email address that represents a Google group. For example, `admins@example.com`.
128
+ # * `deleted:user:<emailid>?uid=<uniqueid>`: An email address (plus unique identifier) representing a user
129
+ # that has been recently deleted. For example, `alice@example.com?uid=123456789012345678901`. If the user
130
+ # is recovered, this value reverts to `user:<emailid>` and the recovered user retains the role in the
131
+ # binding.
132
+ # * `deleted: serviceAccount:<emailid>?uid=<uniqueid>`: An email address (plus unique identifier) representing
133
+ # a service account that has been recently deleted. For example,
134
+ # `my-other-app@appspot.gserviceaccount.com?uid=123456789012345678901`. If the service account is undeleted,
135
+ # this value reverts to `serviceAccount:<emailid>` and the undeleted service account retains the role in
136
+ # the binding.
137
+ # * `deleted:group:<emailid>?uid=<uniqueid>`: An email address (plus unique identifier) representing a Google
138
+ # group that has been recently deleted. For example, `admins@example.com?uid=123456789012345678901`. If the
139
+ # group is recovered, this value reverts to `group:<emailid>` and the recovered group retains the role in
140
+ # the binding.
141
+ # * `domain:<domain>`: The G Suite domain (primary) that represents all the users of that domain. For example,
142
+ # `google.com` or `example.com`.
143
+ #
144
+ # @return [nil]
145
+ #
146
+ # @example Grant a role to a member.
147
+ # require "google/cloud/bigquery"
148
+ #
149
+ # bigquery = Google::Cloud::Bigquery.new
150
+ # dataset = bigquery.dataset "my_dataset"
151
+ # table = dataset.table "my_table"
152
+ #
153
+ # table.update_policy do |p|
154
+ # p.grant role: "roles/viewer", members: "user:viewer@example.com"
155
+ # end
156
+ #
157
+ def grant role:, members:
158
+ existing_binding = bindings.find { |b| b.role == role }
159
+ if existing_binding
160
+ existing_binding.members.concat Array(members)
161
+ existing_binding.members.uniq!
162
+ else
163
+ bindings << Binding.new(role, members)
164
+ end
165
+ nil
166
+ end
167
+
168
+ ##
169
+ # Convenience method for removing a binding or bindings from the policy. See
170
+ # [Understanding Roles](https://cloud.google.com/iam/docs/understanding-roles) for a list of primitive and
171
+ # curated roles. See [BigQuery Table ACL
172
+ # permissions](https://cloud.google.com/bigquery/docs/table-access-controls-intro#permissions) for a list of
173
+ # values and patterns for members.
174
+ #
175
+ # @param [String] role A role that is bound to members in the policy. For example, `roles/viewer`,
176
+ # `roles/editor`, or `roles/owner`. Optional.
177
+ # @param [String, Array<String>] members Specifies the identities receiving access for a Cloud Platform
178
+ # resource. `members` can have the following values. Optional.
179
+ #
180
+ # * `allUsers`: A special identifier that represents anyone who is on the internet; with or without a Google
181
+ # account.
182
+ # * `allAuthenticatedUsers`: A special identifier that represents anyone who is authenticated with a Google
183
+ # account or a service account.
184
+ # * `user:<emailid>`: An email address that represents a specific Google account. For example,
185
+ # `alice@example.com`.
186
+ # * `serviceAccount:<emailid>`: An email address that represents a service account. For example,
187
+ # `my-other-app@appspot.gserviceaccount.com`.
188
+ # * `group:<emailid>`: An email address that represents a Google group. For example, `admins@example.com`.
189
+ # * `deleted:user:<emailid>?uid=<uniqueid>`: An email address (plus unique identifier) representing a user
190
+ # that has been recently deleted. For example, `alice@example.com?uid=123456789012345678901`. If the user
191
+ # is recovered, this value reverts to `user:<emailid>` and the recovered user retains the role in the
192
+ # binding.
193
+ # * `deleted: serviceAccount:<emailid>?uid=<uniqueid>`: An email address (plus unique identifier) representing
194
+ # a service account that has been recently deleted. For example,
195
+ # `my-other-app@appspot.gserviceaccount.com?uid=123456789012345678901`. If the service account is undeleted,
196
+ # this value reverts to `serviceAccount:<emailid>` and the undeleted service account retains the role in
197
+ # the binding.
198
+ # * `deleted:group:<emailid>?uid=<uniqueid>`: An email address (plus unique identifier) representing a Google
199
+ # group that has been recently deleted. For example, `admins@example.com?uid=123456789012345678901`. If the
200
+ # group is recovered, this value reverts to `group:<emailid>` and the recovered group retains the role in
201
+ # the binding.
202
+ # * `domain:<domain>`: The G Suite domain (primary) that represents all the users of that domain. For example,
203
+ # `google.com` or `example.com`.
204
+ #
205
+ # @return [nil]
206
+ #
207
+ # @example Revoke a role for a member or members.
208
+ # require "google/cloud/bigquery"
209
+ #
210
+ # bigquery = Google::Cloud::Bigquery.new
211
+ # dataset = bigquery.dataset "my_dataset"
212
+ # table = dataset.table "my_table"
213
+ #
214
+ # table.update_policy do |p|
215
+ # p.revoke role: "roles/viewer", members: "user:viewer@example.com"
216
+ # end
217
+ #
218
+ # @example Revoke a role for all members.
219
+ # require "google/cloud/bigquery"
220
+ #
221
+ # bigquery = Google::Cloud::Bigquery.new
222
+ # dataset = bigquery.dataset "my_dataset"
223
+ # table = dataset.table "my_table"
224
+ #
225
+ # table.update_policy do |p|
226
+ # p.revoke role: "roles/viewer"
227
+ # end
228
+ #
229
+ # @example Revoke all roles for a member or members.
230
+ # require "google/cloud/bigquery"
231
+ #
232
+ # bigquery = Google::Cloud::Bigquery.new
233
+ # dataset = bigquery.dataset "my_dataset"
234
+ # table = dataset.table "my_table"
235
+ #
236
+ # table.update_policy do |p|
237
+ # p.revoke members: ["user:viewer@example.com", "user:editor@example.com"]
238
+ # end
239
+ #
240
+ def revoke role: nil, members: nil
241
+ bindings_for_role = role ? bindings.select { |b| b.role == role } : bindings
242
+ bindings_for_role.each do |b|
243
+ if members
244
+ b.members -= Array(members)
245
+ bindings.delete b if b.members.empty?
246
+ else
247
+ bindings.delete b
248
+ end
249
+ end
250
+ nil
251
+ end
252
+
253
+ ##
254
+ # @private Convert the Policy to a Google::Apis::BigqueryV2::Policy.
255
+ def to_gapi
256
+ Google::Apis::BigqueryV2::Policy.new(
257
+ bindings: bindings_to_gapi,
258
+ etag: etag,
259
+ version: 1
260
+ )
261
+ end
262
+
263
+ ##
264
+ # @private Deep freeze the policy including its bindings.
265
+ def freeze
266
+ super
267
+ @bindings.each(&:freeze)
268
+ @bindings.freeze
269
+ self
270
+ end
271
+
272
+ ##
273
+ # @private New Policy from a Google::Apis::BigqueryV2::Policy object.
274
+ def self.from_gapi gapi
275
+ bindings = Array(gapi.bindings).map do |binding|
276
+ Binding.new binding.role, binding.members.to_a
277
+ end
278
+ new gapi.etag, bindings
279
+ end
280
+
281
+ ##
282
+ # # Policy::Binding
283
+ #
284
+ # Represents a Cloud IAM Binding for BigQuery resources within the context of a {Policy}.
285
+ #
286
+ # A binding binds one or more members to a single role. Member strings can describe user accounts, service
287
+ # accounts, Google groups, and domains. A role is a named list of permissions; each role can be an IAM
288
+ # predefined role or a user-created custom role.
289
+ #
290
+ # @see https://cloud.google.com/bigquery/docs/table-access-controls-intro Controlling access to tables
291
+ #
292
+ # @attr [String] role The role that is assigned to `members`. For example, `roles/viewer`, `roles/editor`, or
293
+ # `roles/owner`. Required.
294
+ # @attr [Array<String>] members Specifies the identities requesting access for a Cloud Platform resource.
295
+ # `members` can have the following values. Required.
296
+ #
297
+ # * `allUsers`: A special identifier that represents anyone who is on the internet; with or without a Google
298
+ # account.
299
+ # * `allAuthenticatedUsers`: A special identifier that represents anyone who is authenticated with a Google
300
+ # account or a service account.
301
+ # * `user:<emailid>`: An email address that represents a specific Google account. For example,
302
+ # `alice@example.com`.
303
+ # * `serviceAccount:<emailid>`: An email address that represents a service account. For example,
304
+ # `my-other-app@appspot.gserviceaccount.com`.
305
+ # * `group:<emailid>`: An email address that represents a Google group. For example, `admins@example.com`.
306
+ # * `deleted:user:<emailid>?uid=<uniqueid>`: An email address (plus unique identifier) representing a user
307
+ # that has been recently deleted. For example, `alice@example.com?uid=123456789012345678901`. If the user
308
+ # is recovered, this value reverts to `user:<emailid>` and the recovered user retains the role in the
309
+ # binding.
310
+ # * `deleted: serviceAccount:<emailid>?uid=<uniqueid>`: An email address (plus unique identifier) representing
311
+ # a service account that has been recently deleted. For example,
312
+ # `my-other-app@appspot.gserviceaccount.com?uid=123456789012345678901`. If the service account is undeleted,
313
+ # this value reverts to `serviceAccount:<emailid>` and the undeleted service account retains the role in
314
+ # the binding.
315
+ # * `deleted:group:<emailid>?uid=<uniqueid>`: An email address (plus unique identifier) representing a Google
316
+ # group that has been recently deleted. For example, `admins@example.com?uid=123456789012345678901`. If the
317
+ # group is recovered, this value reverts to `group:<emailid>` and the recovered group retains the role in
318
+ # the binding.
319
+ # * `domain:<domain>`: The G Suite domain (primary) that represents all the users of that domain. For example,
320
+ # `google.com` or `example.com`.
321
+ #
322
+ # @example
323
+ # require "google/cloud/bigquery"
324
+ #
325
+ # bigquery = Google::Cloud::Bigquery.new
326
+ # dataset = bigquery.dataset "my_dataset"
327
+ # table = dataset.table "my_table"
328
+ #
329
+ # policy = table.policy
330
+ # binding_owner = policy.bindings.find { |b| b.role == "roles/owner" }
331
+ #
332
+ # binding_owner.role #=> "roles/owner"
333
+ # binding_owner.members #=> ["user:owner@example.com"]
334
+ #
335
+ # binding_owner.frozen? #=> true
336
+ # binding_owner.members.frozen? #=> true
337
+ #
338
+ # @example Update mutable bindings.
339
+ # require "google/cloud/bigquery"
340
+ #
341
+ # bigquery = Google::Cloud::Bigquery.new
342
+ # dataset = bigquery.dataset "my_dataset"
343
+ # table = dataset.table "my_table"
344
+ #
345
+ # table.update_policy do |p|
346
+ # binding_owner = p.bindings.find { |b| b.role == "roles/owner" }
347
+ # binding_owner.members.delete_if { |m| m.include? "@example.com" }
348
+ # end
349
+ #
350
+ class Binding
351
+ attr_accessor :role
352
+ attr_reader :members
353
+
354
+ # @private
355
+ def initialize role, members
356
+ members = Array(members).uniq
357
+ raise ArgumentError, "members cannot be empty" if members.empty?
358
+ @role = role
359
+ @members = members
360
+ end
361
+
362
+ ##
363
+ # Sets the binding members.
364
+ #
365
+ # @param [Array<String>] new_members Specifies the identities requesting access for a Cloud Platform resource.
366
+ # `new_members` can have the following values. Required.
367
+ #
368
+ # * `allUsers`: A special identifier that represents anyone who is on the internet; with or without a Google
369
+ # account.
370
+ # * `allAuthenticatedUsers`: A special identifier that represents anyone who is authenticated with a Google
371
+ # account or a service account.
372
+ # * `user:<emailid>`: An email address that represents a specific Google account. For example,
373
+ # `alice@example.com`.
374
+ # * `serviceAccount:<emailid>`: An email address that represents a service account. For example,
375
+ # `my-other-app@appspot.gserviceaccount.com`.
376
+ # * `group:<emailid>`: An email address that represents a Google group. For example, `admins@example.com`.
377
+ # * `deleted:user:<emailid>?uid=<uniqueid>`: An email address (plus unique identifier) representing a user
378
+ # that has been recently deleted. For example, `alice@example.com?uid=123456789012345678901`. If the user
379
+ # is recovered, this value reverts to `user:<emailid>` and the recovered user retains the role in the
380
+ # binding.
381
+ # * `deleted: serviceAccount:<emailid>?uid=<uniqueid>`: An email address (plus unique identifier)
382
+ # representing a service account that has been recently deleted. For example,
383
+ # `my-other-app@appspot.gserviceaccount.com?uid=123456789012345678901`. If the service account is
384
+ # undeleted, this value reverts to `serviceAccount:<emailid>` and the undeleted service account retains
385
+ # the role in the binding.
386
+ # * `deleted:group:<emailid>?uid=<uniqueid>`: An email address (plus unique identifier) representing a
387
+ # Google group that has been recently deleted. For example,
388
+ # `admins@example.com?uid=123456789012345678901`. If the group is recovered, this value reverts to
389
+ # `group:<emailid>` and the recovered group retains the role in the binding.
390
+ # * `domain:<domain>`: The G Suite domain (primary) that represents all the users of that domain. For
391
+ # example, `google.com` or `example.com`.
392
+ #
393
+ def members= new_members
394
+ @members = Array(new_members).uniq
395
+ end
396
+
397
+ ##
398
+ # @private Convert the Binding to a Google::Apis::BigqueryV2::Binding.
399
+ def to_gapi
400
+ Google::Apis::BigqueryV2::Binding.new role: role, members: members
401
+ end
402
+
403
+ ##
404
+ # @private Deep freeze the policy including its members.
405
+ def freeze
406
+ super
407
+ role.freeze
408
+ members.each(&:freeze)
409
+ members.freeze
410
+ self
411
+ end
412
+
413
+ ##
414
+ # @private New Binding from a Google::Apis::BigqueryV2::Binding object.
415
+ def self.from_gapi gapi
416
+ new gapi.etag, gapi.members.to_a
417
+ end
418
+ end
419
+
420
+ protected
421
+
422
+ def bindings_to_gapi
423
+ @bindings.compact.uniq.map do |b|
424
+ next if b.members.empty?
425
+ b.to_gapi
426
+ end
427
+ end
428
+ end
429
+ end
430
+ end
431
+ end