google-cloud-bigquery 1.24.0 → 1.25.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 +12 -0
- data/lib/google/cloud/bigquery/dataset/access.rb +110 -12
- data/lib/google/cloud/bigquery/policy.rb +431 -0
- data/lib/google/cloud/bigquery/service.rb +33 -0
- data/lib/google/cloud/bigquery/table.rb +102 -0
- data/lib/google/cloud/bigquery/version.rb +1 -1
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ae4b6e4d7c37a945f027fe56425698b19b430f5e75451ce82f2156f2dae96719
|
4
|
+
data.tar.gz: d50284a47bf96d5221b574590a60b3af0f77b3a8943d201fd473d78f41a46670
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 56c0b2d3214b385efb3866e502faa0b0c28c2fffc0c3d2ca3c5e1ad05f4d69e0638e68d59d8310c68d01c26c3db55b42225944379bfb8f6ad7a57eec558ced3a
|
7
|
+
data.tar.gz: 0562b98e65e880a40d634f541285241823354a966f4d05a559463a23eacca54addf8843f89b32731d313a56d91dfe2984f6098630c4126d7dbc97033d3dc6a81
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,17 @@
|
|
1
1
|
# Release History
|
2
2
|
|
3
|
+
### 1.25.0 / 2020-11-16
|
4
|
+
|
5
|
+
#### Features
|
6
|
+
|
7
|
+
* Add routine (UDF) to Dataset::Access
|
8
|
+
* Add support for Table ACLS (IAM Policy)
|
9
|
+
* feat(bigquery): Add support for Table ACLS
|
10
|
+
* Add Bigquery::Policy
|
11
|
+
* Add Table#policy
|
12
|
+
* Add Table#test_iam_permissions
|
13
|
+
* Add Table#update_policy
|
14
|
+
|
3
15
|
### 1.24.0 / 2020-10-29
|
4
16
|
|
5
17
|
#### Features
|
@@ -54,6 +54,7 @@ module Google
|
|
54
54
|
"groupByEmail" => :group_by_email,
|
55
55
|
"iam_member" => :iam_member,
|
56
56
|
"iamMember" => :iam_member,
|
57
|
+
"routine" => :routine,
|
57
58
|
"special" => :special_group,
|
58
59
|
"special_group" => :special_group,
|
59
60
|
"specialGroup" => :special_group,
|
@@ -212,6 +213,33 @@ module Google
|
|
212
213
|
add_access_role_scope_value :reader, :special, group
|
213
214
|
end
|
214
215
|
|
216
|
+
##
|
217
|
+
# Add access to a routine from a different dataset. Queries executed
|
218
|
+
# against that routine will have read access to views/tables/routines
|
219
|
+
# in this dataset. Only UDF is supported for now. The role field is
|
220
|
+
# not required when this field is set. If that routine is updated by
|
221
|
+
# any user, access to the routine needs to be granted again via an
|
222
|
+
# update operation.
|
223
|
+
#
|
224
|
+
# @param [Google::Cloud::Bigquery::Routine] routine A routine object.
|
225
|
+
#
|
226
|
+
# @example
|
227
|
+
# require "google/cloud/bigquery"
|
228
|
+
#
|
229
|
+
# bigquery = Google::Cloud::Bigquery.new
|
230
|
+
# dataset = bigquery.dataset "my_dataset"
|
231
|
+
# other_dataset = bigquery.dataset "my_other_dataset", skip_lookup: true
|
232
|
+
#
|
233
|
+
# routine = other_dataset.routine "my_routine"
|
234
|
+
#
|
235
|
+
# dataset.access do |access|
|
236
|
+
# access.add_reader_routine routine
|
237
|
+
# end
|
238
|
+
#
|
239
|
+
def add_reader_routine routine
|
240
|
+
add_access_routine routine
|
241
|
+
end
|
242
|
+
|
215
243
|
##
|
216
244
|
# Add reader access to a view.
|
217
245
|
#
|
@@ -227,9 +255,9 @@ module Google
|
|
227
255
|
#
|
228
256
|
# bigquery = Google::Cloud::Bigquery.new
|
229
257
|
# dataset = bigquery.dataset "my_dataset"
|
230
|
-
# other_dataset = bigquery.dataset "my_other_dataset"
|
258
|
+
# other_dataset = bigquery.dataset "my_other_dataset", skip_lookup: true
|
231
259
|
#
|
232
|
-
# view = other_dataset.table "my_view"
|
260
|
+
# view = other_dataset.table "my_view", skip_lookup: true
|
233
261
|
#
|
234
262
|
# dataset.access do |access|
|
235
263
|
# access.add_reader_view view
|
@@ -533,6 +561,28 @@ module Google
|
|
533
561
|
remove_access_role_scope_value :reader, :special, group
|
534
562
|
end
|
535
563
|
|
564
|
+
##
|
565
|
+
# Remove reader access from a routine from a different dataset.
|
566
|
+
#
|
567
|
+
# @param [Google::Cloud::Bigquery::Routine] routine A routine object.
|
568
|
+
#
|
569
|
+
# @example
|
570
|
+
# require "google/cloud/bigquery"
|
571
|
+
#
|
572
|
+
# bigquery = Google::Cloud::Bigquery.new
|
573
|
+
# dataset = bigquery.dataset "my_dataset"
|
574
|
+
# other_dataset = bigquery.dataset "my_other_dataset", skip_lookup: true
|
575
|
+
#
|
576
|
+
# routine = other_dataset.routine "my_routine", skip_lookup: true
|
577
|
+
#
|
578
|
+
# dataset.access do |access|
|
579
|
+
# access.remove_reader_routine routine
|
580
|
+
# end
|
581
|
+
#
|
582
|
+
def remove_reader_routine routine
|
583
|
+
remove_access_routine routine
|
584
|
+
end
|
585
|
+
|
536
586
|
##
|
537
587
|
# Remove reader access from a view.
|
538
588
|
#
|
@@ -548,9 +598,9 @@ module Google
|
|
548
598
|
#
|
549
599
|
# bigquery = Google::Cloud::Bigquery.new
|
550
600
|
# dataset = bigquery.dataset "my_dataset"
|
551
|
-
# other_dataset = bigquery.dataset "my_other_dataset"
|
601
|
+
# other_dataset = bigquery.dataset "my_other_dataset", skip_lookup: true
|
552
602
|
#
|
553
|
-
# view = other_dataset.table "my_view"
|
603
|
+
# view = other_dataset.table "my_view", skip_lookup: true
|
554
604
|
#
|
555
605
|
# dataset.access do |access|
|
556
606
|
# access.remove_reader_view view
|
@@ -849,6 +899,32 @@ module Google
|
|
849
899
|
lookup_access_role_scope_value :reader, :special, group
|
850
900
|
end
|
851
901
|
|
902
|
+
##
|
903
|
+
# Checks access for a routine from a different dataset. Queries executed
|
904
|
+
# against that routine will have read access to views/tables/routines
|
905
|
+
# in this dataset. Only UDF is supported for now. The role field is
|
906
|
+
# not required when this field is set. If that routine is updated by
|
907
|
+
# any user, access to the routine needs to be granted again via an
|
908
|
+
# update operation.
|
909
|
+
#
|
910
|
+
# @param [Google::Cloud::Bigquery::Routine] routine A routine object.
|
911
|
+
#
|
912
|
+
# @example
|
913
|
+
# require "google/cloud/bigquery"
|
914
|
+
#
|
915
|
+
# bigquery = Google::Cloud::Bigquery.new
|
916
|
+
# dataset = bigquery.dataset "my_dataset"
|
917
|
+
# other_dataset = bigquery.dataset "my_other_dataset", skip_lookup: true
|
918
|
+
#
|
919
|
+
# routine = other_dataset.routine "my_routine", skip_lookup: true
|
920
|
+
#
|
921
|
+
# access = dataset.access
|
922
|
+
# access.reader_routine? routine #=> false
|
923
|
+
#
|
924
|
+
def reader_routine? routine
|
925
|
+
lookup_access_routine routine
|
926
|
+
end
|
927
|
+
|
852
928
|
##
|
853
929
|
# Checks reader access for a view.
|
854
930
|
#
|
@@ -864,9 +940,9 @@ module Google
|
|
864
940
|
#
|
865
941
|
# bigquery = Google::Cloud::Bigquery.new
|
866
942
|
# dataset = bigquery.dataset "my_dataset"
|
867
|
-
# other_dataset = bigquery.dataset "my_other_dataset"
|
943
|
+
# other_dataset = bigquery.dataset "my_other_dataset", skip_lookup: true
|
868
944
|
#
|
869
|
-
# view = other_dataset.table "my_view"
|
945
|
+
# view = other_dataset.table "my_view", skip_lookup: true
|
870
946
|
#
|
871
947
|
# access = dataset.access
|
872
948
|
# access.reader_view? view #=> false
|
@@ -1121,12 +1197,22 @@ module Google
|
|
1121
1197
|
@rules << Google::Apis::BigqueryV2::Dataset::Access.new(opts)
|
1122
1198
|
end
|
1123
1199
|
|
1200
|
+
# @private
|
1201
|
+
def add_access_routine routine
|
1202
|
+
value = routine.routine_ref
|
1203
|
+
# Remove existing routine rule, if any
|
1204
|
+
@rules.reject!(&find_by_scope_and_resource_ref(:routine, value))
|
1205
|
+
# Add new rule for this role, scope, and value
|
1206
|
+
opts = { routine: value }
|
1207
|
+
@rules << Google::Apis::BigqueryV2::Dataset::Access.new(opts)
|
1208
|
+
end
|
1209
|
+
|
1124
1210
|
# @private
|
1125
1211
|
def add_access_view value
|
1126
1212
|
# scope is view, make sure value is in the right format
|
1127
1213
|
value = validate_view value
|
1128
1214
|
# Remove existing view rule, if any
|
1129
|
-
@rules.reject!(&
|
1215
|
+
@rules.reject!(&find_by_scope_and_resource_ref(:view, value))
|
1130
1216
|
# Add new rule for this role, scope, and value
|
1131
1217
|
opts = { view: value }
|
1132
1218
|
@rules << Google::Apis::BigqueryV2::Dataset::Access.new(opts)
|
@@ -1144,12 +1230,18 @@ module Google
|
|
1144
1230
|
)
|
1145
1231
|
end
|
1146
1232
|
|
1233
|
+
# @private
|
1234
|
+
def remove_access_routine routine
|
1235
|
+
# Remove existing routine rule, if any
|
1236
|
+
@rules.reject!(&find_by_scope_and_resource_ref(:routine, routine.routine_ref))
|
1237
|
+
end
|
1238
|
+
|
1147
1239
|
# @private
|
1148
1240
|
def remove_access_view value
|
1149
1241
|
# scope is view, make sure value is in the right format
|
1150
1242
|
value = validate_view value
|
1151
1243
|
# Remove existing view rule, if any
|
1152
|
-
@rules.reject!(&
|
1244
|
+
@rules.reject!(&find_by_scope_and_resource_ref(:view, value))
|
1153
1245
|
end
|
1154
1246
|
|
1155
1247
|
# @private
|
@@ -1162,12 +1254,18 @@ module Google
|
|
1162
1254
|
!(!@rules.detect(&find_by_role_and_scope_and_value(role, scope, value)))
|
1163
1255
|
end
|
1164
1256
|
|
1257
|
+
# @private
|
1258
|
+
def lookup_access_routine routine
|
1259
|
+
# Detect routine rule, if any
|
1260
|
+
!(!@rules.detect(&find_by_scope_and_resource_ref(:routine, routine.routine_ref)))
|
1261
|
+
end
|
1262
|
+
|
1165
1263
|
# @private
|
1166
1264
|
def lookup_access_view value
|
1167
1265
|
# scope is view, make sure value is in the right format
|
1168
1266
|
value = validate_view value
|
1169
1267
|
# Detect view rule, if any
|
1170
|
-
!(!@rules.detect(&
|
1268
|
+
!(!@rules.detect(&find_by_scope_and_resource_ref(:view, value)))
|
1171
1269
|
end
|
1172
1270
|
|
1173
1271
|
# @private
|
@@ -1186,11 +1284,11 @@ module Google
|
|
1186
1284
|
end
|
1187
1285
|
end
|
1188
1286
|
|
1189
|
-
# @private
|
1190
|
-
def
|
1287
|
+
# @private Compare hash representations to find table_ref, routine_ref.
|
1288
|
+
def find_by_scope_and_resource_ref scope, value
|
1191
1289
|
lambda do |a|
|
1192
1290
|
h = a.to_h
|
1193
|
-
h[
|
1291
|
+
h[scope].to_h == value.to_h
|
1194
1292
|
end
|
1195
1293
|
end
|
1196
1294
|
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
|
@@ -182,6 +182,34 @@ module Google
|
|
182
182
|
end
|
183
183
|
end
|
184
184
|
|
185
|
+
##
|
186
|
+
# Returns Google::Apis::BigqueryV2::Policy
|
187
|
+
def get_table_policy dataset_id, table_id
|
188
|
+
policy_options = API::GetPolicyOptions.new requested_policy_version: 1
|
189
|
+
execute do
|
190
|
+
service.get_table_iam_policy table_path(dataset_id, table_id),
|
191
|
+
API::GetIamPolicyRequest.new(options: policy_options)
|
192
|
+
end
|
193
|
+
end
|
194
|
+
|
195
|
+
##
|
196
|
+
# @param [Google::Apis::BigqueryV2::Policy] new_policy
|
197
|
+
def set_table_policy dataset_id, table_id, new_policy
|
198
|
+
execute do
|
199
|
+
service.set_table_iam_policy table_path(dataset_id, table_id),
|
200
|
+
API::SetIamPolicyRequest.new(policy: new_policy)
|
201
|
+
end
|
202
|
+
end
|
203
|
+
|
204
|
+
##
|
205
|
+
# Returns Google::Apis::BigqueryV2::TestIamPermissionsResponse
|
206
|
+
def test_table_permissions dataset_id, table_id, permissions
|
207
|
+
execute do
|
208
|
+
service.test_table_iam_permissions table_path(dataset_id, table_id),
|
209
|
+
API::TestIamPermissionsRequest.new(permissions: permissions)
|
210
|
+
end
|
211
|
+
end
|
212
|
+
|
185
213
|
##
|
186
214
|
# Deletes the table specified by tableId from the dataset.
|
187
215
|
# If the table contains data, all the data will be deleted.
|
@@ -508,6 +536,11 @@ module Google
|
|
508
536
|
|
509
537
|
protected
|
510
538
|
|
539
|
+
# Creates a formatted table path.
|
540
|
+
def table_path dataset_id, table_id
|
541
|
+
"projects/#{@project}/datasets/#{dataset_id}/tables/#{table_id}"
|
542
|
+
end
|
543
|
+
|
511
544
|
# Generate a random string similar to the BigQuery service job IDs.
|
512
545
|
def generate_id
|
513
546
|
SecureRandom.urlsafe_base64 21
|
@@ -23,6 +23,7 @@ require "google/cloud/bigquery/external"
|
|
23
23
|
require "google/cloud/bigquery/insert_response"
|
24
24
|
require "google/cloud/bigquery/table/async_inserter"
|
25
25
|
require "google/cloud/bigquery/convert"
|
26
|
+
require "google/cloud/bigquery/policy"
|
26
27
|
require "google/apis/bigquery_v2"
|
27
28
|
|
28
29
|
module Google
|
@@ -1274,6 +1275,107 @@ module Google
|
|
1274
1275
|
Array(udfs_gapi).map { |udf| udf.inline_code || udf.resource_uri }
|
1275
1276
|
end
|
1276
1277
|
|
1278
|
+
##
|
1279
|
+
# Gets the Cloud IAM access control policy for the table. The latest policy will be read from the service. See
|
1280
|
+
# also {#update_policy}.
|
1281
|
+
#
|
1282
|
+
# @see https://cloud.google.com/iam/docs/managing-policies Managing Policies
|
1283
|
+
# @see https://cloud.google.com/bigquery/docs/table-access-controls-intro Controlling access to tables
|
1284
|
+
#
|
1285
|
+
# @return [Policy] The frozen policy for the table.
|
1286
|
+
#
|
1287
|
+
# @example
|
1288
|
+
# require "google/cloud/bigquery"
|
1289
|
+
#
|
1290
|
+
# bigquery = Google::Cloud::Bigquery.new
|
1291
|
+
# dataset = bigquery.dataset "my_dataset"
|
1292
|
+
# table = dataset.table "my_table"
|
1293
|
+
#
|
1294
|
+
# policy = table.policy
|
1295
|
+
#
|
1296
|
+
# policy.frozen? #=> true
|
1297
|
+
# binding_owner = policy.bindings.find { |b| b.role == "roles/owner" }
|
1298
|
+
# binding_owner.role #=> "roles/owner"
|
1299
|
+
# binding_owner.members #=> ["user:owner@example.com"]
|
1300
|
+
# binding_owner.frozen? #=> true
|
1301
|
+
# binding_owner.members.frozen? #=> true
|
1302
|
+
#
|
1303
|
+
def policy
|
1304
|
+
raise ArgumentError, "Block argument not supported: Use #update_policy instead." if block_given?
|
1305
|
+
ensure_service!
|
1306
|
+
gapi = service.get_table_policy dataset_id, table_id
|
1307
|
+
Policy.from_gapi(gapi).freeze
|
1308
|
+
end
|
1309
|
+
|
1310
|
+
##
|
1311
|
+
# Updates the Cloud IAM access control policy for the table. The latest policy will be read from the service.
|
1312
|
+
# See also {#policy}.
|
1313
|
+
#
|
1314
|
+
# @see https://cloud.google.com/iam/docs/managing-policies Managing Policies
|
1315
|
+
# @see https://cloud.google.com/bigquery/docs/table-access-controls-intro Controlling access to tables
|
1316
|
+
#
|
1317
|
+
# @yield [policy] A block for updating the policy. The latest policy will be read from the service and passed to
|
1318
|
+
# the block. After the block completes, the modified policy will be written to the service.
|
1319
|
+
# @yieldparam [Policy] policy The mutable Policy for the table.
|
1320
|
+
#
|
1321
|
+
# @return [Policy] The updated and frozen policy for the table.
|
1322
|
+
#
|
1323
|
+
# @example Update the policy by passing a block.
|
1324
|
+
# require "google/cloud/bigquery"
|
1325
|
+
#
|
1326
|
+
# bigquery = Google::Cloud::Bigquery.new
|
1327
|
+
# dataset = bigquery.dataset "my_dataset"
|
1328
|
+
# table = dataset.table "my_table"
|
1329
|
+
#
|
1330
|
+
# table.update_policy do |p|
|
1331
|
+
# p.grant role: "roles/viewer", members: "user:viewer@example.com"
|
1332
|
+
# p.revoke role: "roles/editor", members: "user:editor@example.com"
|
1333
|
+
# p.revoke role: "roles/owner"
|
1334
|
+
# end # 2 API calls
|
1335
|
+
#
|
1336
|
+
def update_policy
|
1337
|
+
raise ArgumentError, "A block updating the policy must be provided" unless block_given?
|
1338
|
+
ensure_service!
|
1339
|
+
gapi = service.get_table_policy dataset_id, table_id
|
1340
|
+
policy = Policy.from_gapi gapi
|
1341
|
+
yield policy
|
1342
|
+
# TODO: Check for changes before calling RPC
|
1343
|
+
gapi = service.set_table_policy dataset_id, table_id, policy.to_gapi
|
1344
|
+
Policy.from_gapi(gapi).freeze
|
1345
|
+
end
|
1346
|
+
|
1347
|
+
##
|
1348
|
+
# Tests the specified permissions against the [Cloud
|
1349
|
+
# IAM](https://cloud.google.com/iam/) access control policy.
|
1350
|
+
#
|
1351
|
+
# @see https://cloud.google.com/iam/docs/managing-policies Managing Policies
|
1352
|
+
#
|
1353
|
+
# @param [String, Array<String>] permissions The set of permissions
|
1354
|
+
# against which to check access. Permissions must be of the format
|
1355
|
+
# `bigquery.resource.capability`.
|
1356
|
+
# See https://cloud.google.com/bigquery/docs/access-control#bigquery.
|
1357
|
+
#
|
1358
|
+
# @return [Array<String>] The frozen array of permissions held by the caller.
|
1359
|
+
#
|
1360
|
+
# @example
|
1361
|
+
# require "google/cloud/bigquery"
|
1362
|
+
#
|
1363
|
+
# bigquery = Google::Cloud::Bigquery.new
|
1364
|
+
# dataset = bigquery.dataset "my_dataset"
|
1365
|
+
# table = dataset.table "my_table"
|
1366
|
+
#
|
1367
|
+
# permissions = table.test_iam_permissions "bigquery.tables.get",
|
1368
|
+
# "bigquery.tables.delete"
|
1369
|
+
# permissions.include? "bigquery.tables.get" #=> true
|
1370
|
+
# permissions.include? "bigquery.tables.delete" #=> false
|
1371
|
+
#
|
1372
|
+
def test_iam_permissions *permissions
|
1373
|
+
permissions = Array(permissions).flatten
|
1374
|
+
ensure_service!
|
1375
|
+
gapi = service.test_table_permissions dataset_id, table_id, permissions
|
1376
|
+
gapi.permissions.freeze
|
1377
|
+
end
|
1378
|
+
|
1277
1379
|
##
|
1278
1380
|
# Retrieves data from the table.
|
1279
1381
|
#
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: google-cloud-bigquery
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.25.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Mike Moore
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2020-
|
12
|
+
date: 2020-11-16 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: concurrent-ruby
|
@@ -257,6 +257,7 @@ files:
|
|
257
257
|
- lib/google/cloud/bigquery/load_job.rb
|
258
258
|
- lib/google/cloud/bigquery/model.rb
|
259
259
|
- lib/google/cloud/bigquery/model/list.rb
|
260
|
+
- lib/google/cloud/bigquery/policy.rb
|
260
261
|
- lib/google/cloud/bigquery/project.rb
|
261
262
|
- lib/google/cloud/bigquery/project/list.rb
|
262
263
|
- lib/google/cloud/bigquery/query_job.rb
|