kibana-rack 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (213) hide show
  1. checksums.yaml +7 -0
  2. checksums.yaml.gz.sig +1 -0
  3. data.tar.gz.sig +0 -0
  4. data/.editorconfig +13 -0
  5. data/.gitattributes +2 -0
  6. data/.gitignore +10 -0
  7. data/.overcommit.yml +11 -0
  8. data/.rspec +2 -0
  9. data/.rubocop.yml +24 -0
  10. data/.simplecov +12 -0
  11. data/.travis.yml +5 -0
  12. data/.yardopts +13 -0
  13. data/CHANGELOG.md +5 -0
  14. data/CONTRIBUTING.md +105 -0
  15. data/Gemfile +30 -0
  16. data/LICENSE.txt +22 -0
  17. data/README.md +269 -0
  18. data/Rakefile +27 -0
  19. data/dashboards/blank.json +32 -0
  20. data/dashboards/default.json +90 -0
  21. data/dashboards/guided.json +272 -0
  22. data/dashboards/logstash.js +138 -0
  23. data/dashboards/logstash.json +227 -0
  24. data/dashboards/noted.json +161 -0
  25. data/examples/dashboards/default.json +90 -0
  26. data/examples/rack/config.ru +14 -0
  27. data/examples/rack_basic_auth/config.ru +18 -0
  28. data/examples/rack_basic_auth/dashboards/default.json +90 -0
  29. data/examples/rails/app/controllers/application_controller.rb +3 -0
  30. data/examples/rails/app/helpers/application_helper.rb +2 -0
  31. data/examples/rails/app/kibana/blank.json +32 -0
  32. data/examples/rails/app/kibana/default.json +90 -0
  33. data/examples/rails/app/kibana/guided.json +272 -0
  34. data/examples/rails/app/kibana/logstash.json +227 -0
  35. data/examples/rails/app/kibana/noted.json +161 -0
  36. data/examples/rails/bin/bundle +3 -0
  37. data/examples/rails/bin/rails +4 -0
  38. data/examples/rails/bin/rake +4 -0
  39. data/examples/rails/config.ru +2 -0
  40. data/examples/rails/config/application.rb +11 -0
  41. data/examples/rails/config/boot.rb +2 -0
  42. data/examples/rails/config/environment.rb +2 -0
  43. data/examples/rails/config/environments/development.rb +7 -0
  44. data/examples/rails/config/environments/production.rb +11 -0
  45. data/examples/rails/config/environments/test.rb +11 -0
  46. data/examples/rails/config/initializers/cookies_serializer.rb +1 -0
  47. data/examples/rails/config/initializers/filter_parameter_logging.rb +1 -0
  48. data/examples/rails/config/initializers/kibana.rb +3 -0
  49. data/examples/rails/config/initializers/session_store.rb +1 -0
  50. data/examples/rails/config/initializers/wrap_parameters.rb +3 -0
  51. data/examples/rails/config/routes.rb +3 -0
  52. data/examples/rails/config/secrets.yml +9 -0
  53. data/examples/rails/log/.keep +0 -0
  54. data/examples/sinatra/config.ru +27 -0
  55. data/examples/sinatra/dashboards/default.json +90 -0
  56. data/kibana-rack.gemspec +28 -0
  57. data/lib/kibana/rack.rb +34 -0
  58. data/lib/kibana/rack/version.rb +5 -0
  59. data/lib/kibana/rack/web.rb +60 -0
  60. data/spec/fixtures/dashboards/default.json +90 -0
  61. data/spec/fixtures/dashboards/templated.json +1 -0
  62. data/spec/spec_helper.rb +32 -0
  63. data/spec/unit/kibana/rack/web_spec.rb +69 -0
  64. data/spec/unit/kibana/rack_spec.rb +4 -0
  65. data/tabolario.gpg +31 -0
  66. data/tabolario.pem +21 -0
  67. data/web/assets/LICENSE.md +13 -0
  68. data/web/assets/README.md +69 -0
  69. data/web/assets/app/app.js +24 -0
  70. data/web/assets/app/components/require.config.js +4 -0
  71. data/web/assets/app/factories/store.js +4 -0
  72. data/web/assets/app/panels/bettermap/editor.html +1 -0
  73. data/web/assets/app/panels/bettermap/leaflet/images/layers-2x.png +0 -0
  74. data/web/assets/app/panels/bettermap/leaflet/images/layers.png +0 -0
  75. data/web/assets/app/panels/bettermap/leaflet/images/marker-icon-2x.png +0 -0
  76. data/web/assets/app/panels/bettermap/leaflet/images/marker-icon.png +0 -0
  77. data/web/assets/app/panels/bettermap/leaflet/images/marker-shadow.png +0 -0
  78. data/web/assets/app/panels/bettermap/leaflet/leaflet.css +1 -0
  79. data/web/assets/app/panels/bettermap/leaflet/leaflet.ie.css +1 -0
  80. data/web/assets/app/panels/bettermap/leaflet/leaflet.js +7 -0
  81. data/web/assets/app/panels/bettermap/leaflet/plugins.css +1 -0
  82. data/web/assets/app/panels/bettermap/leaflet/plugins.js +4 -0
  83. data/web/assets/app/panels/bettermap/module.css +1 -0
  84. data/web/assets/app/panels/bettermap/module.html +3 -0
  85. data/web/assets/app/panels/bettermap/module.js +8 -0
  86. data/web/assets/app/panels/column/editor.html +1 -0
  87. data/web/assets/app/panels/column/module.html +1 -0
  88. data/web/assets/app/panels/column/module.js +4 -0
  89. data/web/assets/app/panels/column/panelgeneral.html +1 -0
  90. data/web/assets/app/panels/dashcontrol/editor.html +1 -0
  91. data/web/assets/app/panels/dashcontrol/module.html +1 -0
  92. data/web/assets/app/panels/dashcontrol/module.js +4 -0
  93. data/web/assets/app/panels/derivequeries/editor.html +1 -0
  94. data/web/assets/app/panels/derivequeries/module.html +1 -0
  95. data/web/assets/app/panels/derivequeries/module.js +4 -0
  96. data/web/assets/app/panels/fields/editor.html +1 -0
  97. data/web/assets/app/panels/fields/micropanel.html +1 -0
  98. data/web/assets/app/panels/fields/module.html +1 -0
  99. data/web/assets/app/panels/fields/module.js +4 -0
  100. data/web/assets/app/panels/filtering/editor.html +1 -0
  101. data/web/assets/app/panels/filtering/meta.html +3 -0
  102. data/web/assets/app/panels/filtering/module.html +30 -0
  103. data/web/assets/app/panels/filtering/module.js +4 -0
  104. data/web/assets/app/panels/goal/editor.html +1 -0
  105. data/web/assets/app/panels/goal/module.html +1 -0
  106. data/web/assets/app/panels/goal/module.js +4 -0
  107. data/web/assets/app/panels/histogram/editor.html +1 -0
  108. data/web/assets/app/panels/histogram/module.html +40 -0
  109. data/web/assets/app/panels/histogram/module.js +5 -0
  110. data/web/assets/app/panels/histogram/queriesEditor.html +9 -0
  111. data/web/assets/app/panels/histogram/styleEditor.html +1 -0
  112. data/web/assets/app/panels/hits/editor.html +1 -0
  113. data/web/assets/app/panels/hits/module.html +1 -0
  114. data/web/assets/app/panels/hits/module.js +4 -0
  115. data/web/assets/app/panels/map/editor.html +1 -0
  116. data/web/assets/app/panels/map/lib/map.europe.js +4 -0
  117. data/web/assets/app/panels/map/lib/map.usa.js +4 -0
  118. data/web/assets/app/panels/map/lib/map.world.js +4 -0
  119. data/web/assets/app/panels/map/module.html +58 -0
  120. data/web/assets/app/panels/map/module.js +5 -0
  121. data/web/assets/app/panels/query/editor.html +1 -0
  122. data/web/assets/app/panels/query/editors/lucene.html +0 -0
  123. data/web/assets/app/panels/query/editors/regex.html +0 -0
  124. data/web/assets/app/panels/query/editors/topN.html +1 -0
  125. data/web/assets/app/panels/query/help/lucene.html +1 -0
  126. data/web/assets/app/panels/query/help/regex.html +1 -0
  127. data/web/assets/app/panels/query/help/topN.html +1 -0
  128. data/web/assets/app/panels/query/helpModal.html +1 -0
  129. data/web/assets/app/panels/query/meta.html +3 -0
  130. data/web/assets/app/panels/query/module.html +1 -0
  131. data/web/assets/app/panels/query/module.js +4 -0
  132. data/web/assets/app/panels/query/query.css +1 -0
  133. data/web/assets/app/panels/sparklines/editor.html +1 -0
  134. data/web/assets/app/panels/sparklines/module.html +1 -0
  135. data/web/assets/app/panels/sparklines/module.js +4 -0
  136. data/web/assets/app/panels/stats/editor.html +1 -0
  137. data/web/assets/app/panels/stats/module.html +7 -0
  138. data/web/assets/app/panels/stats/module.js +4 -0
  139. data/web/assets/app/panels/table/editor.html +1 -0
  140. data/web/assets/app/panels/table/micropanel.html +3 -0
  141. data/web/assets/app/panels/table/modal.html +31 -0
  142. data/web/assets/app/panels/table/module.html +52 -0
  143. data/web/assets/app/panels/table/module.js +4 -0
  144. data/web/assets/app/panels/table/pagination.html +1 -0
  145. data/web/assets/app/panels/terms/editor.html +1 -0
  146. data/web/assets/app/panels/terms/module.html +24 -0
  147. data/web/assets/app/panels/terms/module.js +4 -0
  148. data/web/assets/app/panels/text/editor.html +1 -0
  149. data/web/assets/app/panels/text/module.html +1 -0
  150. data/web/assets/app/panels/text/module.js +4 -0
  151. data/web/assets/app/panels/timepicker/custom.html +31 -0
  152. data/web/assets/app/panels/timepicker/editor.html +1 -0
  153. data/web/assets/app/panels/timepicker/module.html +3 -0
  154. data/web/assets/app/panels/timepicker/module.js +4 -0
  155. data/web/assets/app/panels/timepicker/refreshctrl.html +1 -0
  156. data/web/assets/app/panels/trends/editor.html +1 -0
  157. data/web/assets/app/panels/trends/module.html +9 -0
  158. data/web/assets/app/panels/trends/module.js +4 -0
  159. data/web/assets/app/partials/dashLoader.html +3 -0
  160. data/web/assets/app/partials/dashLoaderShare.html +1 -0
  161. data/web/assets/app/partials/dashboard.html +1 -0
  162. data/web/assets/app/partials/dasheditor.html +1 -0
  163. data/web/assets/app/partials/inspector.html +2 -0
  164. data/web/assets/app/partials/load.html +1 -0
  165. data/web/assets/app/partials/modal.html +1 -0
  166. data/web/assets/app/partials/paneladd.html +1 -0
  167. data/web/assets/app/partials/paneleditor.html +1 -0
  168. data/web/assets/app/partials/panelgeneral.html +1 -0
  169. data/web/assets/app/partials/querySelect.html +9 -0
  170. data/web/assets/app/partials/roweditor.html +1 -0
  171. data/web/assets/build.txt +153 -0
  172. data/web/assets/css/animate.min.css +1 -0
  173. data/web/assets/css/bootstrap-responsive.min.css +9 -0
  174. data/web/assets/css/bootstrap.dark.less +6290 -0
  175. data/web/assets/css/bootstrap.dark.min.css +9 -0
  176. data/web/assets/css/bootstrap.light.less +6287 -0
  177. data/web/assets/css/bootstrap.light.min.css +9 -0
  178. data/web/assets/css/font-awesome.min.css +1 -0
  179. data/web/assets/css/normalize.min.css +1 -0
  180. data/web/assets/css/timepicker.css +18 -0
  181. data/web/assets/favicon.ico +0 -0
  182. data/web/assets/font/FontAwesome.otf +0 -0
  183. data/web/assets/font/fontawesome-webfont.eot +0 -0
  184. data/web/assets/font/fontawesome-webfont.svg +399 -0
  185. data/web/assets/font/fontawesome-webfont.ttf +0 -0
  186. data/web/assets/font/fontawesome-webfont.woff +0 -0
  187. data/web/assets/img/annotation-icon.png +0 -0
  188. data/web/assets/img/cubes.png +0 -0
  189. data/web/assets/img/glyphicons-halflings-white.png +0 -0
  190. data/web/assets/img/glyphicons-halflings.png +0 -0
  191. data/web/assets/img/kibana.png +0 -0
  192. data/web/assets/img/light.png +0 -0
  193. data/web/assets/img/load.gif +0 -0
  194. data/web/assets/img/load_big.gif +0 -0
  195. data/web/assets/img/small.png +0 -0
  196. data/web/assets/index.html +1 -0
  197. data/web/assets/vendor/LICENSE.json +94 -0
  198. data/web/assets/vendor/bootstrap/less/tests/buttons.html +139 -0
  199. data/web/assets/vendor/bootstrap/less/tests/css-tests.css +3 -0
  200. data/web/assets/vendor/bootstrap/less/tests/css-tests.html +1399 -0
  201. data/web/assets/vendor/bootstrap/less/tests/forms-responsive.html +71 -0
  202. data/web/assets/vendor/bootstrap/less/tests/forms.html +179 -0
  203. data/web/assets/vendor/bootstrap/less/tests/navbar-fixed-top.html +104 -0
  204. data/web/assets/vendor/bootstrap/less/tests/navbar-static-top.html +107 -0
  205. data/web/assets/vendor/bootstrap/less/tests/navbar.html +107 -0
  206. data/web/assets/vendor/require/css-build.js +4 -0
  207. data/web/assets/vendor/require/require.js +4 -0
  208. data/web/assets/vendor/require/tmpl.js +4 -0
  209. data/web/assets/vendor/timezone.js +4 -0
  210. data/web/views/config.erb +80 -0
  211. data/web/views/index.erb +56 -0
  212. metadata +336 -0
  213. metadata.gz.sig +3 -0
