gazer 0.2.9

Sign up to get free protection for your applications and to get access to all the features.
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