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.
Files changed (128) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +15 -0
  3. data/.rspec +3 -0
  4. data/.ruby-version +1 -0
  5. data/.travis.yml +5 -0
  6. data/CODE_OF_CONDUCT.md +74 -0
  7. data/Gemfile +35 -0
  8. data/Gemfile.lock +150 -0
  9. data/LICENSE.txt +20 -0
  10. data/README.md +527 -0
  11. data/Rakefile +27 -0
  12. data/bin/console +35 -0
  13. data/bin/setup +30 -0
  14. data/exe/gzr +40 -0
  15. data/gzr.gemspec +67 -0
  16. data/lib/gzr.rb +25 -0
  17. data/lib/gzr/cli.rb +86 -0
  18. data/lib/gzr/command.rb +251 -0
  19. data/lib/gzr/commands/.gitkeep +1 -0
  20. data/lib/gzr/commands/connection.rb +69 -0
  21. data/lib/gzr/commands/connection/dialects.rb +72 -0
  22. data/lib/gzr/commands/connection/ls.rb +72 -0
  23. data/lib/gzr/commands/dashboard.rb +75 -0
  24. data/lib/gzr/commands/dashboard/cat.rb +67 -0
  25. data/lib/gzr/commands/dashboard/import.rb +256 -0
  26. data/lib/gzr/commands/dashboard/rm.rb +47 -0
  27. data/lib/gzr/commands/group.rb +87 -0
  28. data/lib/gzr/commands/group/ls.rb +73 -0
  29. data/lib/gzr/commands/group/member_groups.rb +74 -0
  30. data/lib/gzr/commands/group/member_users.rb +74 -0
  31. data/lib/gzr/commands/look.rb +75 -0
  32. data/lib/gzr/commands/look/cat.rb +55 -0
  33. data/lib/gzr/commands/look/import.rb +62 -0
  34. data/lib/gzr/commands/look/rm.rb +47 -0
  35. data/lib/gzr/commands/model.rb +51 -0
  36. data/lib/gzr/commands/model/ls.rb +72 -0
  37. data/lib/gzr/commands/plan.rb +149 -0
  38. data/lib/gzr/commands/plan/cat.rb +52 -0
  39. data/lib/gzr/commands/plan/disable.rb +49 -0
  40. data/lib/gzr/commands/plan/enable.rb +49 -0
  41. data/lib/gzr/commands/plan/failures.rb +98 -0
  42. data/lib/gzr/commands/plan/import.rb +69 -0
  43. data/lib/gzr/commands/plan/ls.rb +102 -0
  44. data/lib/gzr/commands/plan/rm.rb +47 -0
  45. data/lib/gzr/commands/plan/run.rb +58 -0
  46. data/lib/gzr/commands/query.rb +49 -0
  47. data/lib/gzr/commands/query/runquery.rb +102 -0
  48. data/lib/gzr/commands/role.rb +163 -0
  49. data/lib/gzr/commands/role/cat.rb +52 -0
  50. data/lib/gzr/commands/role/group_add.rb +51 -0
  51. data/lib/gzr/commands/role/group_ls.rb +76 -0
  52. data/lib/gzr/commands/role/group_rm.rb +51 -0
  53. data/lib/gzr/commands/role/ls.rb +75 -0
  54. data/lib/gzr/commands/role/rm.rb +47 -0
  55. data/lib/gzr/commands/role/user_add.rb +51 -0
  56. data/lib/gzr/commands/role/user_ls.rb +76 -0
  57. data/lib/gzr/commands/role/user_rm.rb +51 -0
  58. data/lib/gzr/commands/space.rb +137 -0
  59. data/lib/gzr/commands/space/cat.rb +53 -0
  60. data/lib/gzr/commands/space/create.rb +50 -0
  61. data/lib/gzr/commands/space/export.rb +117 -0
  62. data/lib/gzr/commands/space/ls.rb +97 -0
  63. data/lib/gzr/commands/space/rm.rb +56 -0
  64. data/lib/gzr/commands/space/top.rb +62 -0
  65. data/lib/gzr/commands/space/tree.rb +79 -0
  66. data/lib/gzr/commands/subcommandbase.rb +41 -0
  67. data/lib/gzr/commands/user.rb +111 -0
  68. data/lib/gzr/commands/user/cat.rb +52 -0
  69. data/lib/gzr/commands/user/disable.rb +47 -0
  70. data/lib/gzr/commands/user/enable.rb +47 -0
  71. data/lib/gzr/commands/user/ls.rb +82 -0
  72. data/lib/gzr/commands/user/me.rb +66 -0
  73. data/lib/gzr/modules/connection.rb +52 -0
  74. data/lib/gzr/modules/dashboard.rb +215 -0
  75. data/lib/gzr/modules/filehelper.rb +81 -0
  76. data/lib/gzr/modules/group.rb +93 -0
  77. data/lib/gzr/modules/look.rb +162 -0
  78. data/lib/gzr/modules/model.rb +40 -0
  79. data/lib/gzr/modules/plan.rb +216 -0
  80. data/lib/gzr/modules/role.rb +128 -0
  81. data/lib/gzr/modules/session.rb +203 -0
  82. data/lib/gzr/modules/space.rb +160 -0
  83. data/lib/gzr/modules/user.rb +114 -0
  84. data/lib/gzr/templates/.gitkeep +1 -0
  85. data/lib/gzr/templates/connection/dialects/.gitkeep +1 -0
  86. data/lib/gzr/templates/connection/ls/.gitkeep +1 -0
  87. data/lib/gzr/templates/dashboard/cat/.gitkeep +1 -0
  88. data/lib/gzr/templates/dashboard/import/.gitkeep +1 -0
  89. data/lib/gzr/templates/dashboard/rm/.gitkeep +1 -0
  90. data/lib/gzr/templates/group/ls/.gitkeep +1 -0
  91. data/lib/gzr/templates/group/member_groups/.gitkeep +1 -0
  92. data/lib/gzr/templates/group/member_users/.gitkeep +1 -0
  93. data/lib/gzr/templates/look/cat/.gitkeep +1 -0
  94. data/lib/gzr/templates/look/import/.gitkeep +1 -0
  95. data/lib/gzr/templates/look/rm/.gitkeep +1 -0
  96. data/lib/gzr/templates/model/ls/.gitkeep +1 -0
  97. data/lib/gzr/templates/plan/cat/.gitkeep +1 -0
  98. data/lib/gzr/templates/plan/disable/.gitkeep +1 -0
  99. data/lib/gzr/templates/plan/enable/.gitkeep +1 -0
  100. data/lib/gzr/templates/plan/failures/.gitkeep +1 -0
  101. data/lib/gzr/templates/plan/import/.gitkeep +1 -0
  102. data/lib/gzr/templates/plan/ls/.gitkeep +1 -0
  103. data/lib/gzr/templates/plan/rm/.gitkeep +1 -0
  104. data/lib/gzr/templates/plan/run/.gitkeep +1 -0
  105. data/lib/gzr/templates/query/run/.gitkeep +1 -0
  106. data/lib/gzr/templates/role/cat/.gitkeep +1 -0
  107. data/lib/gzr/templates/role/group_add/.gitkeep +1 -0
  108. data/lib/gzr/templates/role/group_ls/.gitkeep +1 -0
  109. data/lib/gzr/templates/role/group_rm/.gitkeep +1 -0
  110. data/lib/gzr/templates/role/ls/.gitkeep +1 -0
  111. data/lib/gzr/templates/role/rm/.gitkeep +1 -0
  112. data/lib/gzr/templates/role/user_add/.gitkeep +1 -0
  113. data/lib/gzr/templates/role/user_ls/.gitkeep +1 -0
  114. data/lib/gzr/templates/role/user_rm/.gitkeep +1 -0
  115. data/lib/gzr/templates/space/cat/.gitkeep +1 -0
  116. data/lib/gzr/templates/space/create/.gitkeep +1 -0
  117. data/lib/gzr/templates/space/export/.gitkeep +1 -0
  118. data/lib/gzr/templates/space/ls/.gitkeep +1 -0
  119. data/lib/gzr/templates/space/rm/.gitkeep +1 -0
  120. data/lib/gzr/templates/space/top/.gitkeep +1 -0
  121. data/lib/gzr/templates/space/tree/.gitkeep +1 -0
  122. data/lib/gzr/templates/user/cat/.gitkeep +1 -0
  123. data/lib/gzr/templates/user/disable/.gitkeep +1 -0
  124. data/lib/gzr/templates/user/enable/.gitkeep +1 -0
  125. data/lib/gzr/templates/user/ls/.gitkeep +1 -0
  126. data/lib/gzr/templates/user/me/.gitkeep +1 -0
  127. data/lib/gzr/version.rb +24 -0
  128. 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