gazer 0.2.9
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 +7 -0
- data/.gitignore +15 -0
- data/.rspec +3 -0
- data/.ruby-version +1 -0
- data/.travis.yml +5 -0
- data/CODE_OF_CONDUCT.md +74 -0
- data/Gemfile +35 -0
- data/Gemfile.lock +150 -0
- data/LICENSE.txt +20 -0
- data/README.md +527 -0
- data/Rakefile +27 -0
- data/bin/console +35 -0
- data/bin/setup +30 -0
- data/exe/gzr +40 -0
- data/gzr.gemspec +67 -0
- data/lib/gzr.rb +25 -0
- data/lib/gzr/cli.rb +86 -0
- data/lib/gzr/command.rb +251 -0
- data/lib/gzr/commands/.gitkeep +1 -0
- data/lib/gzr/commands/connection.rb +69 -0
- data/lib/gzr/commands/connection/dialects.rb +72 -0
- data/lib/gzr/commands/connection/ls.rb +72 -0
- data/lib/gzr/commands/dashboard.rb +75 -0
- data/lib/gzr/commands/dashboard/cat.rb +67 -0
- data/lib/gzr/commands/dashboard/import.rb +256 -0
- data/lib/gzr/commands/dashboard/rm.rb +47 -0
- data/lib/gzr/commands/group.rb +87 -0
- data/lib/gzr/commands/group/ls.rb +73 -0
- data/lib/gzr/commands/group/member_groups.rb +74 -0
- data/lib/gzr/commands/group/member_users.rb +74 -0
- data/lib/gzr/commands/look.rb +75 -0
- data/lib/gzr/commands/look/cat.rb +55 -0
- data/lib/gzr/commands/look/import.rb +62 -0
- data/lib/gzr/commands/look/rm.rb +47 -0
- data/lib/gzr/commands/model.rb +51 -0
- data/lib/gzr/commands/model/ls.rb +72 -0
- data/lib/gzr/commands/plan.rb +149 -0
- data/lib/gzr/commands/plan/cat.rb +52 -0
- data/lib/gzr/commands/plan/disable.rb +49 -0
- data/lib/gzr/commands/plan/enable.rb +49 -0
- data/lib/gzr/commands/plan/failures.rb +98 -0
- data/lib/gzr/commands/plan/import.rb +69 -0
- data/lib/gzr/commands/plan/ls.rb +102 -0
- data/lib/gzr/commands/plan/rm.rb +47 -0
- data/lib/gzr/commands/plan/run.rb +58 -0
- data/lib/gzr/commands/query.rb +49 -0
- data/lib/gzr/commands/query/runquery.rb +102 -0
- data/lib/gzr/commands/role.rb +163 -0
- data/lib/gzr/commands/role/cat.rb +52 -0
- data/lib/gzr/commands/role/group_add.rb +51 -0
- data/lib/gzr/commands/role/group_ls.rb +76 -0
- data/lib/gzr/commands/role/group_rm.rb +51 -0
- data/lib/gzr/commands/role/ls.rb +75 -0
- data/lib/gzr/commands/role/rm.rb +47 -0
- data/lib/gzr/commands/role/user_add.rb +51 -0
- data/lib/gzr/commands/role/user_ls.rb +76 -0
- data/lib/gzr/commands/role/user_rm.rb +51 -0
- data/lib/gzr/commands/space.rb +137 -0
- data/lib/gzr/commands/space/cat.rb +53 -0
- data/lib/gzr/commands/space/create.rb +50 -0
- data/lib/gzr/commands/space/export.rb +117 -0
- data/lib/gzr/commands/space/ls.rb +97 -0
- data/lib/gzr/commands/space/rm.rb +56 -0
- data/lib/gzr/commands/space/top.rb +62 -0
- data/lib/gzr/commands/space/tree.rb +79 -0
- data/lib/gzr/commands/subcommandbase.rb +41 -0
- data/lib/gzr/commands/user.rb +111 -0
- data/lib/gzr/commands/user/cat.rb +52 -0
- data/lib/gzr/commands/user/disable.rb +47 -0
- data/lib/gzr/commands/user/enable.rb +47 -0
- data/lib/gzr/commands/user/ls.rb +82 -0
- data/lib/gzr/commands/user/me.rb +66 -0
- data/lib/gzr/modules/connection.rb +52 -0
- data/lib/gzr/modules/dashboard.rb +215 -0
- data/lib/gzr/modules/filehelper.rb +81 -0
- data/lib/gzr/modules/group.rb +93 -0
- data/lib/gzr/modules/look.rb +162 -0
- data/lib/gzr/modules/model.rb +40 -0
- data/lib/gzr/modules/plan.rb +216 -0
- data/lib/gzr/modules/role.rb +128 -0
- data/lib/gzr/modules/session.rb +203 -0
- data/lib/gzr/modules/space.rb +160 -0
- data/lib/gzr/modules/user.rb +114 -0
- data/lib/gzr/templates/.gitkeep +1 -0
- data/lib/gzr/templates/connection/dialects/.gitkeep +1 -0
- data/lib/gzr/templates/connection/ls/.gitkeep +1 -0
- data/lib/gzr/templates/dashboard/cat/.gitkeep +1 -0
- data/lib/gzr/templates/dashboard/import/.gitkeep +1 -0
- data/lib/gzr/templates/dashboard/rm/.gitkeep +1 -0
- data/lib/gzr/templates/group/ls/.gitkeep +1 -0
- data/lib/gzr/templates/group/member_groups/.gitkeep +1 -0
- data/lib/gzr/templates/group/member_users/.gitkeep +1 -0
- data/lib/gzr/templates/look/cat/.gitkeep +1 -0
- data/lib/gzr/templates/look/import/.gitkeep +1 -0
- data/lib/gzr/templates/look/rm/.gitkeep +1 -0
- data/lib/gzr/templates/model/ls/.gitkeep +1 -0
- data/lib/gzr/templates/plan/cat/.gitkeep +1 -0
- data/lib/gzr/templates/plan/disable/.gitkeep +1 -0
- data/lib/gzr/templates/plan/enable/.gitkeep +1 -0
- data/lib/gzr/templates/plan/failures/.gitkeep +1 -0
- data/lib/gzr/templates/plan/import/.gitkeep +1 -0
- data/lib/gzr/templates/plan/ls/.gitkeep +1 -0
- data/lib/gzr/templates/plan/rm/.gitkeep +1 -0
- data/lib/gzr/templates/plan/run/.gitkeep +1 -0
- data/lib/gzr/templates/query/run/.gitkeep +1 -0
- data/lib/gzr/templates/role/cat/.gitkeep +1 -0
- data/lib/gzr/templates/role/group_add/.gitkeep +1 -0
- data/lib/gzr/templates/role/group_ls/.gitkeep +1 -0
- data/lib/gzr/templates/role/group_rm/.gitkeep +1 -0
- data/lib/gzr/templates/role/ls/.gitkeep +1 -0
- data/lib/gzr/templates/role/rm/.gitkeep +1 -0
- data/lib/gzr/templates/role/user_add/.gitkeep +1 -0
- data/lib/gzr/templates/role/user_ls/.gitkeep +1 -0
- data/lib/gzr/templates/role/user_rm/.gitkeep +1 -0
- data/lib/gzr/templates/space/cat/.gitkeep +1 -0
- data/lib/gzr/templates/space/create/.gitkeep +1 -0
- data/lib/gzr/templates/space/export/.gitkeep +1 -0
- data/lib/gzr/templates/space/ls/.gitkeep +1 -0
- data/lib/gzr/templates/space/rm/.gitkeep +1 -0
- data/lib/gzr/templates/space/top/.gitkeep +1 -0
- data/lib/gzr/templates/space/tree/.gitkeep +1 -0
- data/lib/gzr/templates/user/cat/.gitkeep +1 -0
- data/lib/gzr/templates/user/disable/.gitkeep +1 -0
- data/lib/gzr/templates/user/enable/.gitkeep +1 -0
- data/lib/gzr/templates/user/ls/.gitkeep +1 -0
- data/lib/gzr/templates/user/me/.gitkeep +1 -0
- data/lib/gzr/version.rb +24 -0
- metadata +325 -0
@@ -0,0 +1,40 @@
|
|
1
|
+
# The MIT License (MIT)
|
2
|
+
|
3
|
+
# Copyright (c) 2018 Mike DeAngelo Looker Data Sciences, Inc.
|
4
|
+
|
5
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy of
|
6
|
+
# this software and associated documentation files (the "Software"), to deal in
|
7
|
+
# the Software without restriction, including without limitation the rights to
|
8
|
+
# use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
9
|
+
# the Software, and to permit persons to whom the Software is furnished to do so,
|
10
|
+
# subject to the following conditions:
|
11
|
+
|
12
|
+
# The above copyright notice and this permission notice shall be included in all
|
13
|
+
# copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
17
|
+
# FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
18
|
+
# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
19
|
+
# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
20
|
+
# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
21
|
+
|
22
|
+
# frozen_string_literal: true
|
23
|
+
|
24
|
+
module Gzr
|
25
|
+
module Model
|
26
|
+
def query_all_lookml_models(fields=nil)
|
27
|
+
data = nil
|
28
|
+
begin
|
29
|
+
req = Hash.new
|
30
|
+
req[:fields] = fields if fields
|
31
|
+
data = @sdk.all_lookml_models(req)
|
32
|
+
rescue LookerSDK::Error => e
|
33
|
+
say_error "Error querying all_lookml_models(#{JSON.pretty_generate(req)})"
|
34
|
+
say_error e.message
|
35
|
+
raise
|
36
|
+
end
|
37
|
+
data
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,216 @@
|
|
1
|
+
# The MIT License (MIT)
|
2
|
+
|
3
|
+
# Copyright (c) 2018 Mike DeAngelo Looker Data Sciences, Inc.
|
4
|
+
|
5
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy of
|
6
|
+
# this software and associated documentation files (the "Software"), to deal in
|
7
|
+
# the Software without restriction, including without limitation the rights to
|
8
|
+
# use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
9
|
+
# the Software, and to permit persons to whom the Software is furnished to do so,
|
10
|
+
# subject to the following conditions:
|
11
|
+
|
12
|
+
# The above copyright notice and this permission notice shall be included in all
|
13
|
+
# copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
17
|
+
# FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
18
|
+
# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
19
|
+
# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
20
|
+
# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
21
|
+
|
22
|
+
# frozen_string_literal: true
|
23
|
+
|
24
|
+
module Gzr
|
25
|
+
module Plan
|
26
|
+
def query_all_scheduled_plans(user_id,fields=nil)
|
27
|
+
req = {}
|
28
|
+
req[:all_users] = true if user_id == "all"
|
29
|
+
req[:user_id] = user_id if user_id && !(user_id == "all")
|
30
|
+
req[:fields] = fields if fields
|
31
|
+
data = nil
|
32
|
+
id = nil
|
33
|
+
id = user_id unless user_id == "all"
|
34
|
+
begin
|
35
|
+
data = @sdk.all_scheduled_plans(req)
|
36
|
+
rescue LookerSDK::ClientError => e
|
37
|
+
say_error "Unable to get all_scheduled_plans(#{JSON.pretty_generate(req)})"
|
38
|
+
say_error e.message
|
39
|
+
raise
|
40
|
+
end
|
41
|
+
data
|
42
|
+
end
|
43
|
+
|
44
|
+
def query_scheduled_plans_for_look(look_id,user_id,fields=nil)
|
45
|
+
req = {}
|
46
|
+
req[:all_users] = true if user_id == "all"
|
47
|
+
req[:user_id] = user_id if user_id && !(user_id == "all")
|
48
|
+
req[:fields] = fields if fields
|
49
|
+
data = nil
|
50
|
+
begin
|
51
|
+
data = @sdk.scheduled_plans_for_look(look_id,req)
|
52
|
+
rescue LookerSDK::ClientError => e
|
53
|
+
say_error "Unable to get scheduled_plans_for_look(#{look_id},#{JSON.pretty_generate(req)})"
|
54
|
+
say_error e.message
|
55
|
+
raise
|
56
|
+
end
|
57
|
+
data
|
58
|
+
end
|
59
|
+
|
60
|
+
def query_scheduled_plans_for_dashboard(dashboard_id,user_id,fields=nil)
|
61
|
+
req = {}
|
62
|
+
req[:all_users] = true if user_id == "all"
|
63
|
+
req[:user_id] = user_id if user_id && !(user_id == "all")
|
64
|
+
req[:fields] = fields if fields
|
65
|
+
data = nil
|
66
|
+
begin
|
67
|
+
data = @sdk.scheduled_plans_for_dashboard(dashboard_id,req)
|
68
|
+
rescue LookerSDK::ClientError => e
|
69
|
+
say_error "Unable to get scheduled_plans_for_dashboard(#{dashboard_id},#{JSON.pretty_generate(req)})"
|
70
|
+
say_error e.message
|
71
|
+
raise
|
72
|
+
end
|
73
|
+
data
|
74
|
+
end
|
75
|
+
|
76
|
+
def query_scheduled_plan(plan_id,fields=nil)
|
77
|
+
req = {}
|
78
|
+
req[:fields] = fields if fields
|
79
|
+
begin
|
80
|
+
data = @sdk.scheduled_plan(plan_id,req)
|
81
|
+
rescue LookerSDK::ClientError => e
|
82
|
+
say_error "Unable to get scheduled_plan(#{plan_id},#{JSON.pretty_generate(req)})"
|
83
|
+
say_error e.message
|
84
|
+
raise
|
85
|
+
end
|
86
|
+
data
|
87
|
+
end
|
88
|
+
|
89
|
+
def delete_scheduled_plan(plan_id)
|
90
|
+
begin
|
91
|
+
data = @sdk.delete_scheduled_plan(plan_id)
|
92
|
+
rescue LookerSDK::ClientError => e
|
93
|
+
say_error "Unable to delete scheduled_plan(#{plan_id})"
|
94
|
+
say_error e.message
|
95
|
+
raise
|
96
|
+
end
|
97
|
+
data
|
98
|
+
end
|
99
|
+
|
100
|
+
def create_scheduled_plan(plan)
|
101
|
+
begin
|
102
|
+
data = @sdk.create_scheduled_plan(plan)
|
103
|
+
rescue LookerSDK::Error => e
|
104
|
+
say_error "Error creating scheduled_plan(#{JSON.pretty_generate(plan)})"
|
105
|
+
say_error e.message
|
106
|
+
raise
|
107
|
+
end
|
108
|
+
data
|
109
|
+
end
|
110
|
+
|
111
|
+
def update_scheduled_plan(plan_id,plan)
|
112
|
+
begin
|
113
|
+
data = @sdk.update_scheduled_plan(plan_id,plan)
|
114
|
+
rescue LookerSDK::Error => e
|
115
|
+
say_error "Error updating scheduled_plan(#{plan_id},#{JSON.pretty_generate(plan)})"
|
116
|
+
say_error e.message
|
117
|
+
raise
|
118
|
+
end
|
119
|
+
data
|
120
|
+
end
|
121
|
+
|
122
|
+
def run_scheduled_plan(plan)
|
123
|
+
begin
|
124
|
+
data = @sdk.scheduled_plan_run_once(plan)
|
125
|
+
rescue LookerSDK::Error => e
|
126
|
+
say_error "Error executing scheduled_plan_run_once(#{JSON.pretty_generate(plan)})"
|
127
|
+
say_error e.message
|
128
|
+
raise
|
129
|
+
end
|
130
|
+
data
|
131
|
+
end
|
132
|
+
|
133
|
+
def upsert_plans_for_look(look_id,user_id,source_plans)
|
134
|
+
existing_plans = query_scheduled_plans_for_look(look_id,"all")
|
135
|
+
upsert_plans_for_obj(user_id,source_plans,existing_plans) { |p| p[:look_id] = look_id }
|
136
|
+
end
|
137
|
+
|
138
|
+
def upsert_plans_for_dashboard(dashboard_id,user_id,source_plans)
|
139
|
+
existing_plans = query_scheduled_plans_for_dashboard(dashboard_id,"all")
|
140
|
+
upsert_plans_for_obj(user_id,source_plans,existing_plans) { |p| p[:dashboard_id] = dashboard_id }
|
141
|
+
end
|
142
|
+
|
143
|
+
def upsert_plan_for_look(look_id,user_id,source_plan)
|
144
|
+
existing_plans = query_scheduled_plans_for_look(look_id,"all")
|
145
|
+
upsert_plan_for_obj(user_id,source_plan,existing_plans) { |p| p[:look_id] = look_id }
|
146
|
+
end
|
147
|
+
|
148
|
+
def upsert_plan_for_dashboard(dashboard_id,user_id,source_plan)
|
149
|
+
existing_plans = query_scheduled_plans_for_dashboard(dashboard_id,"all")
|
150
|
+
upsert_plan_for_obj(user_id,source_plan,existing_plans) { |p| p[:dashboard_id] = dashboard_id }
|
151
|
+
end
|
152
|
+
|
153
|
+
def upsert_plans_for_obj(user_id,source_plans,existing_plans, &block)
|
154
|
+
plans = nil
|
155
|
+
source_plans.collect do |source_plan|
|
156
|
+
plans = upsert_plan_for_obj(user_id, source_plan, existing_plans, &block)
|
157
|
+
end
|
158
|
+
return nil unless plans.length > 0
|
159
|
+
plans.first
|
160
|
+
end
|
161
|
+
|
162
|
+
def upsert_plan_for_obj(user_id, source_plan, existing_plans)
|
163
|
+
matches = existing_plans.select { |p| p.name == source_plan[:name] && user_id == p.user_id }
|
164
|
+
if matches.length > 0 then
|
165
|
+
say_ok "Modifying existing plan #{matches.first.id} #{matches.first.name}"
|
166
|
+
plan = keys_to_keep('update_scheduled_plan').collect do |e|
|
167
|
+
[e,nil]
|
168
|
+
end.to_h
|
169
|
+
|
170
|
+
plan.merge!( source_plan.select do |k,v|
|
171
|
+
(keys_to_keep('update_scheduled_plan') - [:plan_id,:look_id,:dashboard_id,:user_id,:dashboard_filters,:lookml_dashboard_id,:scheduled_plan_destination]).include? k
|
172
|
+
end)
|
173
|
+
plan[:scheduled_plan_destination] = source_plan[:scheduled_plan_destination].collect do |p|
|
174
|
+
p.reject do |k,v|
|
175
|
+
[:id,:scheduled_plan_id,:looker_recipient,:can].include? k
|
176
|
+
end
|
177
|
+
end
|
178
|
+
plan[:user_id] = user_id
|
179
|
+
plan[:enabled] = true if @options[:enabled]
|
180
|
+
plan[:enabled] = false if @options[:disabled]
|
181
|
+
|
182
|
+
plan[:enabled] = false if plan[:enabled].nil?
|
183
|
+
plan[:require_results] = false if plan[:require_results].nil?
|
184
|
+
plan[:require_no_results] = false if plan[:require_no_results].nil?
|
185
|
+
plan[:require_change] = false if plan[:require_change].nil?
|
186
|
+
plan[:send_all_results] = false if plan[:send_all_results].nil?
|
187
|
+
plan[:run_once] = false if plan[:run_once].nil?
|
188
|
+
plan[:include_links] = false if plan[:include_links].nil?
|
189
|
+
yield plan
|
190
|
+
update_scheduled_plan(matches.first.id,plan)
|
191
|
+
else
|
192
|
+
plan = source_plan.select do |k,v|
|
193
|
+
(keys_to_keep('create_scheduled_plan') - [:plan_id,:dashboard_id,:user_id,:dashboard_filters,:lookml_dashboard_id,:scheduled_plan_destination]).include? k
|
194
|
+
end
|
195
|
+
plan[:scheduled_plan_destination] = source_plan[:scheduled_plan_destination].collect do |p|
|
196
|
+
p.reject do |k,v|
|
197
|
+
[:id,:scheduled_plan_id,:looker_recipient,:can].include? k
|
198
|
+
end
|
199
|
+
end
|
200
|
+
|
201
|
+
yield plan
|
202
|
+
plan[:enabled] = true if @options[:enabled]
|
203
|
+
plan[:enabled] = false if @options[:disabled]
|
204
|
+
|
205
|
+
plan[:enabled] = false if plan[:enabled].nil?
|
206
|
+
plan[:require_results] = false if plan[:require_results].nil?
|
207
|
+
plan[:require_no_results] = false if plan[:require_no_results].nil?
|
208
|
+
plan[:require_change] = false if plan[:require_change].nil?
|
209
|
+
plan[:send_all_results] = false if plan[:send_all_results].nil?
|
210
|
+
plan[:run_once] = false if plan[:run_once].nil?
|
211
|
+
plan[:include_links] = false if plan[:include_links].nil?
|
212
|
+
create_scheduled_plan(plan)
|
213
|
+
end
|
214
|
+
end
|
215
|
+
end
|
216
|
+
end
|
@@ -0,0 +1,128 @@
|
|
1
|
+
# The MIT License (MIT)
|
2
|
+
|
3
|
+
# Copyright (c) 2018 Mike DeAngelo Looker Data Sciences, Inc.
|
4
|
+
|
5
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy of
|
6
|
+
# this software and associated documentation files (the "Software"), to deal in
|
7
|
+
# the Software without restriction, including without limitation the rights to
|
8
|
+
# use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
9
|
+
# the Software, and to permit persons to whom the Software is furnished to do so,
|
10
|
+
# subject to the following conditions:
|
11
|
+
|
12
|
+
# The above copyright notice and this permission notice shall be included in all
|
13
|
+
# copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
17
|
+
# FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
18
|
+
# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
19
|
+
# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
20
|
+
# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
21
|
+
|
22
|
+
# frozen_string_literal: true
|
23
|
+
|
24
|
+
module Gzr
|
25
|
+
module Role
|
26
|
+
def query_all_roles(fields=nil)
|
27
|
+
req = Hash.new
|
28
|
+
req[:fields] = fields if fields
|
29
|
+
data = Array.new
|
30
|
+
begin
|
31
|
+
data = @sdk.all_roles(req)
|
32
|
+
rescue LookerSDK::NotFound => e
|
33
|
+
# do nothing
|
34
|
+
rescue LookerSDK::ClientError => e
|
35
|
+
say_error "Unable to get all_roles(#{JSON.pretty_generate(req)})"
|
36
|
+
say_error e.message
|
37
|
+
say_error e.errors if e.errors
|
38
|
+
raise
|
39
|
+
end
|
40
|
+
data
|
41
|
+
end
|
42
|
+
def query_role(role_id)
|
43
|
+
data = nil
|
44
|
+
begin
|
45
|
+
data = @sdk.role(role_id)
|
46
|
+
rescue LookerSDK::NotFound => e
|
47
|
+
# do nothing
|
48
|
+
rescue LookerSDK::ClientError => e
|
49
|
+
say_error "Unable to get role(#{role_id})"
|
50
|
+
say_error e.message
|
51
|
+
say_error e.errors if e.errors
|
52
|
+
raise
|
53
|
+
end
|
54
|
+
data
|
55
|
+
end
|
56
|
+
def delete_role(role_id)
|
57
|
+
data = nil
|
58
|
+
begin
|
59
|
+
data = @sdk.delete_role(role_id)
|
60
|
+
rescue LookerSDK::NotFound => e
|
61
|
+
# do nothing
|
62
|
+
rescue LookerSDK::ClientError => e
|
63
|
+
say_error "Unable to delete_role(#{role_id})"
|
64
|
+
say_error e.message
|
65
|
+
say_error e.errors if e.errors
|
66
|
+
raise
|
67
|
+
end
|
68
|
+
data
|
69
|
+
end
|
70
|
+
def query_role_groups(role_id,fields=nil)
|
71
|
+
req = Hash.new
|
72
|
+
req[:fields] = fields if fields
|
73
|
+
data = Array.new
|
74
|
+
begin
|
75
|
+
data = @sdk.role_groups(role_id, req)
|
76
|
+
rescue LookerSDK::NotFound => e
|
77
|
+
# do nothing
|
78
|
+
rescue LookerSDK::ClientError => e
|
79
|
+
say_error "Unable to get role_groups(#{role_id},#{JSON.pretty_generate(req)})"
|
80
|
+
say_error e.message
|
81
|
+
say_error e.errors if e.errors
|
82
|
+
raise
|
83
|
+
end
|
84
|
+
data
|
85
|
+
end
|
86
|
+
def query_role_users(role_id,fields=nil,direct_association_only=true)
|
87
|
+
req = Hash.new
|
88
|
+
req[:fields] = fields if fields
|
89
|
+
req[:direct_association_only] = direct_association_only
|
90
|
+
data = Array.new
|
91
|
+
begin
|
92
|
+
data = @sdk.role_users(role_id, req)
|
93
|
+
rescue LookerSDK::NotFound => e
|
94
|
+
# do nothing
|
95
|
+
rescue LookerSDK::ClientError => e
|
96
|
+
say_error "Unable to get role_users(#{role_id},#{JSON.pretty_generate(req)})"
|
97
|
+
say_error e.message
|
98
|
+
say_error e.errors if e.errors
|
99
|
+
raise
|
100
|
+
end
|
101
|
+
data
|
102
|
+
end
|
103
|
+
def set_role_groups(role_id,groups=[])
|
104
|
+
data = Array.new
|
105
|
+
begin
|
106
|
+
data = @sdk.set_role_groups(role_id, groups)
|
107
|
+
rescue LookerSDK::ClientError => e
|
108
|
+
say_error "Unable to call set_role_groups(#{role_id},#{JSON.pretty_generate(groups)})"
|
109
|
+
say_error e.message
|
110
|
+
say_error e.errors if e.errors
|
111
|
+
raise
|
112
|
+
end
|
113
|
+
data
|
114
|
+
end
|
115
|
+
def set_role_users(role_id,users=[])
|
116
|
+
data = Array.new
|
117
|
+
begin
|
118
|
+
data = @sdk.set_role_users(role_id, users)
|
119
|
+
rescue LookerSDK::ClientError => e
|
120
|
+
say_error "Unable to call set_role_users(#{role_id},#{JSON.pretty_generate(users)})"
|
121
|
+
say_error e.message
|
122
|
+
say_error e.errors if e.errors
|
123
|
+
raise
|
124
|
+
end
|
125
|
+
data
|
126
|
+
end
|
127
|
+
end
|
128
|
+
end
|
@@ -0,0 +1,203 @@
|
|
1
|
+
# The MIT License (MIT)
|
2
|
+
|
3
|
+
# Copyright (c) 2018 Mike DeAngelo Looker Data Sciences, Inc.
|
4
|
+
|
5
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy of
|
6
|
+
# this software and associated documentation files (the "Software"), to deal in
|
7
|
+
# the Software without restriction, including without limitation the rights to
|
8
|
+
# use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
9
|
+
# the Software, and to permit persons to whom the Software is furnished to do so,
|
10
|
+
# subject to the following conditions:
|
11
|
+
|
12
|
+
# The above copyright notice and this permission notice shall be included in all
|
13
|
+
# copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
17
|
+
# FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
18
|
+
# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
19
|
+
# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
20
|
+
# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
21
|
+
|
22
|
+
# frozen_string_literal: true
|
23
|
+
|
24
|
+
require 'pastel'
|
25
|
+
require 'tty-reader'
|
26
|
+
|
27
|
+
require_relative '../../gzr'
|
28
|
+
|
29
|
+
module Gzr
|
30
|
+
module Session
|
31
|
+
|
32
|
+
def pastel
|
33
|
+
@pastel ||= Pastel.new
|
34
|
+
end
|
35
|
+
|
36
|
+
def say_ok(data)
|
37
|
+
puts pastel.green data
|
38
|
+
end
|
39
|
+
|
40
|
+
def say_warning(data)
|
41
|
+
puts pastel.yellow data
|
42
|
+
end
|
43
|
+
|
44
|
+
def say_error(data)
|
45
|
+
puts pastel.red data
|
46
|
+
end
|
47
|
+
|
48
|
+
def v3_1_available?
|
49
|
+
@v3_1_available ||= false
|
50
|
+
end
|
51
|
+
|
52
|
+
def build_connection_hash(api_version)
|
53
|
+
conn_hash = Hash.new
|
54
|
+
conn_hash[:api_endpoint] = "http#{@options[:ssl] ? "s" : ""}://#{@options[:host]}:#{@options[:port]}/api/#{api_version}"
|
55
|
+
if @options[:http_proxy]
|
56
|
+
conn_hash[:connection_options] ||= {}
|
57
|
+
conn_hash[:connection_options][:proxy] = {
|
58
|
+
:uri => @options[:http_proxy]
|
59
|
+
}
|
60
|
+
end
|
61
|
+
if @options[:ssl]
|
62
|
+
conn_hash[:connection_options] ||= {}
|
63
|
+
if @options[:verify_ssl] then
|
64
|
+
conn_hash[:connection_options][:ssl] = {
|
65
|
+
:verify => true,
|
66
|
+
:verify_mode => (OpenSSL::SSL::VERIFY_PEER | OpenSSL::SSL::VERIFY_FAIL_IF_NO_PEER_CERT)
|
67
|
+
}
|
68
|
+
else
|
69
|
+
conn_hash[:connection_options][:ssl] = {
|
70
|
+
:verify => false
|
71
|
+
}
|
72
|
+
end
|
73
|
+
end
|
74
|
+
if @options[:timeout]
|
75
|
+
conn_hash[:connection_options] ||= {}
|
76
|
+
conn_hash[:connection_options][:request] = {
|
77
|
+
:timeout => @options[:timeout]
|
78
|
+
}
|
79
|
+
end
|
80
|
+
conn_hash[:user_agent] = "Gazer #{Gzr::VERSION}"
|
81
|
+
if @options[:client_id] then
|
82
|
+
conn_hash[:client_id] = @options[:client_id]
|
83
|
+
if @options[:client_secret] then
|
84
|
+
conn_hash[:client_secret] = @options[:client_secret]
|
85
|
+
else
|
86
|
+
reader = TTY::Reader.new
|
87
|
+
@secret ||= reader.read_line("Enter your client_secret:", echo: false)
|
88
|
+
conn_hash[:client_secret] = @secret
|
89
|
+
end
|
90
|
+
else
|
91
|
+
conn_hash[:netrc] = true
|
92
|
+
conn_hash[:netrc_file] = "~/.netrc"
|
93
|
+
end
|
94
|
+
conn_hash
|
95
|
+
end
|
96
|
+
|
97
|
+
def login(api_version)
|
98
|
+
@secret = nil
|
99
|
+
begin
|
100
|
+
conn_hash = build_connection_hash("3.0")
|
101
|
+
sdk = LookerSDK::Client.new(conn_hash)
|
102
|
+
begin
|
103
|
+
sdk.get "/"
|
104
|
+
rescue Faraday::SSLError => e
|
105
|
+
raise Gzr::CLI::Error, "SSL Certificate could not be verified\nDo you need the --no-verify-ssl option or the --no-ssl option?"
|
106
|
+
rescue Faraday::ConnectionFailed => cf
|
107
|
+
raise Gzr::CLI::Error, "Connection Failed.\nDid you specify the --no-ssl option for an ssl secured server?"
|
108
|
+
rescue LookerSDK::NotFound => nf
|
109
|
+
#ignore this
|
110
|
+
end
|
111
|
+
raise Gzr::CLI::Error, "Invalid credentials" unless sdk.authenticated?
|
112
|
+
sdk.versions.supported_versions.each do |v|
|
113
|
+
@v3_1_available = true if v.version == "3.1"
|
114
|
+
end
|
115
|
+
begin
|
116
|
+
sdk.logout
|
117
|
+
rescue LookerSDK::Error => e
|
118
|
+
# eat this error if it occurs
|
119
|
+
end
|
120
|
+
end unless @options[:api_version]
|
121
|
+
|
122
|
+
say_warning "API 3.1 available? #{v3_1_available?}" if @options[:debug]
|
123
|
+
|
124
|
+
raise Gzr::CLI::Error, "Operation requires API v3.1, but user specified a different version" if (api_version == "3.1") && @options[:api_version] && !("3.1" == @options[:api_version])
|
125
|
+
raise Gzr::CLI::Error, "Operation requires API v3.1, which is not available from this host" if (api_version == "3.1") && !v3_1_available?
|
126
|
+
|
127
|
+
conn_hash = build_connection_hash(@options[:api_version] || api_version)
|
128
|
+
@secret = nil
|
129
|
+
|
130
|
+
say_ok("connecting to #{conn_hash.each { |k,v| "#{k}=>#{(k == :client_secret) ? '*********' : v}" }}") if @options[:debug]
|
131
|
+
|
132
|
+
begin
|
133
|
+
@sdk = LookerSDK::Client.new(conn_hash) unless @sdk
|
134
|
+
say_ok "check for connectivity: #{@sdk.alive?}" if @options[:debug]
|
135
|
+
say_ok "verify authentication: #{@sdk.authenticated?}" if @options[:debug]
|
136
|
+
rescue LookerSDK::Unauthorized => e
|
137
|
+
say_error "Unauthorized - credentials are not valid"
|
138
|
+
raise
|
139
|
+
rescue LookerSDK::Error => e
|
140
|
+
say_error "Unable to connect"
|
141
|
+
say_error e.message
|
142
|
+
say_error e.errors if e.respond_to?(:errors) && e.errors
|
143
|
+
raise
|
144
|
+
end
|
145
|
+
raise Gzr::CLI::Error, "Invalid credentials" unless @sdk.authenticated?
|
146
|
+
|
147
|
+
|
148
|
+
if @options[:su] then
|
149
|
+
say_ok "su to user #{@options[:su]}" if @options[:debug]
|
150
|
+
@access_token_stack.push(@sdk.access_token)
|
151
|
+
begin
|
152
|
+
@sdk.access_token = @sdk.login_user(@options[:su]).access_token
|
153
|
+
say_warning "verify authentication: #{@sdk.authenticated?}" if @options[:debug]
|
154
|
+
rescue LookerSDK::Error => e
|
155
|
+
say_error "Unable to su to user #{@options[:su]}"
|
156
|
+
say_error e.message
|
157
|
+
say_error e.errors if e.respond_to?(:errors) && e.errors
|
158
|
+
raise
|
159
|
+
end
|
160
|
+
end
|
161
|
+
@sdk
|
162
|
+
end
|
163
|
+
|
164
|
+
def logout_all
|
165
|
+
pastel = Pastel.new(enabled: true)
|
166
|
+
say_ok "logout" if @options[:debug]
|
167
|
+
begin
|
168
|
+
@sdk.logout
|
169
|
+
rescue LookerSDK::Error => e
|
170
|
+
say_error "Unable to logout"
|
171
|
+
say_error e.message
|
172
|
+
say_error e.errors if e.respond_to?(:errors) && e.errors
|
173
|
+
end if @sdk
|
174
|
+
loop do
|
175
|
+
token = @access_token_stack.pop
|
176
|
+
break unless token
|
177
|
+
say_ok "logout the parent session" if @options[:debug]
|
178
|
+
@sdk.access_token = token
|
179
|
+
begin
|
180
|
+
@sdk.logout
|
181
|
+
rescue LookerSDK::Error => e
|
182
|
+
say_error "Unable to logout"
|
183
|
+
say_error e.message
|
184
|
+
say_error e.errors if e.respond_to?(:errors) && e.errors
|
185
|
+
end
|
186
|
+
end
|
187
|
+
end
|
188
|
+
|
189
|
+
def with_session(api_version="3.0")
|
190
|
+
return nil unless block_given?
|
191
|
+
begin
|
192
|
+
login(api_version) unless @sdk
|
193
|
+
yield
|
194
|
+
rescue LookerSDK::Error => e
|
195
|
+
say_error e.errors if e.respond_to?(:errors) && e.errors
|
196
|
+
e.backtrace.each { |b| say_error b } if @options[:debug]
|
197
|
+
raise Gzr::CLI::Error, e.message
|
198
|
+
ensure
|
199
|
+
logout_all
|
200
|
+
end
|
201
|
+
end
|
202
|
+
end
|
203
|
+
end
|