google-cloud-bigquery 1.23.0 → 1.28.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +62 -0
- data/CONTRIBUTING.md +1 -1
- data/lib/google/cloud/bigquery/dataset.rb +97 -10
- data/lib/google/cloud/bigquery/dataset/access.rb +293 -16
- data/lib/google/cloud/bigquery/external.rb +328 -3
- data/lib/google/cloud/bigquery/extract_job.rb +4 -8
- data/lib/google/cloud/bigquery/job.rb +35 -1
- data/lib/google/cloud/bigquery/load_job.rb +182 -28
- data/lib/google/cloud/bigquery/policy.rb +431 -0
- data/lib/google/cloud/bigquery/project.rb +1 -2
- data/lib/google/cloud/bigquery/query_job.rb +9 -6
- data/lib/google/cloud/bigquery/routine.rb +127 -5
- data/lib/google/cloud/bigquery/service.rb +35 -0
- data/lib/google/cloud/bigquery/table.rb +257 -41
- data/lib/google/cloud/bigquery/version.rb +1 -1
- metadata +7 -6
@@ -37,8 +37,8 @@ module Google
|
|
37
37
|
# bigquery = Google::Cloud::Bigquery.new
|
38
38
|
# dataset = bigquery.dataset "my_dataset"
|
39
39
|
#
|
40
|
-
#
|
41
|
-
# load_job = dataset.load_job "my_new_table",
|
40
|
+
# gcs_uri = "gs://my-bucket/file-name.csv"
|
41
|
+
# load_job = dataset.load_job "my_new_table", gcs_uri do |schema|
|
42
42
|
# schema.string "first_name", mode: :required
|
43
43
|
# schema.record "cities_lived", mode: :repeated do |nested_schema|
|
44
44
|
# nested_schema.string "place", mode: :required
|
@@ -112,8 +112,7 @@ module Google
|
|
112
112
|
# `false` otherwise.
|
113
113
|
#
|
114
114
|
def iso8859_1?
|
115
|
-
|
116
|
-
val == "ISO-8859-1"
|
115
|
+
@gapi.configuration.load.encoding == "ISO-8859-1"
|
117
116
|
end
|
118
117
|
|
119
118
|
##
|
@@ -195,8 +194,7 @@ module Google
|
|
195
194
|
# `NEWLINE_DELIMITED_JSON`, `false` otherwise.
|
196
195
|
#
|
197
196
|
def json?
|
198
|
-
|
199
|
-
val == "NEWLINE_DELIMITED_JSON"
|
197
|
+
@gapi.configuration.load.source_format == "NEWLINE_DELIMITED_JSON"
|
200
198
|
end
|
201
199
|
|
202
200
|
##
|
@@ -218,8 +216,27 @@ module Google
|
|
218
216
|
# `false` otherwise.
|
219
217
|
#
|
220
218
|
def backup?
|
221
|
-
|
222
|
-
|
219
|
+
@gapi.configuration.load.source_format == "DATASTORE_BACKUP"
|
220
|
+
end
|
221
|
+
|
222
|
+
##
|
223
|
+
# Checks if the source format is ORC.
|
224
|
+
#
|
225
|
+
# @return [Boolean] `true` when the source format is `ORC`,
|
226
|
+
# `false` otherwise.
|
227
|
+
#
|
228
|
+
def orc?
|
229
|
+
@gapi.configuration.load.source_format == "ORC"
|
230
|
+
end
|
231
|
+
|
232
|
+
##
|
233
|
+
# Checks if the source format is Parquet.
|
234
|
+
#
|
235
|
+
# @return [Boolean] `true` when the source format is `PARQUET`,
|
236
|
+
# `false` otherwise.
|
237
|
+
#
|
238
|
+
def parquet?
|
239
|
+
@gapi.configuration.load.source_format == "PARQUET"
|
223
240
|
end
|
224
241
|
|
225
242
|
##
|
@@ -347,6 +364,58 @@ module Google
|
|
347
364
|
nil
|
348
365
|
end
|
349
366
|
|
367
|
+
###
|
368
|
+
# Checks if hive partitioning options are set.
|
369
|
+
#
|
370
|
+
# @see https://cloud.google.com/bigquery/docs/hive-partitioned-loads-gcs Loading externally partitioned data
|
371
|
+
#
|
372
|
+
# @return [Boolean] `true` when hive partitioning options are set, or `false` otherwise.
|
373
|
+
#
|
374
|
+
# @!group Attributes
|
375
|
+
#
|
376
|
+
def hive_partitioning?
|
377
|
+
!@gapi.configuration.load.hive_partitioning_options.nil?
|
378
|
+
end
|
379
|
+
|
380
|
+
###
|
381
|
+
# The mode of hive partitioning to use when reading data. The following modes are supported:
|
382
|
+
#
|
383
|
+
# 1. `AUTO`: automatically infer partition key name(s) and type(s).
|
384
|
+
# 2. `STRINGS`: automatically infer partition key name(s). All types are interpreted as strings.
|
385
|
+
# 3. `CUSTOM`: partition key schema is encoded in the source URI prefix.
|
386
|
+
#
|
387
|
+
# @see https://cloud.google.com/bigquery/docs/hive-partitioned-loads-gcs Loading externally partitioned data
|
388
|
+
#
|
389
|
+
# @return [String, nil] The mode of hive partitioning, or `nil` if not set.
|
390
|
+
#
|
391
|
+
# @!group Attributes
|
392
|
+
#
|
393
|
+
def hive_partitioning_mode
|
394
|
+
@gapi.configuration.load.hive_partitioning_options.mode if hive_partitioning?
|
395
|
+
end
|
396
|
+
|
397
|
+
###
|
398
|
+
# The common prefix for all source uris when hive partition detection is requested. The prefix must end
|
399
|
+
# immediately before the partition key encoding begins. For example, consider files following this data layout:
|
400
|
+
#
|
401
|
+
# ```
|
402
|
+
# gs://bucket/path_to_table/dt=2019-01-01/country=BR/id=7/file.avro
|
403
|
+
# gs://bucket/path_to_table/dt=2018-12-31/country=CA/id=3/file.avro
|
404
|
+
# ```
|
405
|
+
#
|
406
|
+
# When hive partitioning is requested with either `AUTO` or `STRINGS` mode, the common prefix can be either of
|
407
|
+
# `gs://bucket/path_to_table` or `gs://bucket/path_to_table/` (trailing slash does not matter).
|
408
|
+
#
|
409
|
+
# @see https://cloud.google.com/bigquery/docs/hive-partitioned-loads-gcs Loading externally partitioned data
|
410
|
+
#
|
411
|
+
# @return [String, nil] The common prefix for all source uris, or `nil` if not set.
|
412
|
+
#
|
413
|
+
# @!group Attributes
|
414
|
+
#
|
415
|
+
def hive_partitioning_source_uri_prefix
|
416
|
+
@gapi.configuration.load.hive_partitioning_options.source_uri_prefix if hive_partitioning?
|
417
|
+
end
|
418
|
+
|
350
419
|
###
|
351
420
|
# Checks if the destination table will be range partitioned. See [Creating and using integer range partitioned
|
352
421
|
# tables](https://cloud.google.com/bigquery/docs/creating-integer-range-partitions).
|
@@ -428,8 +497,9 @@ module Google
|
|
428
497
|
# The period for which the destination table will be time partitioned, if
|
429
498
|
# any. See [Partitioned Tables](https://cloud.google.com/bigquery/docs/partitioned-tables).
|
430
499
|
#
|
431
|
-
# @return [String, nil] The time partition type.
|
432
|
-
#
|
500
|
+
# @return [String, nil] The time partition type. The supported types are `DAY`,
|
501
|
+
# `HOUR`, `MONTH`, and `YEAR`, which will generate one partition per day,
|
502
|
+
# hour, month, and year, respectively; or `nil` if not present.
|
433
503
|
#
|
434
504
|
# @!group Attributes
|
435
505
|
#
|
@@ -1325,6 +1395,89 @@ module Google
|
|
1325
1395
|
@gapi.configuration.update! labels: val
|
1326
1396
|
end
|
1327
1397
|
|
1398
|
+
##
|
1399
|
+
# Sets the mode of hive partitioning to use when reading data. The following modes are supported:
|
1400
|
+
#
|
1401
|
+
# 1. `auto`: automatically infer partition key name(s) and type(s).
|
1402
|
+
# 2. `strings`: automatically infer partition key name(s). All types are interpreted as strings.
|
1403
|
+
# 3. `custom`: partition key schema is encoded in the source URI prefix.
|
1404
|
+
#
|
1405
|
+
# Not all storage formats support hive partitioning. Requesting hive partitioning on an unsupported format
|
1406
|
+
# will lead to an error. Currently supported types include: `avro`, `csv`, `json`, `orc` and `parquet`.
|
1407
|
+
#
|
1408
|
+
# See {#format=} and {#hive_partitioning_source_uri_prefix=}.
|
1409
|
+
#
|
1410
|
+
# @see https://cloud.google.com/bigquery/docs/hive-partitioned-loads-gcs Loading externally partitioned data
|
1411
|
+
#
|
1412
|
+
# @param [String, Symbol] mode The mode of hive partitioning to use when reading data.
|
1413
|
+
#
|
1414
|
+
# @example
|
1415
|
+
# require "google/cloud/bigquery"
|
1416
|
+
#
|
1417
|
+
# bigquery = Google::Cloud::Bigquery.new
|
1418
|
+
# dataset = bigquery.dataset "my_dataset"
|
1419
|
+
#
|
1420
|
+
# gcs_uri = "gs://cloud-samples-data/bigquery/hive-partitioning-samples/autolayout/*"
|
1421
|
+
# source_uri_prefix = "gs://cloud-samples-data/bigquery/hive-partitioning-samples/autolayout/"
|
1422
|
+
# load_job = dataset.load_job "my_new_table", gcs_uri do |job|
|
1423
|
+
# job.format = :parquet
|
1424
|
+
# job.hive_partitioning_mode = :auto
|
1425
|
+
# job.hive_partitioning_source_uri_prefix = source_uri_prefix
|
1426
|
+
# end
|
1427
|
+
#
|
1428
|
+
# load_job.wait_until_done!
|
1429
|
+
# load_job.done? #=> true
|
1430
|
+
#
|
1431
|
+
# @!group Attributes
|
1432
|
+
#
|
1433
|
+
def hive_partitioning_mode= mode
|
1434
|
+
@gapi.configuration.load.hive_partitioning_options ||= Google::Apis::BigqueryV2::HivePartitioningOptions.new
|
1435
|
+
@gapi.configuration.load.hive_partitioning_options.mode = mode.to_s.upcase
|
1436
|
+
end
|
1437
|
+
|
1438
|
+
##
|
1439
|
+
# Sets the common prefix for all source uris when hive partition detection is requested. The prefix must end
|
1440
|
+
# immediately before the partition key encoding begins. For example, consider files following this data
|
1441
|
+
# layout:
|
1442
|
+
#
|
1443
|
+
# ```
|
1444
|
+
# gs://bucket/path_to_table/dt=2019-01-01/country=BR/id=7/file.avro
|
1445
|
+
# gs://bucket/path_to_table/dt=2018-12-31/country=CA/id=3/file.avro
|
1446
|
+
# ```
|
1447
|
+
#
|
1448
|
+
# When hive partitioning is requested with either `AUTO` or `STRINGS` mode, the common prefix can be either of
|
1449
|
+
# `gs://bucket/path_to_table` or `gs://bucket/path_to_table/` (trailing slash does not matter).
|
1450
|
+
#
|
1451
|
+
# See {#hive_partitioning_mode=}.
|
1452
|
+
#
|
1453
|
+
# @see https://cloud.google.com/bigquery/docs/hive-partitioned-loads-gcs Loading externally partitioned data
|
1454
|
+
#
|
1455
|
+
# @param [String] source_uri_prefix The common prefix for all source uris.
|
1456
|
+
#
|
1457
|
+
# @example
|
1458
|
+
# require "google/cloud/bigquery"
|
1459
|
+
#
|
1460
|
+
# bigquery = Google::Cloud::Bigquery.new
|
1461
|
+
# dataset = bigquery.dataset "my_dataset"
|
1462
|
+
#
|
1463
|
+
# gcs_uri = "gs://cloud-samples-data/bigquery/hive-partitioning-samples/autolayout/*"
|
1464
|
+
# source_uri_prefix = "gs://cloud-samples-data/bigquery/hive-partitioning-samples/autolayout/"
|
1465
|
+
# load_job = dataset.load_job "my_new_table", gcs_uri do |job|
|
1466
|
+
# job.format = :parquet
|
1467
|
+
# job.hive_partitioning_mode = :auto
|
1468
|
+
# job.hive_partitioning_source_uri_prefix = source_uri_prefix
|
1469
|
+
# end
|
1470
|
+
#
|
1471
|
+
# load_job.wait_until_done!
|
1472
|
+
# load_job.done? #=> true
|
1473
|
+
#
|
1474
|
+
# @!group Attributes
|
1475
|
+
#
|
1476
|
+
def hive_partitioning_source_uri_prefix= source_uri_prefix
|
1477
|
+
@gapi.configuration.load.hive_partitioning_options ||= Google::Apis::BigqueryV2::HivePartitioningOptions.new
|
1478
|
+
@gapi.configuration.load.hive_partitioning_options.source_uri_prefix = source_uri_prefix
|
1479
|
+
end
|
1480
|
+
|
1328
1481
|
##
|
1329
1482
|
# Sets the field on which to range partition the table. See [Creating and using integer range partitioned
|
1330
1483
|
# tables](https://cloud.google.com/bigquery/docs/creating-integer-range-partitions).
|
@@ -1344,8 +1497,8 @@ module Google
|
|
1344
1497
|
# bigquery = Google::Cloud::Bigquery.new
|
1345
1498
|
# dataset = bigquery.dataset "my_dataset"
|
1346
1499
|
#
|
1347
|
-
#
|
1348
|
-
# load_job = dataset.load_job "my_new_table",
|
1500
|
+
# gcs_uri = "gs://my-bucket/file-name.csv"
|
1501
|
+
# load_job = dataset.load_job "my_new_table", gcs_uri do |job|
|
1349
1502
|
# job.schema do |schema|
|
1350
1503
|
# schema.integer "my_table_id", mode: :required
|
1351
1504
|
# schema.string "my_table_data", mode: :required
|
@@ -1385,8 +1538,8 @@ module Google
|
|
1385
1538
|
# bigquery = Google::Cloud::Bigquery.new
|
1386
1539
|
# dataset = bigquery.dataset "my_dataset"
|
1387
1540
|
#
|
1388
|
-
#
|
1389
|
-
# load_job = dataset.load_job "my_new_table",
|
1541
|
+
# gcs_uri = "gs://my-bucket/file-name.csv"
|
1542
|
+
# load_job = dataset.load_job "my_new_table", gcs_uri do |job|
|
1390
1543
|
# job.schema do |schema|
|
1391
1544
|
# schema.integer "my_table_id", mode: :required
|
1392
1545
|
# schema.string "my_table_data", mode: :required
|
@@ -1426,8 +1579,8 @@ module Google
|
|
1426
1579
|
# bigquery = Google::Cloud::Bigquery.new
|
1427
1580
|
# dataset = bigquery.dataset "my_dataset"
|
1428
1581
|
#
|
1429
|
-
#
|
1430
|
-
# load_job = dataset.load_job "my_new_table",
|
1582
|
+
# gcs_uri = "gs://my-bucket/file-name.csv"
|
1583
|
+
# load_job = dataset.load_job "my_new_table", gcs_uri do |job|
|
1431
1584
|
# job.schema do |schema|
|
1432
1585
|
# schema.integer "my_table_id", mode: :required
|
1433
1586
|
# schema.string "my_table_data", mode: :required
|
@@ -1467,8 +1620,8 @@ module Google
|
|
1467
1620
|
# bigquery = Google::Cloud::Bigquery.new
|
1468
1621
|
# dataset = bigquery.dataset "my_dataset"
|
1469
1622
|
#
|
1470
|
-
#
|
1471
|
-
# load_job = dataset.load_job "my_new_table",
|
1623
|
+
# gcs_uri = "gs://my-bucket/file-name.csv"
|
1624
|
+
# load_job = dataset.load_job "my_new_table", gcs_uri do |job|
|
1472
1625
|
# job.schema do |schema|
|
1473
1626
|
# schema.integer "my_table_id", mode: :required
|
1474
1627
|
# schema.string "my_table_data", mode: :required
|
@@ -1499,8 +1652,9 @@ module Google
|
|
1499
1652
|
# BigQuery does not allow you to change partitioning on an existing
|
1500
1653
|
# table.
|
1501
1654
|
#
|
1502
|
-
# @param [String] type The time partition type.
|
1503
|
-
#
|
1655
|
+
# @param [String] type The time partition type. The supported types are `DAY`,
|
1656
|
+
# `HOUR`, `MONTH`, and `YEAR`, which will generate one partition per day,
|
1657
|
+
# hour, month, and year, respectively.
|
1504
1658
|
#
|
1505
1659
|
# @example
|
1506
1660
|
# require "google/cloud/bigquery"
|
@@ -1508,8 +1662,8 @@ module Google
|
|
1508
1662
|
# bigquery = Google::Cloud::Bigquery.new
|
1509
1663
|
# dataset = bigquery.dataset "my_dataset"
|
1510
1664
|
#
|
1511
|
-
#
|
1512
|
-
# load_job = dataset.load_job "my_new_table",
|
1665
|
+
# gcs_uri = "gs://my-bucket/file-name.csv"
|
1666
|
+
# load_job = dataset.load_job "my_new_table", gcs_uri do |job|
|
1513
1667
|
# job.time_partitioning_type = "DAY"
|
1514
1668
|
# end
|
1515
1669
|
#
|
@@ -1547,8 +1701,8 @@ module Google
|
|
1547
1701
|
# bigquery = Google::Cloud::Bigquery.new
|
1548
1702
|
# dataset = bigquery.dataset "my_dataset"
|
1549
1703
|
#
|
1550
|
-
#
|
1551
|
-
# load_job = dataset.load_job "my_new_table",
|
1704
|
+
# gcs_uri = "gs://my-bucket/file-name.csv"
|
1705
|
+
# load_job = dataset.load_job "my_new_table", gcs_uri do |job|
|
1552
1706
|
# job.time_partitioning_type = "DAY"
|
1553
1707
|
# job.time_partitioning_field = "dob"
|
1554
1708
|
# job.schema do |schema|
|
@@ -1583,8 +1737,8 @@ module Google
|
|
1583
1737
|
# bigquery = Google::Cloud::Bigquery.new
|
1584
1738
|
# dataset = bigquery.dataset "my_dataset"
|
1585
1739
|
#
|
1586
|
-
#
|
1587
|
-
# load_job = dataset.load_job "my_new_table",
|
1740
|
+
# gcs_uri = "gs://my-bucket/file-name.csv"
|
1741
|
+
# load_job = dataset.load_job "my_new_table", gcs_uri do |job|
|
1588
1742
|
# job.time_partitioning_type = "DAY"
|
1589
1743
|
# job.time_partitioning_expiration = 86_400
|
1590
1744
|
# end
|
@@ -1643,8 +1797,8 @@ module Google
|
|
1643
1797
|
# bigquery = Google::Cloud::Bigquery.new
|
1644
1798
|
# dataset = bigquery.dataset "my_dataset"
|
1645
1799
|
#
|
1646
|
-
#
|
1647
|
-
# load_job = dataset.load_job "my_new_table",
|
1800
|
+
# gcs_uri = "gs://my-bucket/file-name.csv"
|
1801
|
+
# load_job = dataset.load_job "my_new_table", gcs_uri do |job|
|
1648
1802
|
# job.time_partitioning_type = "DAY"
|
1649
1803
|
# job.time_partitioning_field = "dob"
|
1650
1804
|
# job.schema do |schema|
|
@@ -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
|