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,27 @@
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
+ require "bundler/gem_tasks"
23
+ require "rspec/core/rake_task"
24
+
25
+ RSpec::Core::RakeTask.new(:spec)
26
+
27
+ task :default => :spec
@@ -0,0 +1,35 @@
1
+ #!/usr/bin/env bash
2
+
3
+ # The MIT License (MIT)
4
+
5
+ # Copyright (c) 2018 Mike DeAngelo Looker Data Sciences, Inc.
6
+
7
+ # Permission is hereby granted, free of charge, to any person obtaining a copy of
8
+ # this software and associated documentation files (the "Software"), to deal in
9
+ # the Software without restriction, including without limitation the rights to
10
+ # use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
11
+ # the Software, and to permit persons to whom the Software is furnished to do so,
12
+ # subject to the following conditions:
13
+
14
+ # The above copyright notice and this permission notice shall be included in all
15
+ # copies or substantial portions of the Software.
16
+
17
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
19
+ # FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
20
+ # COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
21
+ # IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
22
+ # CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23
+
24
+ require "bundler/setup"
25
+ require "gzr"
26
+
27
+ # You can add fixtures and/or initialization code here to make experimenting
28
+ # with your gem easier. You can also use a different console, if you like.
29
+
30
+ # (If you use this, don't forget to add pry to your Gemfile!)
31
+ # require "pry"
32
+ # Pry.start
33
+
34
+ require "irb"
35
+ IRB.start(__FILE__)
@@ -0,0 +1,30 @@
1
+ #!/usr/bin/env bash
2
+
3
+ # The MIT License (MIT)
4
+
5
+ # Copyright (c) 2018 Mike DeAngelo Looker Data Sciences, Inc.
6
+
7
+ # Permission is hereby granted, free of charge, to any person obtaining a copy of
8
+ # this software and associated documentation files (the "Software"), to deal in
9
+ # the Software without restriction, including without limitation the rights to
10
+ # use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
11
+ # the Software, and to permit persons to whom the Software is furnished to do so,
12
+ # subject to the following conditions:
13
+
14
+ # The above copyright notice and this permission notice shall be included in all
15
+ # copies or substantial portions of the Software.
16
+
17
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
19
+ # FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
20
+ # COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
21
+ # IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
22
+ # CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23
+
24
+ set -euo pipefail
25
+ IFS=$'\n\t'
26
+ set -vx
27
+
28
+ bundle install
29
+
30
+ # Do any other automated setup that you need to do here
data/exe/gzr ADDED
@@ -0,0 +1,40 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ # The MIT License (MIT)
4
+
5
+ # Copyright (c) 2018 Mike DeAngelo Looker Data Sciences, Inc.
6
+
7
+ # Permission is hereby granted, free of charge, to any person obtaining a copy of
8
+ # this software and associated documentation files (the "Software"), to deal in
9
+ # the Software without restriction, including without limitation the rights to
10
+ # use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
11
+ # the Software, and to permit persons to whom the Software is furnished to do so,
12
+ # subject to the following conditions:
13
+
14
+ # The above copyright notice and this permission notice shall be included in all
15
+ # copies or substantial portions of the Software.
16
+
17
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
19
+ # FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
20
+ # COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
21
+ # IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
22
+ # CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23
+
24
+ # frozen_string_literal: true
25
+
26
+ lib_path = File.expand_path('../lib', __dir__)
27
+ $:.unshift(lib_path) if !$:.include?(lib_path)
28
+ require 'gzr/cli'
29
+
30
+ Signal.trap('INT') do
31
+ warn("\n#{caller.join("\n")}: interrupted")
32
+ exit(1)
33
+ end
34
+
35
+ begin
36
+ Gzr::CLI.start
37
+ rescue Gzr::CLI::Error => err
38
+ puts "ERROR: #{err.message}"
39
+ exit 1
40
+ end
@@ -0,0 +1,67 @@
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
+ lib = File.expand_path("../lib", __FILE__)
23
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
24
+ require "gzr/version"
25
+
26
+ Gem::Specification.new do |spec|
27
+ spec.name = "gazer"
28
+ spec.license = "MIT"
29
+ spec.version = Gzr::VERSION
30
+ spec.authors = ["Mike DeAngelo"]
31
+ spec.email = ["deangelo@looker.com"]
32
+
33
+ spec.summary = %q{Command line tool to manage the content of a Looker instance.}
34
+ spec.description = %q{Command line tool to manage the content of a Looker instance.}
35
+ spec.homepage = "https://github.com/deangelo-llooker/gzr"
36
+
37
+ spec.required_ruby_version = '>= 2.3.0'
38
+
39
+ # Prevent pushing this gem to RubyGems.org. To allow pushes either set the 'allowed_push_host'
40
+ # to allow pushing to a single host or delete this section to allow pushing to any host.
41
+ if spec.respond_to?(:metadata)
42
+ #spec.metadata["allowed_push_host"] = "TODO: Set to 'http://mygemserver.com'"
43
+ else
44
+ raise "RubyGems 2.0 or newer is required to protect against " \
45
+ "public gem pushes."
46
+ end
47
+
48
+ spec.files = `git ls-files -z`.split("\x0").reject do |f|
49
+ f.match(%r{^(test|spec|features)/})
50
+ end
51
+ spec.bindir = "exe"
52
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
53
+ spec.require_paths = ["lib"]
54
+
55
+ spec.add_dependency "tty-reader", "~> 0.3.0"
56
+ spec.add_dependency "tty-table", "~> 0.10.0"
57
+ spec.add_dependency "tty-tree", "~> 0.1.0"
58
+ spec.add_dependency "pastel", "~> 0.7.2"
59
+ spec.add_dependency "thor", "~> 0.20.0"
60
+ spec.add_dependency 'netrc', "~> 0.11.0"
61
+ spec.add_dependency 'looker-sdk', "~> 0.0.6"
62
+
63
+ spec.add_development_dependency "bundler", "~> 1.16"
64
+ spec.add_development_dependency "rake", "~> 10.0"
65
+ spec.add_development_dependency "rspec", "~> 3.0"
66
+ spec.add_development_dependency "tty", "~> 0.8"
67
+ end
@@ -0,0 +1,25 @@
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
+ require "gzr/version"
23
+
24
+ module Gzr
25
+ end
@@ -0,0 +1,86 @@
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 'thor'
25
+
26
+ module Gzr
27
+ # Handle the application command line parsing
28
+ # and the dispatch to various command objects
29
+ #
30
+ # @api public
31
+ class CLI < Thor
32
+ class_option :debug, type: :boolean, default: false, desc: 'Run in debug mode'
33
+ class_option :host, type: :string, default: 'localhost', desc: 'Looker Host'
34
+ class_option :port, type: :string, default: '19999', desc: 'Looker API Port'
35
+ class_option :client_id, type: :string, desc: 'API3 Client Id'
36
+ class_option :client_secret, type: :string, desc: 'API3 Client Secret'
37
+ class_option :api_version, type: :string, desc: 'Looker API Version'
38
+ class_option :ssl, type: :boolean, default: true, desc: 'Use ssl to communicate with host'
39
+ class_option :verify_ssl, type: :boolean, default: true, desc: 'Verify the SSL certificate of the host'
40
+ class_option :timeout, type: :numeric, default: 60, desc: 'Seconds to wait for a response from the server'
41
+ class_option :http_proxy, type: :string, desc: 'HTTP Proxy for connecting to Looker host'
42
+ class_option :force, type: :boolean, default: false, desc: 'Overwrite objects on server'
43
+ class_option :su, type: :string, desc: 'After connecting, change to user_id given'
44
+
45
+
46
+ # Error raised by this runner
47
+ Error = Class.new(StandardError)
48
+
49
+ desc 'version', 'gzr version'
50
+ def version
51
+ require_relative 'version'
52
+ puts "v#{Gzr::VERSION}"
53
+ end
54
+ map %w(--version -v) => :version
55
+
56
+ require_relative 'commands/query'
57
+ register Gzr::Commands::Query, 'query', 'query [SUBCOMMAND]', 'Commands to retrieve and run queries'
58
+
59
+ require_relative 'commands/role'
60
+ register Gzr::Commands::Role, 'role', 'role [SUBCOMMAND]', 'Commands pertaining to roles'
61
+
62
+ require_relative 'commands/plan'
63
+ register Gzr::Commands::Plan, 'plan', 'plan [SUBCOMMAND]', 'Commands pertaining to plans'
64
+
65
+ require_relative 'commands/group'
66
+ register Gzr::Commands::Group, 'group', 'group [SUBCOMMAND]', 'Commands pertaining to groups'
67
+
68
+ require_relative 'commands/model'
69
+ register Gzr::Commands::Model, 'model', 'model [SUBCOMMAND]', 'Commands pertaining to LookML Models'
70
+
71
+ require_relative 'commands/connection'
72
+ register Gzr::Commands::Connection, 'connection', 'connection [SUBCOMMAND]', 'Commands pertaining to database connections and dialects'
73
+
74
+ require_relative 'commands/user'
75
+ register Gzr::Commands::User, 'user', 'user [SUBCOMMAND]', 'Commands pertaining to users'
76
+
77
+ require_relative 'commands/dashboard'
78
+ register Gzr::Commands::Dashboard, 'dashboard', 'dashboard [SUBCOMMAND]', 'Commands pertaining to dashboards'
79
+
80
+ require_relative 'commands/look'
81
+ register Gzr::Commands::Look, 'look', 'look [SUBCOMMAND]', 'Commands pertaining to looks'
82
+
83
+ require_relative 'commands/space'
84
+ register Gzr::Commands::Space, 'space', 'space [SUBCOMMAND]', 'Commands pertaining to spaces'
85
+ end
86
+ end
@@ -0,0 +1,251 @@
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 'forwardable'
25
+ require 'tty-reader'
26
+ require 'netrc'
27
+ require 'looker-sdk'
28
+
29
+ require_relative 'modules/session'
30
+
31
+ module Gzr
32
+ class Command
33
+ extend Forwardable
34
+ include Gzr::Session
35
+
36
+ def initialize
37
+ @sdk = nil
38
+ @access_token_stack = Array.new
39
+ @options = Hash.new
40
+ end
41
+
42
+ def_delegators :command, :run
43
+
44
+ # Execute this command
45
+ #
46
+ # @api public
47
+ def execute(*)
48
+ raise(
49
+ NotImplementedError,
50
+ "#{self.class}##{__method__} must be implemented"
51
+ )
52
+ end
53
+
54
+ def query(query_id)
55
+ data = nil
56
+ begin
57
+ data = @sdk.query(query_id)
58
+ rescue LookerSDK::Error => e
59
+ say_error "Error querying query(#{query_id})"
60
+ say_error e.message
61
+ raise
62
+ end
63
+ data
64
+ end
65
+
66
+ def create_query(query)
67
+ begin
68
+ data = @sdk.create_query(query)
69
+ rescue LookerSDK::Error => e
70
+ say_error "Error creating query(#{JSON.pretty_generate(query)})"
71
+ say_error e.message
72
+ raise
73
+ end
74
+ data
75
+ end
76
+
77
+ def merge_query(merge_result_id)
78
+ data = nil
79
+ begin
80
+ data = @sdk.merge_query(merge_result_id)
81
+ rescue NoMethodError => nme
82
+ say_error "The api endpoint merge_query(#{merge_result_id}) is not implemented on this Looker instance"
83
+ rescue LookerSDK::Error => e
84
+ say_error "Error querying merge_query(#{merge_result_id})"
85
+ say_error e.message
86
+ raise
87
+ end
88
+ data
89
+ end
90
+
91
+ def create_merge_query(merge_query)
92
+ begin
93
+ data = @sdk.create_merge_query(merge_query)
94
+ rescue NoMethodError => nme
95
+ say_error "The api endpoint create_merge_query() is not implemented on this Looker instance"
96
+ raise
97
+ rescue LookerSDK::Error => e
98
+ say_error "Error creating merge_query(#{JSON.pretty_generate(merge_query)})"
99
+ say_error e.message
100
+ raise
101
+ end
102
+ data
103
+ end
104
+
105
+ def run_inline_query(query)
106
+ begin
107
+ data = @sdk.run_inline_query("json",query)
108
+ rescue LookerSDK::Error => e
109
+ say_error "Error running inline_query(#{JSON.pretty_generate(query)})"
110
+ say_error e.message
111
+ raise
112
+ end
113
+ data
114
+ end
115
+
116
+
117
+ ##
118
+ # This method accepts the name of an sdk operation, then finds the parameter for that
119
+ # operation in the data structures from the swagger.json file. The parameter is a
120
+ # json object. Some of the attributes of the json object are read-only, and some
121
+ # are read-write. A few are write-only. The list of read-write and write-only attribute
122
+ # names are returned as an array. That array can be used to take the json document that
123
+ # describes an object and strip out the read-only values, creating a document that can
124
+ # be used to create or update an object.
125
+ #
126
+ # The pattern typically looks like this...
127
+ #
128
+ # new_obj_hash = existing_obj_hash.select do |k,v|
129
+ # keys_to_keep('create_new_obj').include? k
130
+ # end
131
+
132
+ def keys_to_keep(operation)
133
+ o = @sdk.operations[operation]
134
+ begin
135
+ say_error "Operation #{operation} not found"
136
+ return []
137
+ end unless o
138
+
139
+ parameters = o[:info][:parameters].select { |p| p[:in] == "body" && p[:schema] }
140
+
141
+ say_warning "Expecting exactly one body parameter with a schema for operation #{operation}" unless parameters.length == 1
142
+ schema_ref = parameters[0][:schema][:$ref].split(/\//)
143
+ return @sdk.swagger[schema_ref[1].to_sym][schema_ref[2].to_sym][:properties].reject { |k,v| v[:readOnly] }.keys
144
+ end
145
+
146
+ ##
147
+ # The tty-table gem is normally used to output tabular data. This method accepts a Table
148
+ # object as used by the tty-table gem, and generates CSV output. It returns a string
149
+ # with crlf encoding
150
+
151
+ def render_csv(t)
152
+ io = StringIO.new
153
+ io.puts (
154
+ t.header.collect do |v|
155
+ v ? "\"#{v.to_s.gsub(/"/, '""')}\"" : ""
156
+ end.join(',')
157
+ ) unless @options[:plain]
158
+ t.each do |row|
159
+ next if row === t.header
160
+ io.puts (
161
+ row.collect do |v|
162
+ v ? "\"#{v.to_s.gsub(/"/, '""')}\"" : ""
163
+ end.join(',')
164
+ )
165
+ end
166
+ io.rewind
167
+ io.gets(nil).encode(crlf_newline: true)
168
+ end
169
+
170
+ ##
171
+ # This method accepts a string containing a list of fields. The fields can be nested
172
+ # in a format like...
173
+ #
174
+ # 'a,b,c(d,e(f,g)),h'
175
+ #
176
+ # representing a structure like
177
+ #
178
+ # {
179
+ # a: "val",
180
+ # b: "val",
181
+ # c: {
182
+ # d: "val",
183
+ # e: {
184
+ # f: "val",
185
+ # g: "val"
186
+ # }
187
+ # },
188
+ # h: "val"
189
+ # }
190
+ #
191
+ # That string will get parsed and yield an array like
192
+ # [ a, b, c.d, c.e.f, c.e.g, h ]
193
+ #
194
+
195
+ def field_names(opt_fields)
196
+ fields = []
197
+ token_stack = []
198
+ last_token = false
199
+ tokens = opt_fields.split /(\(|,|\))/
200
+ tokens << nil
201
+ tokens.each do |t|
202
+ if t.nil? then
203
+ fields << (token_stack + [last_token]).join('.') if last_token
204
+ elsif t.empty? then
205
+ next
206
+ elsif t == ',' then
207
+ fields << (token_stack + [last_token]).join('.') if last_token
208
+ elsif t == '(' then
209
+ token_stack.push(last_token)
210
+ elsif t == ')' then
211
+ fields << (token_stack + [last_token]).join('.') if last_token
212
+ token_stack.pop
213
+ last_token = false
214
+ else
215
+ last_token = t
216
+ end
217
+ end
218
+ fields
219
+ end
220
+
221
+ ##
222
+ # This method will accept a field name in a format like 'c.e.g'
223
+ # and convert it into 'c&.e&.g', which can be evaluated to get
224
+ # the value of g, or nil if any intermediate value is nil.
225
+
226
+ def field_expression(name)
227
+ parts = name.split(/\./)
228
+ parts.join('&.')
229
+ end
230
+
231
+ ##
232
+ # This method will accept two arrays, a and b, and create a third array
233
+ # like [ [a[0],b[0]], [a[1],b[1]], [a[2],b[2]], ...].
234
+ # If either array is longer than the other, additional pairs
235
+ # will be generated with the shorter array padded out with nil values.
236
+ #
237
+ # Any additional args will be added to each inner array.
238
+
239
+ def pairs(a, b, *args)
240
+ pair_array = Array.new([a.count,b.count].max) do |i|
241
+ pair = [a.fetch(i,nil),b.fetch(i,nil)]
242
+ pair += args if args
243
+ pair
244
+ end
245
+
246
+ return pair_array unless block_given?
247
+
248
+ pair_array.collect { |e| yield(e) }
249
+ end
250
+ end
251
+ end