killbill-kpm 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (79) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +33 -0
  3. data/.travis.yml +38 -0
  4. data/Gemfile +3 -0
  5. data/Gemfile.head +5 -0
  6. data/Gemfile.lock +90 -0
  7. data/Jarfile +11 -0
  8. data/Jarfile.lock +56 -0
  9. data/LICENSE +201 -0
  10. data/README.md +2 -2
  11. data/Rakefile +16 -31
  12. data/VERSION +1 -0
  13. data/config.ru +4 -0
  14. data/killbill-kpm.gemspec +31 -0
  15. data/killbill.properties +3 -0
  16. data/lib/kpm/application.rb +91 -0
  17. data/lib/kpm/listener.rb +94 -0
  18. data/lib/kpm/plugins_installer.rb +113 -0
  19. data/lib/kpm_plugin.rb +13 -0
  20. data/pom.xml +44 -0
  21. data/release.sh +61 -0
  22. data/spec/kpm/base_plugin_spec.rb +25 -0
  23. data/spec/spec_helper.rb +14 -0
  24. metadata +49 -349
  25. data/MIT-LICENSE +0 -20
  26. data/app/assets/javascripts/application.js +0 -24
  27. data/app/assets/javascripts/kpm/kpm.js +0 -7
  28. data/app/assets/stylesheets/application.css +0 -19
  29. data/app/assets/stylesheets/bootstrap_and_overrides.css +0 -17
  30. data/app/assets/stylesheets/kpm/kpm.css +0 -6
  31. data/app/controllers/kpm/engine_controller.rb +0 -29
  32. data/app/controllers/kpm/nodes_info_controller.rb +0 -108
  33. data/app/controllers/kpm/plugins_controller.rb +0 -19
  34. data/app/helpers/kpm/application_helper.rb +0 -4
  35. data/app/views/kpm/layouts/kpm_application.html.erb +0 -31
  36. data/app/views/kpm/nodes_info/_logs_table.html.erb +0 -43
  37. data/app/views/kpm/nodes_info/_nodes_table.html.erb +0 -68
  38. data/app/views/kpm/nodes_info/index.html.erb +0 -68
  39. data/app/views/kpm/nodes_info/index.js.erb +0 -4
  40. data/app/views/kpm/plugins/_form.html.erb +0 -37
  41. data/app/views/kpm/plugins/_plugins_table.html.erb +0 -48
  42. data/app/views/kpm/plugins/index.html.erb +0 -18
  43. data/config/routes.rb +0 -17
  44. data/lib/kpm.rb +0 -24
  45. data/lib/kpm/client.rb +0 -31
  46. data/lib/kpm/engine.rb +0 -23
  47. data/lib/kpm/version.rb +0 -3
  48. data/lib/tasks/kpm_tasks.rake +0 -4
  49. data/test/dummy/README.rdoc +0 -28
  50. data/test/dummy/Rakefile +0 -6
  51. data/test/dummy/app/controllers/application_controller.rb +0 -5
  52. data/test/dummy/app/helpers/application_helper.rb +0 -2
  53. data/test/dummy/bin/bundle +0 -3
  54. data/test/dummy/bin/rails +0 -4
  55. data/test/dummy/bin/rake +0 -4
  56. data/test/dummy/bin/setup +0 -29
  57. data/test/dummy/config.ru +0 -4
  58. data/test/dummy/config/application.rb +0 -32
  59. data/test/dummy/config/boot.rb +0 -5
  60. data/test/dummy/config/database.yml +0 -23
  61. data/test/dummy/config/environment.rb +0 -5
  62. data/test/dummy/config/environments/development.rb +0 -41
  63. data/test/dummy/config/environments/production.rb +0 -79
  64. data/test/dummy/config/environments/test.rb +0 -42
  65. data/test/dummy/config/initializers/assets.rb +0 -11
  66. data/test/dummy/config/initializers/backtrace_silencers.rb +0 -7
  67. data/test/dummy/config/initializers/cookies_serializer.rb +0 -3
  68. data/test/dummy/config/initializers/filter_parameter_logging.rb +0 -4
  69. data/test/dummy/config/initializers/inflections.rb +0 -16
  70. data/test/dummy/config/initializers/killbill_client.rb +0 -3
  71. data/test/dummy/config/initializers/mime_types.rb +0 -4
  72. data/test/dummy/config/initializers/session_store.rb +0 -3
  73. data/test/dummy/config/initializers/wrap_parameters.rb +0 -14
  74. data/test/dummy/config/locales/en.yml +0 -23
  75. data/test/dummy/config/routes.rb +0 -4
  76. data/test/dummy/config/secrets.yml +0 -22
  77. data/test/integration/navigation_test.rb +0 -8
  78. data/test/kpm_test.rb +0 -7
  79. data/test/test_helper.rb +0 -21