@@ -0,0 +1,11 @@
1
+ Rails.application.configure do
2
+ config.cache_classes = true
3
+ config.consider_all_requests_local = true
4
+ config.eager_load = false
5
+ config.serve_static_assets = true
6
+ config.static_cache_control = 'public, max-age=3600'
7
+ config.action_controller.allow_forgery_protection = false
8
+ config.action_controller.perform_caching = false
9
+ config.action_dispatch.show_exceptions = false
10
+ config.active_support.deprecation = :stderr
11
+ end
@@ -0,0 +1 @@
1
+ Rails.application.config.action_dispatch.cookies_serializer = :json
@@ -0,0 +1 @@
1
+ Rails.application.config.filter_parameters += %i(password)
@@ -0,0 +1,3 @@
1
+ Kibana.configure do |config|
2
+ config.kibana_dashboards_path = Rails.root.join('app/kibana')
3
+ end
@@ -0,0 +1 @@
1
+ Rails.application.config.session_store :cookie_store, key: '_dummy_session'
@@ -0,0 +1,3 @@
1
+ ActiveSupport.on_load(:action_controller) do
2
+ wrap_parameters format: [:json] if respond_to?(:wrap_parameters)
3
+ end
@@ -0,0 +1,3 @@
1
+ Rails.application.routes.draw do
2
+ mount Kibana::Rack::Web => '/kibana'
3
+ end
@@ -0,0 +1,9 @@
1
+ ---
2
+ development:
3
+ secret_key_base: f8fbe13331f2261f989b0bffbe72a3255bff3a76d1b2061c6672a2addc5a4d68bf91ff969c7444d013c1d0ff2bd4c205bfe0f25564408d82cb99fbc42aa83150
4
+
5
+ test:
6
+ secret_key_base: d8aa6adba6ef61735c328af28544248524437fafdf251fcb040bbdeeec188124df4abe15b6f9672a10dfb556c8d3fd89395a94ecdab7f7d35e5600c75e672ac4
7
+
8
+ production:
9
+ secret_key_base: <%= ENV['SECRET_KEY_BASE'] %>
File without changes
@@ -0,0 +1,27 @@
1
+ ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../../Gemfile', __FILE__)
2
+ require 'bundler/setup' if File.exist?(ENV['BUNDLE_GEMFILE'])
3
+
4
+ require 'kibana/rack'
5
+ require 'sinatra/base'
6
+
7
+ ENV['EXAMPLE_NAME'] = 'Rails Example'
8
+
9
+ Kibana.configure do |config|
10
+ config.kibana_dashboards_path = File.expand_path('../../dashboards', __FILE__)
11
+ end
12
+
13
+ class SinatraExample < Sinatra::Base
14
+ get '/' do
15
+ 'kibana-rack Sinatra example'
16
+ end
17
+ end
18
+
19
+ app = Rack::Builder.app do
20
+ map '/kibana' do
21
+ use Kibana::Rack::Web
22
+ end
23
+
24
+ run SinatraExample
25
+ end
26
+
27
+ run app
@@ -0,0 +1,90 @@
1
+ {
2
+ "title": "kibana-rack Sinatra Example",
3
+ "services": {
4
+ "query": {
5
+ "list": {
6
+ "0": {
7
+ "query": "*",
8
+ "alias": "",
9
+ "color": "#7EB26D",
10
+ "id": 0,
11
+ "pin": false,
12
+ "type": "lucene"
13
+ }
14
+ },
15
+ "ids": [
16
+ 0
17
+ ]
18
+ },
19
+ "filter": {
20
+ "list": {},
21
+ "ids": []
22
+ }
23
+ },
24
+ "rows": [
25
+ {
26
+ "title": "Intro",
27
+ "height": "700px",
28
+ "editable": false,
29
+ "collapse": false,
30
+ "collapsable": false,
31
+ "panels": [
32
+ {
33
+ "error": false,
34
+ "span": 4,
35
+ "editable": false,
36
+ "group": [
37
+ "default"
38
+ ],
39
+ "type": "text",
40
+ "mode": "markdown",
41
+ "content": "![kibana](img/kibana.png) \n\n##### Did you just upgrade? Not expecting this screen?\nIf you were using the old default page you might not be expecting this screen. I understand, change can be awkward. Let me explain. \n\n##### Setting a global default dashboard\nKibana has always shipped with an interface for Logstash, still does! You can access it [here](index.html#dashboard/file/logstash.json). However, if you want to make it your default again, all you need to do is rename a file!\nIn your Kibana installation directory: \n\nRename *logstash.json* to *default.json* and refresh. Should be all set.\n\n##### But wait, there's more!\nIn fact, you can add any exported dashboard to that directory and access it as *http://YOUR-HOST -HERE/index.html#dashboard/file/YOUR-DASHBOARD.json*. Neat trick eh?",
42
+ "style": {},
43
+ "title": "",
44
+ "status": "Stable"
45
+ },
46
+ {
47
+ "error": false,
48
+ "span": 8,
49
+ "editable": false,
50
+ "group": [
51
+ "default"
52
+ ],
53
+ "type": "text",
54
+ "mode": "markdown",
55
+ "content": "### Welcome to Kibana. \nGlad you could make it. Happy to have you here! Lets get started, shall we?\n##### Requirements\n* **A good browser.** \n The latest version of Chrome or Firefox is recommended. Safari (latest version) and Internet Explorer 9 and above are also supported.\n* **A webserver.** \n Just somewhere to host the HTML and Javascript. Basically any webserver will work.\n* **Elasticsearch** \n 0.90.9 or above. \n\n##### Configuration\nIf Kibana and Elasticsearch are on the same host, and you're using the default Elasticsearch port, then you're all set. Kibana is configured to use that setup by default! \n\nIf not, you need to edit *config.js* and set the *elasticsearch* parameter with the URL (including port, probably 9200) of your Elasticsearch server. The host part should be the entire, fully qualified domain name, or IP, **not localhost**.\n#### Are you a Logstash User?\n+ **YES** - Great! We have a prebuilt dashboard: [(Logstash Dashboard)](index.html#/dashboard/file/logstash.json). See the note to the right about making it your global default \n\n+ **NO** - Hey, no problem, you just have a bit of setup to do. You have a few choices: \n\n 1. [Sample Dashboard](index.html#/dashboard/file/guided.json) *I don't have much data yet, please extract some basics for me* \n 2. [Unconfigured Dashboard](index.html#/dashboard/file/noted.json) *I have a lot of data and I don't want Kibana to query it at once*\n 3. [Blank Dashboard](index.html#/dashboard/file/blank.json) *I'm comfortable figuring it out on my own*",
56
+ "style": {},
57
+ "status": "Stable"
58
+ }
59
+ ],
60
+ "notice": false
61
+ }
62
+ ],
63
+ "editable": false,
64
+ "index": {
65
+ "interval": "none",
66
+ "pattern": "[logstash-]YYYY.MM.DD",
67
+ "default": "_all",
68
+ "warm_fields": false
69
+ },
70
+ "style": "dark",
71
+ "failover": false,
72
+ "panel_hints": true,
73
+ "pulldowns": [],
74
+ "nav": [],
75
+ "loader": {
76
+ "save_gist": false,
77
+ "save_elasticsearch": true,
78
+ "save_local": true,
79
+ "save_default": true,
80
+ "save_temp": true,
81
+ "save_temp_ttl_enable": true,
82
+ "save_temp_ttl": "30d",
83
+ "load_gist": true,
84
+ "load_elasticsearch": true,
85
+ "load_elasticsearch_size": 20,
86
+ "load_local": true,
87
+ "hide": false
88
+ },
89
+ "refresh": false
90
+ }
@@ -0,0 +1,28 @@
1
+ lib = File.expand_path('../lib', __FILE__)
2
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
3
+ require 'kibana/rack/version'
4
+
5
+ Gem::Specification.new do |spec|
6
+ spec.name = 'kibana-rack'
7
+ spec.version = Kibana::Rack::VERSION
8
+ spec.authors = ['Tony Burns']
9
+ spec.email = ['tony@tabolario.com']
10
+ spec.summary = 'Embed Kibana as a Rack application'
11
+ spec.description = spec.summary
12
+ spec.homepage = 'https://github.com/tabolario/kibana-rack'
13
+ spec.license = 'MIT'
14
+
15
+ spec.files = `git ls-files -z`.split("\x0")
16
+ spec.executables = spec.files.grep(/^bin\//) { |f| File.basename(f) }
17
+ spec.test_files = spec.files.grep(/^spec\//)
18
+ spec.require_paths = ['lib']
19
+
20
+ spec.cert_chain = %w(tabolario.pem)
21
+ spec.signing_key = File.expand_path('~/.ssh/gem-private_key.pem') if $PROGRAM_NAME =~ /gem\z/
22
+
23
+ spec.add_dependency 'faraday'
24
+ spec.add_dependency 'sinatra'
25
+ spec.add_dependency 'sinatra-contrib'
26
+
27
+ spec.add_development_dependency 'bundler', '~> 1.6'
28
+ end
@@ -0,0 +1,34 @@
1
+ require 'faraday'
2
+ require 'sinatra/base'
3
+ require 'sinatra/multi_route'
4
+
5
+ require 'kibana/rack/version'
6
+ require 'kibana/rack/web'
7
+
8
+ module Kibana
9
+ DEFAULT_ELASTICSEARCH_HOST = 'localhost'
10
+ DEFAULT_ELASTICSEARCH_PORT = 9200
11
+ DEFAULT_KIBANA_DASHBOARDS_PATH = File.expand_path('../../../dashboards', __FILE__)
12
+ DEFAULT_KIBANA_DEFAULT_ROUTE = '/dashboard/file/default.json'
13
+ DEFAULT_KIBANA_INDEX = 'kibana-int'
14
+
15
+ class << self
16
+ attr_accessor :elasticsearch_host, :elasticsearch_port
17
+ attr_accessor :kibana_dashboards_path, :kibana_default_route, :kibana_index
18
+
19
+ def configure(&block)
20
+ block.call(self)
21
+ end
22
+ end
23
+
24
+ configure do |config|
25
+ config.elasticsearch_host = DEFAULT_ELASTICSEARCH_HOST
26
+ config.elasticsearch_port = DEFAULT_ELASTICSEARCH_PORT
27
+ config.kibana_dashboards_path = DEFAULT_KIBANA_DASHBOARDS_PATH
28
+ config.kibana_default_route = DEFAULT_KIBANA_DEFAULT_ROUTE
29
+ config.kibana_index = DEFAULT_KIBANA_INDEX
30
+ end
31
+
32
+ module Rack
33
+ end
34
+ end
@@ -0,0 +1,5 @@
1
+ module Kibana
2
+ module Rack
3
+ VERSION = '0.1.0'
4
+ end
5
+ end
@@ -0,0 +1,60 @@
1
+ module Kibana
2
+ module Rack
3
+ # Rack application that serves Kibana and proxies requests to Elasticsearch
4
+ class Web < Sinatra::Base
5
+ VERSION = '0.1.0'
6
+
7
+ register Sinatra::MultiRoute
8
+
9
+ set :root, File.expand_path('../../../../web', __FILE__)
10
+ set :public_folder, -> { "#{root}/assets" }
11
+ set :views, -> { "#{root}/views" }
12
+
13
+ set :elasticsearch_host, -> { Kibana.elasticsearch_host }
14
+ set :elasticsearch_port, -> { Kibana.elasticsearch_port }
15
+ set :kibana_dashboards_path, -> { Kibana.kibana_dashboards_path }
16
+ set :kibana_default_route, -> { Kibana.kibana_default_route }
17
+ set :kibana_index, -> { Kibana.kibana_index }
18
+
19
+ helpers do
20
+ def proxy
21
+ es_host = settings.elasticsearch_host
22
+ es_port = settings.elasticsearch_port
23
+ @proxy ||= Faraday.new(url: "http://#{es_host}:#{es_port}")
24
+ end
25
+ end
26
+
27
+ get '/' do
28
+ erb :index
29
+ end
30
+
31
+ get '/config.js' do
32
+ content_type 'application/javascript'
33
+ erb :config
34
+ end
35
+
36
+ get(%r{/app/dashboards/([\w-]+\.js(on)?)}) do
37
+ dashboard = params[:captures].first
38
+ dashboard_path = File.join(settings.kibana_dashboards_path, dashboard)
39
+ halt(404, { 'Content-Type' => 'application/json' }, '{"error":"Not found"}') unless File.exist?(dashboard_path)
40
+ template = IO.read(dashboard_path)
41
+ content_type 'application/json'
42
+ erb template
43
+ end
44
+
45
+ route(:delete, :get, :post, :put, %r{^((/_(aliases|nodes))|(.+/_(aliases|mapping|search)))}) do
46
+ request.body.rewind
47
+
48
+ proxy_method = request.request_method.downcase.to_sym
49
+ proxy_response = proxy.send(proxy_method) do |proxy_request|
50
+ proxy_request.url(params[:captures].first)
51
+ proxy_request.headers['Content-Type'] = 'application/json'
52
+ proxy_request.params = env['rack.request.query_hash']
53
+ proxy_request.body = request.body.read if proxy_method == :post
54
+ end
55
+
56
+ [proxy_response.status, proxy_response.headers, proxy_response.body]
57
+ end
58
+ end
59
+ end
60
+ end
@@ -0,0 +1,90 @@
1
+ {
2
+ "title": "Introduction",
3
+ "services": {
4
+ "query": {
5
+ "list": {
6
+ "0": {
7
+ "query": "*",
8
+ "alias": "",
9
+ "color": "#7EB26D",
10
+ "id": 0,
11
+ "pin": false,
12
+ "type": "lucene"
13
+ }
14
+ },
15
+ "ids": [
16
+ 0
17
+ ]
18
+ },
19
+ "filter": {
20
+ "list": {},
21
+ "ids": []
22
+ }
23
+ },
24
+ "rows": [
25
+ {
26
+ "title": "Intro",
27
+ "height": "450px",
28
+ "editable": false,
29
+ "collapse": false,
30
+ "collapsable": false,
31
+ "panels": [
32
+ {
33
+ "error": false,
34
+ "span": 4,
35
+ "editable": false,
36
+ "group": [
37
+ "default"
38
+ ],
39
+ "type": "text",
40
+ "mode": "markdown",
41
+ "content": "![kibana](img/kibana.png) \n\n##### Did you just upgrade? Not expecting this screen?\nIf you were using the old default page you might not be expecting this screen. I understand, change can be awkward. Let me explain. \n\n##### Setting a global default dashboard\nKibana has always shipped with an interface for Logstash, still does! You can access it [here](index.html#dashboard/file/logstash.json). However, if you want to make it your default again, all you need to do is rename a file!\nIn your Kibana installation directory: \n\nRename *logstash.json* to *default.json* and refresh. Should be all set.\n\n##### But wait, there's more!\nIn fact, you can add any exported dashboard to that directory and access it as *http://YOUR-HOST -HERE/index.html#dashboard/file/YOUR-DASHBOARD.json*. Neat trick eh?",
42
+ "style": {},
43
+ "title": "",
44
+ "status": "Stable"
45
+ },
46
+ {
47
+ "error": false,
48
+ "span": 8,
49
+ "editable": false,
50
+ "group": [
51
+ "default"
52
+ ],
53
+ "type": "text",
54
+ "mode": "markdown",
55
+ "content": "### Welcome to Kibana. \nGlad you could make it. Happy to have you here! Lets get started, shall we?\n##### Requirements\n* **A good browser.** \n The latest version of Chrome or Firefox is recommended. Safari (latest version) and Internet Explorer 9 and above are also supported.\n* **A webserver.** \n Just somewhere to host the HTML and Javascript. Basically any webserver will work.\n* **Elasticsearch** \n 0.90.9 or above. \n\n##### Configuration\nIf Kibana and Elasticsearch are on the same host, and you're using the default Elasticsearch port, then you're all set. Kibana is configured to use that setup by default! \n\nIf not, you need to edit *config.js* and set the *elasticsearch* parameter with the URL (including port, probably 9200) of your Elasticsearch server. The host part should be the entire, fully qualified domain name, or IP, **not localhost**.\n#### Are you a Logstash User?\n+ **YES** - Great! We have a prebuilt dashboard: [(Logstash Dashboard)](index.html#/dashboard/file/logstash.json). See the note to the right about making it your global default \n\n+ **NO** - Hey, no problem, you just have a bit of setup to do. You have a few choices: \n\n 1. [Sample Dashboard](index.html#/dashboard/file/guided.json) *I don't have much data yet, please extract some basics for me* \n 2. [Unconfigured Dashboard](index.html#/dashboard/file/noted.json) *I have a lot of data and I don't want Kibana to query it at once*\n 3. [Blank Dashboard](index.html#/dashboard/file/blank.json) *I'm comfortable figuring it out on my own*",
56
+ "style": {},
57
+ "status": "Stable"
58
+ }
59
+ ],
60
+ "notice": false
61
+ }
62
+ ],
63
+ "editable": false,
64
+ "index": {
65
+ "interval": "none",
66
+ "pattern": "[logstash-]YYYY.MM.DD",
67
+ "default": "_all",
68
+ "warm_fields": false
69
+ },
70
+ "style": "dark",
71
+ "failover": false,
72
+ "panel_hints": true,
73
+ "pulldowns": [],
74
+ "nav": [],
75
+ "loader": {
76
+ "save_gist": false,
77
+ "save_elasticsearch": true,
78
+ "save_local": true,
79
+ "save_default": true,
80
+ "save_temp": true,
81
+ "save_temp_ttl_enable": true,
82
+ "save_temp_ttl": "30d",
83
+ "load_gist": true,
84
+ "load_elasticsearch": true,
85
+ "load_elasticsearch_size": 20,
86
+ "load_local": true,
87
+ "hide": false
88
+ },
89
+ "refresh": false
90
+ }
@@ -0,0 +1 @@
1
+ {"title":"<%= ENV['DASHBOARD_TITLE'] %>"}
@@ -0,0 +1,32 @@
1
+ require 'bundler/setup'
2
+ require 'simplecov'
3
+
4
+ Bundler.require(:test)
5
+ Bundler.require(:debugger) unless ENV.key?('CI')
6
+
7
+ ENV['RACK_ENV'] = 'test'
8
+
9
+ $LOAD_PATH.unshift File.expand_path('../../lib', __FILE__)
10
+ require 'kibana/rack'
11
+
12
+ require 'rack/test'
13
+ require 'webmock/rspec'
14
+
15
+ RSpec.configure do |config|
16
+ config.default_formatter = 'doc' if config.files_to_run.one?
17
+ config.filter_run :focus
18
+ config.order = :random
19
+ config.profile_examples = 10
20
+ config.run_all_when_everything_filtered = true
21
+
22
+ config.expect_with :rspec do |expectations|
23
+ expectations.syntax = :expect
24
+ end
25
+
26
+ config.mock_with :rspec do |mocks|
27
+ mocks.syntax = :expect
28
+ mocks.verify_partial_doubles = true
29
+ end
30
+
31
+ Kernel.srand config.seed
32
+ end
@@ -0,0 +1,69 @@
1
+ require 'spec_helper'
2
+
3
+ describe Kibana::Rack::Web do
4
+ include Rack::Test::Methods
5
+
6
+ let(:app) { described_class }
7
+
8
+ let(:dashboards_path) { File.expand_path('../../../../fixtures/dashboards', __FILE__) }
9
+
10
+ before do
11
+ app.set(:raise_exceptions, true)
12
+ app.set(:show_exceptions, false)
13
+ app.set(:kibana_dashboards_path, dashboards_path)
14
+ end
15
+
16
+ it 'serves the Kibana application' do
17
+ get '/'
18
+ expect(last_response.status).to eql(200)
19
+ end
20
+
21
+ it 'serves the Kibana configuration' do
22
+ get '/config.js'
23
+ expect(last_response.status).to eql(200)
24
+ end
25
+
26
+ it 'renders dashboards from the dashboard directory' do
27
+ get '/app/dashboards/default.json'
28
+
29
+ expect(last_response.body).to eql(IO.read(File.join(dashboards_path, 'default.json')))
30
+ expect(last_response.status).to eql(200)
31
+ end
32
+
33
+ it 'processes ERB in dashboards' do
34
+ ENV['DASHBOARD_TITLE'] = 'My Dashboard'
35
+ get '/app/dashboards/templated.json'
36
+
37
+ expect(last_response.body.strip).to eql('{"title":"My Dashboard"}')
38
+ end
39
+
40
+ it 'returns 404 if a dashboard does not exist' do
41
+ get '/app/dashboards/nonexistent.json'
42
+
43
+ expect(last_response.body.strip).to eql('{"error":"Not found"}')
44
+ expect(last_response.status).to eql(404)
45
+ end
46
+
47
+ {
48
+ '/_aliases' => { method: :get },
49
+ '/_nodes' => { method: :get },
50
+ '/_all/_aliases' => { method: :get },
51
+ '/_all/_mapping' => { method: :get },
52
+ '/_all/_search' => { method: :post, body: '{"j":"s","o":"n"}' },
53
+ '/logstash-2014.08.08,logstash-2014.08.09/_aliases' => { method: :get, params: { ignore_missing: 'true' } }
54
+ }.each do |path, options|
55
+ it "proxies #{options[:method].upcase} #{path} to Elasticsearch" do
56
+ request_method = options[:method]
57
+ stub_request(request_method, "localhost:9200#{path}")
58
+ .with(body: options[:body], query: options[:params])
59
+ .to_return(body: '{}', headers: { 'foo' => 'bar' }, status: 200)
60
+
61
+ request_params = request_method == :post ? options[:body] : options[:params]
62
+ send(request_method, path, request_params)
63
+
64
+ expect(last_response.body).to eql('{}')
65
+ expect(last_response.status).to eql(200)
66
+ expect(last_response.headers).to include('foo' => 'bar')
67
+ end
68
+ end
69
+ end