@@ -1,20 +0,0 @@
1
- Copyright 2015 The Billing Project, LLC
2
-
3
- Permission is hereby granted, free of charge, to any person obtaining
4
- a copy of this software and associated documentation files (the
5
- "Software"), to deal in the Software without restriction, including
6
- without limitation the rights to use, copy, modify, merge, publish,
7
- distribute, sublicense, and/or sell copies of the Software, and to
8
- permit persons to whom the Software is furnished to do so, subject to
9
- the following conditions:
10
-
11
- The above copyright notice and this permission notice shall be
12
- included in all copies or substantial portions of the Software.
13
-
14
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
- EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
- NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
- LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
- OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
- WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -1,24 +0,0 @@
1
- // This is a manifest file that'll be compiled into application.js, which will include all the files
2
- // listed below.
3
- //
4
- // Any JavaScript/Coffee file within this directory, lib/assets/javascripts, vendor/assets/javascripts,
5
- // or any plugin's vendor/assets/javascripts directory can be referenced here using a relative path.
6
- //
7
- // It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
8
- // compiled file.
9
- //
10
- // Read Sprockets README (https://github.com/rails/sprockets#sprockets-directives) for details
11
- // about supported directives.
12
- //
13
- //= require js-routes
14
- //= require moment
15
- //= require spin
16
- //= require jquery
17
- //= require jquery_ujs
18
- //= require twitter/bootstrap
19
- //= require dataTables/jquery.dataTables
20
- //= require dataTables/bootstrap/3/jquery.dataTables.bootstrap
21
- //= require d3
22
- //= require bootstrap-datepicker
23
- //= require jquery.spin
24
- //= require kpm/kpm
@@ -1,7 +0,0 @@
1
- // This is a manifest file that'll be compiled into including all the files listed below.
2
- // Add new JavaScript/Coffee code in separate files in this directory and they'll automatically
3
- // be included in the compiled file accessible from http://example.com/assets/application.js
4
- // It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
5
- // the compiled file.
6
- //
7
- //= require_tree .
@@ -1,19 +0,0 @@
1
- /*
2
- * This is a manifest file that'll be compiled into application.css, which will include all the files
3
- * listed below.
4
- *
5
- * Any CSS and SCSS file within this directory, lib/assets/stylesheets, vendor/assets/stylesheets,
6
- * or any plugin's vendor/assets/stylesheets directory can be referenced here using a relative path.
7
- *
8
- * You're free to add application-wide styles to this file and they'll appear at the bottom of the
9
- * compiled file so the styles you add here take precedence over styles defined in any styles
10
- * defined in the other CSS/SCSS files in this directory. It is generally better to create a new
11
- * file per style scope.
12
- *
13
- *= require_self
14
- *= require bootstrap-datepicker3
15
- *= require dataTables/jquery.dataTables
16
- *= require dataTables/bootstrap/3/jquery.dataTables.bootstrap
17
- *= require bootstrap_and_overrides
18
- *= require kpm/kpm
19
- */
@@ -1,17 +0,0 @@
1
- /*
2
- *= require twitter-bootstrap-static/bootstrap
3
- *
4
- * Use Font Awesome icons (default)
5
- * To use Glyphicons sprites instead of Font Awesome, replace with "require twitter-bootstrap-static/sprites"
6
- *= require twitter-bootstrap-static/fontawesome
7
- */
8
-
9
- /* Override Bootstrap 3 font locations */
10
- @font-face {
11
- font-family: 'Glyphicons Halflings';
12
- src: url('../assets/glyphicons-halflings-regular.eot');
13
- src: url('../assets/glyphicons-halflings-regular.eot?#iefix') format('embedded-opentype'),
14
- url('../assets/glyphicons-halflings-regular.woff') format('woff'),
15
- url('../assets/glyphicons-halflings-regular.ttf') format('truetype'),
16
- url('../assets/glyphicons-halflings-regular.svg#glyphicons_halflingsregular') format('svg');
17
- }
@@ -1,6 +0,0 @@
1
- /*
2
- * This is a manifest file that'll automatically include all the stylesheets available in this directory
3
- * and any sub-directories. You're free to add application-wide styles to this file and they'll appear at
4
- * the top of the compiled file, but it's generally better to create a new file per style scope.
5
- *= require_tree .
6
- */
@@ -1,29 +0,0 @@
1
- module KPM
2
- class EngineController < ApplicationController
3
-
4
- layout :get_layout
5
-
6
- def get_layout
7
- layout ||= KPM.config[:layout]
8
- end
9
-
10
- def current_tenant_user
11
- # If the rails application on which that engine is mounted defines such method (Devise), we extract the current user,
12
- # if not we default to nil, and serve our static mock configuration
13
- user = current_user if respond_to?(:current_user)
14
- KPM.current_tenant_user.call(session, user)
15
- end
16
-
17
- def options_for_klient
18
- user = current_tenant_user
19
- {
20
- :username => user[:username],
21
- :password => user[:password],
22
- :session_id => user[:session_id],
23
- :api_key => user[:api_key],
24
- :api_secret => user[:api_secret]
25
- }
26
- end
27
-
28
- end
29
- end
@@ -1,108 +0,0 @@
1
- require 'kpm/client'
2
-
3
- module KPM
4
- class NodesInfoController < EngineController
5
-
6
- def index
7
- @nodes_info = ::KillBillClient::Model::NodesInfo.nodes_info(options_for_klient)
8
-
9
- # For convenience, put pure OSGI bundles at the bottom
10
- @nodes_info.each do |node_info|
11
- next if node_info.plugins_info.nil?
12
- node_info.plugins_info.sort! do |a, b|
13
- if osgi_bundle?(a) && !osgi_bundle?(b)
14
- 1
15
- elsif !osgi_bundle?(a) && osgi_bundle?(b)
16
- -1
17
- else
18
- a.plugin_name <=> b.plugin_name
19
- end
20
- end
21
- end
22
-
23
- @logs = ::Killbill::KPM::KPMClient.get_osgi_logs(options_for_klient).reverse
24
-
25
- respond_to do |format|
26
- format.html
27
- format.js
28
- end
29
- end
30
-
31
- def install_plugin
32
- command_properties = [
33
- build_node_command_property('forceDownload', params[:force_download] == '1')
34
- ]
35
- trigger_node_plugin_command('INSTALL_PLUGIN', command_properties)
36
-
37
- redirect_to :action => :index
38
- end
39
-
40
- def install_plugin_from_fs
41
- ::Killbill::KPM::KPMClient.install_plugin(params.require(:name),
42
- params.require(:version),
43
- params.require(:type),
44
- params.require(:plugin).original_filename,
45
- params.require(:plugin).read,
46
- options_for_klient)
47
-
48
- redirect_to :action => :index
49
- end
50
-
51
- def uninstall_plugin
52
- trigger_node_plugin_command('UNINSTALL_PLUGIN')
53
- render :nothing => true
54
- end
55
-
56
- def start_plugin
57
- trigger_node_plugin_command('START_PLUGIN')
58
- render :nothing => true
59
- end
60
-
61
- def stop_plugin
62
- trigger_node_plugin_command('STOP_PLUGIN')
63
- render :nothing => true
64
- end
65
-
66
- def restart_plugin
67
- trigger_node_plugin_command('RESTART_PLUGIN')
68
- render :nothing => true
69
- end
70
-
71
- private
72
-
73
- def trigger_node_plugin_command(command_type, command_properties=[], plugin_name=nil, plugin_version=nil)
74
- command_properties << build_node_command_property('pluginName', plugin_name || params.require(:plugin_name))
75
- command_properties << build_node_command_property('pluginVersion', plugin_version || params[:plugin_version])
76
-
77
- trigger_node_command(command_type, command_properties)
78
- end
79
-
80
- def trigger_node_command(command_type, command_properties=[])
81
- node_command = ::KillBillClient::Model::NodeCommandAttributes.new
82
- node_command.system_command_type = true
83
- node_command.node_command_type = command_type
84
- node_command.node_command_properties = command_properties
85
-
86
- # TODO Can we actually use node_name?
87
- local_node_only = false
88
-
89
- ::KillBillClient::Model::NodesInfo.trigger_node_command(node_command,
90
- local_node_only,
91
- options_for_klient[:username],
92
- params[:reason],
93
- params[:comment],
94
- options_for_klient)
95
- end
96
-
97
- def build_node_command_property(key, value)
98
- property = ::KillBillClient::Model::NodeCommandPropertyAttributes.new
99
- property.key = key
100
- property.value = value
101
- property
102
- end
103
-
104
- def osgi_bundle?(plugin_info)
105
- plugin_info.version.blank? || plugin_info.plugin_name.starts_with?('org.apache.felix.') || plugin_info.plugin_name.starts_with?('org.kill-bill.billing.killbill-platform-')
106
- end
107
- end
108
- end
@@ -1,19 +0,0 @@
1
- require 'kpm/client'
2
-
3
- module KPM
4
- class PluginsController < EngineController
5
-
6
- def index
7
- begin
8
- plugins = ::Killbill::KPM::KPMClient.get_available_plugins(true, options_for_klient)
9
- rescue => e
10
- # No connectivity, GitHub down, ...
11
- Rails.logger.warn("Unable to get latest plugins, trying built-in directory: #{e.inspect}")
12
- plugins = ::Killbill::KPM::KPMClient.get_available_plugins(false, options_for_klient)
13
- end
14
-
15
- @plugins = Hash[plugins.sort]
16
- end
17
-
18
- end
19
- end
@@ -1,4 +0,0 @@
1
- module KPM
2
- module ApplicationHelper
3
- end
4
- end
@@ -1,31 +0,0 @@
1
- <!DOCTYPE html>
2
- <html>
3
- <head>
4
- <title>KPM</title>
5
- <%= yield :scripts %>
6
- <%= stylesheet_link_tag 'application', :media => 'all' %>
7
- <%= javascript_include_tag 'application' %>
8
- <%= csrf_meta_tags %>
9
- </head>
10
- <div class="container-fluid">
11
- <%- # :alert used by devise -%>
12
- <% [:error, :alert].each do |key| %>
13
- <% if flash[key] %>
14
- <div class="row">
15
- <div class="col-md-10 col-md-offset-2">
16
- <div class="alert alert-error"><%= flash[key] %></div>
17
- </div>
18
- </div>
19
- <% end %>
20
- <% end %>
21
- <% if flash[:notice] %>
22
- <div class="row">
23
- <div class="col-md-10 col-md-offset-2">
24
- <div class="alert alert-info"><%= flash[:notice] %></div>
25
- </div>
26
- </div>
27
- <% end %>
28
- <%= yield %>
29
- </div>
30
- </body>
31
- </html>
@@ -1,43 +0,0 @@
1
- <table id="logs-table" class="table table-condensed table-striped mobile-data">
2
- <thead>
3
- <tr>
4
- <th>Time</th>
5
- <th>Name</th>
6
- <th>Level</th>
7
- <th>Message</th>
8
- </tr>
9
- </thead>
10
- <tbody>
11
- <% logs.each do |log| %>
12
- <tr>
13
- <td>
14
- <% unless log['time'].blank? %>
15
- <%= DateTime.strptime(log['time'].to_s, '%Q').strftime('%Y-%m-%d %H:%M:%S') %>
16
- <% end %>
17
- </td>
18
- <td><%= log['name'] %></td>
19
- <td>
20
- <% if log['level'] == 'ERROR' %>
21
- <span class="label label-danger"><%= log['level'] %></span>
22
- <% elsif log['level'] == 'WARNING' %>
23
- <span class="label label-warning"><%= log['level'] %></span>
24
- <% else %>
25
- <span class="label label-success"><%= log['level'] %></span>
26
- <% end %>
27
- </td>
28
- <td><pre><%= log['message'] %></pre></td>
29
- </tr>
30
- <% end %>
31
- </tbody>
32
- </table>
33
-
34
- <%= javascript_tag do %>
35
- $(document).ready(function() {
36
- $('#logs-table').dataTable({
37
- "dom": "<'row'r>t<'row'<'col-md-6'i><'col-md-6'p>>",
38
- "pagingType": "full_numbers",
39
- "pageLength": 50,
40
- "ordering": false
41
- });
42
- });
43
- <% end %>
@@ -1,68 +0,0 @@
1
- <table id="nodes-table" class="table table-condensed table-striped mobile-data">
2
- <thead>
3
- <tr>
4
- <th>Node name</th>
5
- <th>Boot time</th>
6
- <th>Updated date</th>
7
- <th>Kill Bill version</th>
8
- <th>Dependencies</th>
9
- <th>Plugins</th>
10
- </tr>
11
- </thead>
12
- <tbody>
13
- <% nodes_info.each do |node_info| %>
14
- <tr>
15
- <td><%= node_info.node_name %></td>
16
- <td>
17
- <% unless node_info.boot_time.blank? %>
18
- <%= time_ago_in_words(DateTime.parse(node_info.boot_time)) %> ago
19
- <% end %>
20
- </td>
21
- <td>
22
- <% unless node_info.last_updated_date.blank? %>
23
- <%= time_ago_in_words(DateTime.parse(node_info.last_updated_date)) %> ago
24
- <% end %>
25
- </td>
26
- <td><%= node_info.kb_version %></td>
27
- <td>
28
- <ul>
29
- <li>API: <%= node_info.api_version %></li>
30
- <li>Plugin API: <%= node_info.plugin_api_version %></li>
31
- <li>Platform: <%= node_info.platform_version %></li>
32
- <li>Commons: <%= node_info.common_version %></li>
33
- </ul>
34
- </td>
35
- <td>
36
- <% unless (node_info.plugins_info || []).empty? %>
37
- <ul>
38
- <% node_info.plugins_info.each do |plugin_info| %>
39
- <li>
40
- <%= plugin_info.plugin_name %> <%= plugin_info.version %> <span class="label label-<%= plugin_info.state == 'RUNNING' ? 'success' : (plugin_info.state == 'INSTALLED' ? 'warning' : 'danger') %>"><%= plugin_info.state %></span>
41
- <% if plugin_info.state == 'RUNNING' %>
42
- <%= link_to '<i class="fa fa-pause"></i>'.html_safe, plugin_stop_path(:plugin_name => plugin_info.plugin_name, :plugin_version => plugin_info.version), :method => :post, :title => 'Stop', :remote => true, :class => 'plugin-link' %>
43
- <%= link_to '<i class="fa fa-refresh"></i>'.html_safe, plugin_restart_path(:plugin_name => plugin_info.plugin_name, :plugin_version => plugin_info.version), :method => :post, :title => 'Restart', :remote => true, :class => 'plugin-link' %>
44
- <% elsif plugin_info.state == 'INSTALLED' || plugin_info.state == 'STOPPED' %>
45
- <%= link_to '<i class="fa fa-play"></i>'.html_safe, plugin_start_path(:plugin_name => plugin_info.plugin_name, :plugin_version => plugin_info.version), :method => :post, :title => 'Start', :remote => true, :class => 'plugin-link' %>
46
- <% end %>
47
- <% unless plugin_info.version.nil? %>
48
- <%= link_to '<i class="fa fa-eject"></i>'.html_safe, plugin_uninstall_path(:plugin_name => plugin_info.plugin_name, :plugin_version => plugin_info.version), :method => :post, :title => 'Uninstall', :remote => true, :class => 'plugin-link' %>
49
- <% end %>
50
- </li>
51
- <% end %>
52
- </ul>
53
- <% end %>
54
- </td>
55
- </tr>
56
- <% end %>
57
- </tbody>
58
- </table>
59
-
60
- <%= javascript_tag do %>
61
- $(document).ready(function() {
62
- $('#nodes-table').dataTable({
63
- "dom": "t",
64
- "paging": false,
65
- "ordering": false
66
- });
67
- });
68
- <% end %>
@@ -1,68 +0,0 @@
1
- <div class="search">
2
-
3
- <div class="column-block">
4
-
5
- <h1>Configured instances</h1>
6
-
7
- <div id="nodes-table-wrapper">
8
- <%= render :partial => 'kpm/nodes_info/nodes_table', :locals => {:nodes_info => @nodes_info} %>
9
- </div>
10
-
11
- </div>
12
-
13
- <div class="column-block">
14
-
15
- <h1><%= link_to 'Install new plugin', plugins_path %></h1>
16
-
17
- </div>
18
-
19
- <div class="column-block">
20
-
21
- <h1>Logs</h1>
22
-
23
- <div id="logs-table-wrapper">
24
- <%= render :partial => 'kpm/nodes_info/logs_table', :locals => {:logs => @logs} %>
25
- </div>
26
-
27
- </div>
28
-
29
- </div>
30
-
31
- <%= javascript_tag do %>
32
- $(document).ready(function() {
33
- scheduleRefresh();
34
- });
35
-
36
- function scheduleRefresh() {
37
- var timer = setTimeout(refreshAll, 1500);
38
-
39
- // Stop refreshing when user clicks through logs
40
- $('#logs-table_wrapper a').one('click', function() {
41
- clearTimeout(timer);
42
- });
43
-
44
- $('.plugin-link').one('ajax:beforeSend', function() {
45
- // Disable the refresh
46
- clearTimeout(timer);
47
-
48
- // Prevent other clicks
49
- $('.plugin-link').removeAttr('data-remote')
50
- .removeAttr('data-method')
51
- .removeAttr('href')
52
-
53
- // Spin
54
- $(this).children().addClass('fa-spin');
55
- });
56
-
57
- $('.plugin-link').one('ajax:complete', function() {
58
- // Delay a bit, to give time for the plugin state to change before the next refresh
59
- setTimeout(refreshAll, 6000);
60
- });
61
- }
62
-
63
- function refreshAll() {
64
- $.ajax({
65
- url: "<%= nodes_info_index_path(:format => :js) %>"
66
- });
67
- }
68
- <% end %>