prometheus-splash 0.8.4 → 0.8.5

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 285fc8b213dd02cccc8f43153f9e63ba261d96a6f29dd87b0c7f3194130b09d5
4
- data.tar.gz: be38d7d3804b186ed62f9e3a50b18dd46ccf37c2fe9406b22fbab8df6ccc7af7
3
+ metadata.gz: d55ef029657bc02603c1c3723df64d3a296bf3956d55ba4a9309402ce468aedc
4
+ data.tar.gz: ba6cb4911ea6b5c4f6f2d8d5f4cb083f37111a768ce2978cadb5b701fdb4e186
5
5
  SHA512:
6
- metadata.gz: 9a91bf0cd11d39881f49cb81e3b070da161d8cf24664025360dd1036842c448ce4b86d2498f6d881ec190213780c93b6b15b90a19a4b0410da3a72aa961b2250
7
- data.tar.gz: 1c86c9ba9933d8031e5df00543e254cce43732f2f400f729bd2740f4a7f7ec765bc7d14610bd811cf1b8ceeab2d039d791267e9837db4132e6e193e069a2c2fd
6
+ metadata.gz: f85b863c72f11a4fe2716258c647ce28e2691462a1bf74bb84c8c5fa1cd17e8ec0edd0ac4cd0e816b61fc2d4f9ef536b492aaac6658c8e1567e4f6409d959df3
7
+ data.tar.gz: 45b4f6c99ae525033585a059d34e6c1f363f2f2ffdf4637b41aa2ec19ca5f042c436ee9c439fecc99ad937e73e32c7a430f4a74d2340e6486d9e46861f5af67e
@@ -185,3 +185,12 @@
185
185
  ### FIX
186
186
 
187
187
  * always missing status for log history #65
188
+
189
+
190
+ ## V 0.8.5
191
+
192
+ ### FEATURE
193
+
194
+ * WebUI R/W commands, logs, processes
195
+ * cosmetics
196
+ * multiples fix, debugging
data/README.md CHANGED
@@ -9,7 +9,7 @@ SPLASH is **Supervision with Prometheus of Logs and Asynchronous tasks orchestra
9
9
  * Web : http://www.ultragreen.net
10
10
  * Github : https://github.com/Ultragreen/prometheus-splash
11
11
  * Rubygems : https://rubygems.org/gems/prometheus-splash
12
- * DOC yardoc : https://www.rubydoc.info/gems/prometheus-splash/0.8.4
12
+ * DOC yardoc : https://www.rubydoc.info/gems/prometheus-splash/0.8.5
13
13
 
14
14
  Prometheus Logs and Batchs supervision over PushGateway
15
15
 
@@ -73,49 +73,51 @@
73
73
 
74
74
  ### Sample configuration of commands and scheduling
75
75
  :commands:
76
- :id_root:
76
+ - :name: :id_root
77
77
  :desc: run id command on root
78
78
  :command: id root
79
- :true_test:
79
+ - :name: :true_test
80
80
  :desc: "test command returning true : 0"
81
81
  :command: "true"
82
82
  :schedule:
83
83
  :every: "1h"
84
84
  :on_failure: :ls_slash_tmp
85
85
  :on_success: :pwd
86
- :false_test:
86
+ - :name: :false_test
87
87
  :desc: "test command returning false > 0"
88
88
  :command: "false"
89
89
  :schedule:
90
90
  :every: "1h"
91
91
  :on_failure: :ls_slash_tmp
92
92
  :on_success: :pwd
93
- :ls_slash_tmp:
93
+ - :name: :ls_slash_tmp
94
94
  :desc: list file in /tmp
95
95
  :command: ls -al /tmp
96
96
  :user: daemon
97
97
  :on_success: :echo1
98
- :pwd:
98
+ - :name: :pwd
99
99
  :desc: run pwd
100
100
  :command: pwd
101
101
  :on_success: :echo1
102
102
  :on_failure: :echo2
103
- :echo1:
103
+ - :name: :echo1
104
104
  :desc: echo 'foo'
105
105
  :command: echo foo
106
106
  :on_failure: :echo3
107
- :echo2:
107
+ - :name: :echo2
108
108
  :desc: echo 'bar'
109
109
  :command: echo bar
110
- :echo3:
110
+ - :name: :echo3
111
111
  :desc: echo 'been'
112
112
  :command: echo been
113
- :rand_sleep_5:
113
+ - :name: :rand_sleep_5
114
114
  :desc: sleep on a rand 5
115
115
  :command: ruby -e 'sleep rand(5)'
116
116
  :schedule:
117
- :every: "10s"
118
- :test_remote_call:
117
+ :every: "30s"
118
+ :retention:
119
+ :hours: 1
120
+ - :name: :test_remote_call
119
121
  :desc: remote call test
120
122
  :delegate_to:
121
123
  :host: omicron
@@ -138,7 +140,7 @@
138
140
 
139
141
  ### configuration of monitored processes
140
142
  :processes:
141
- - :process: cron
143
+ - :process: :cron
142
144
  :patterns:
143
145
  - cron
144
146
  :retention:
@@ -159,7 +159,7 @@ module CLISplash
159
159
  end
160
160
  log.info "Command : #{command.to_s}" if depht == 0
161
161
  aproc = Proc::new do |command,depht|
162
- cmd = commands[command.to_sym]
162
+ cmd = commands.select{|item| item[:name] == command.to_sym}.first
163
163
  if cmd[:on_failure] then
164
164
  spacer= " " * depht + " "
165
165
  log.flat "#{spacer}* on failure => #{cmd[:on_failure]}"
@@ -211,16 +211,16 @@ module CLISplash
211
211
  list = get_config.commands
212
212
  end
213
213
  log.info "Splash configured commands :"
214
- log.ko 'No configured commands found' if list.keys.empty?
215
- list.keys.each do |command|
216
- log.item "#{command.to_s}"
214
+ log.ko 'No configured commands found' if list.empty?
215
+ list.each do |command|
216
+ log.item "#{command[:name].to_s}"
217
217
  if options[:detail] then
218
- log.arrow "command line : '#{list[command][:command]}'"
219
- log.arrow "command description : '#{list[command][:desc]}'"
220
- log.arrow "command failure callback : '#{list[command.to_sym][:on_failure]}'" if list[command.to_sym][:on_failure]
221
- log.arrow "command success callback : '#{list[command.to_sym][:on_success]}'" if list[command.to_sym][:on_success]
222
- if list[command.to_sym][:schedule]
223
- sched,val = list[command.to_sym][:schedule].flatten
218
+ log.arrow "command line : '#{command[:command]}'"
219
+ log.arrow "command description : '#{command[:desc]}'"
220
+ log.arrow "command failure callback : '#{command[:on_failure]}'" if command[:on_failure]
221
+ log.arrow "command success callback : '#{command[:on_success]}'" if command[:on_success]
222
+ if command[:schedule] then
223
+ sched,val = command[:schedule].flatten
224
224
  log.arrow "command scheduled : #{sched} #{val}."
225
225
  end
226
226
  end
@@ -235,7 +235,7 @@ module CLISplash
235
235
  with --hostname <HOSTNAME>, an other Splash monitored server (only with Redis backend configured)
236
236
  LONGDESC
237
237
  option :hostname, :type => :string, :aliases => "-H"
238
- def show(command)
238
+ def show(name)
239
239
  unless is_root? then
240
240
  splash_exit case: :not_root, :more => "Command show specifications"
241
241
  end
@@ -261,14 +261,15 @@ module CLISplash
261
261
  else
262
262
  list = get_config.commands
263
263
  end
264
- if list.keys.include? command.to_sym then
265
- log.info "Splash command : #{command}"
266
- log.item "command line : '#{list[command.to_sym][:command]}'"
267
- log.item "command description : '#{list[command.to_sym][:desc]}'"
268
- log.item "command failure callback : '#{list[command.to_sym][:on_failure]}'" if list[command.to_sym][:on_failure]
269
- log.item "command success callback : '#{list[command.to_sym][:on_success]}'" if list[command.to_sym][:on_success]
270
- if list[command.to_sym][:schedule]
271
- sched,val = list[command.to_sym][:schedule].flatten
264
+ command = list.select{|item| item[:name] == name.to_sym}.first
265
+ unless command.nil? then
266
+ log.info "Splash command : #{command[:name]}"
267
+ log.item "command line : '#{command[:command]}'"
268
+ log.item "command description : '#{command[:desc]}'"
269
+ log.item "command failure callback : '#{command[:on_failure]}'" if command[:on_failure]
270
+ log.item "command success callback : '#{command[:on_success]}'" if command[:on_success]
271
+ if command[:schedule]
272
+ sched,val = command[:schedule].flatten
272
273
  log.item "command scheduled : #{sched} #{val}."
273
274
  end
274
275
  splash_exit case: :quiet_exit
@@ -301,7 +302,7 @@ module CLISplash
301
302
  value[:end_date],
302
303
  value[:exec_time],
303
304
  value[:stdout].empty?,
304
- value[:stdout].empty?]
305
+ value[:stderr].empty?]
305
306
  end
306
307
  end
307
308
  if check_unicode_term then
@@ -349,12 +350,12 @@ module CLISplash
349
350
  splash_exit case: :specific_config_required, :more => "Redis backend is requiered for Remote execution report request"
350
351
  end
351
352
  splash_exit case: :not_root if not is_root? and not redis
352
- list = get_config.commands.keys
353
+ list = get_config.commands
353
354
  if options[:hostname] then
354
355
  options[:hostname] = Socket.gethostname if options[:hostname] == 'hostname'
355
356
  list = backend.list("*", options[:hostname]).map(&:to_sym)
356
357
  end
357
- if list.include? command.to_sym then
358
+ if list.select{|cmd| cmd[:name] == command.to_sym}.count > 0 then
358
359
  log.info "Splash command #{command} previous execution report:\n"
359
360
  req = { :key => command}
360
361
  req[:hostname] = options[:hostname] if options[:hostname]
@@ -99,7 +99,7 @@ module CLISplash
99
99
  end
100
100
 
101
101
  # Thor method : sending reset verb over transport in the input queue of Splashd
102
- desc "getjobs", "send a reset verb to HOSTNAME daemon over transport (need an active tranport), Typicallly RabbitMQ"
102
+ desc "reset", "send a reset verb to HOSTNAME daemon over transport (need an active tranport), Typicallly RabbitMQ"
103
103
  def reset(hostname=Socket.gethostname)
104
104
  log = get_logger
105
105
  log.info "ctrl+c for interrupt"
@@ -48,6 +48,11 @@ module Splash
48
48
  @backend = get_backend :execution_trace
49
49
  end
50
50
 
51
+
52
+ def clear
53
+ @backend.del({:key => @name}) if @backend.exist?({key: @name})
54
+ end
55
+
51
56
  def purge(retention)
52
57
  retention = {} if retention.nil?
53
58
  if retention.include? :hours then
@@ -96,7 +101,7 @@ module Splash
96
101
  @config = get_config
97
102
  @url = @config.prometheus_pushgateway_url
98
103
  @name = name
99
- unless @config.commands.keys.include? @name.to_sym then
104
+ unless @config.commands.select{|cmd| cmd[:name] == @name.to_sym }.count > 0 then
100
105
  splash_exit case: :not_found, more: "command #{@name} is not defined in configuration"
101
106
  end
102
107
  end
@@ -139,18 +144,20 @@ module Splash
139
144
  session = (options[:session])? options[:session] : get_session
140
145
  acase = { :case => :quiet_exit }
141
146
  exit_code = 0
142
- if @config.commands[@name.to_sym][:delegate_to] then
147
+ command = @config.commands.select{|command| command[:name] == @name.to_sym}.first
148
+ if command[:delegate_to] then
143
149
  return { :case => :options_incompatibility, :more => '--hostname forbidden with delagate commands'} if options[:hostname]
144
- log.send "Remote command : #{@name} execution delegate to : #{@config.commands[@name.to_sym][:delegate_to][:host]} as : #{@config.commands[@name.to_sym][:delegate_to][:remote_command]}", session
150
+ log.send "Remote command : #{@name} execution delegate to : #{command[:delegate_to][:host]} as : #{command[:delegate_to][:remote_command]}", session
151
+ log.warn "Local command : #{command[:command]} defined but ignored, because delegate have the priority"
145
152
  begin
146
153
  transport = get_default_client
147
154
  if transport.class == Hash and transport.include? :case then
148
155
  return transport
149
156
  else
150
157
  res = transport.execute({ :verb => :execute_command,
151
- payload: {:name => @config.commands[@name.to_sym][:delegate_to][:remote_command].to_s},
158
+ payload: {:name => command[:delegate_to][:remote_command].to_s},
152
159
  :return_to => "splash.#{Socket.gethostname}.return",
153
- :queue => "splash.#{@config.commands[@name.to_sym][:delegate_to][:host]}.input" })
160
+ :queue => "splash.#{command[:delegate_to][:host]}.input" })
154
161
  exit_code = res[:exit_code]
155
162
  log.receive "return with exitcode #{exit_code}", session
156
163
 
@@ -164,35 +171,35 @@ module Splash
164
171
  start_date = DateTime.now.to_s
165
172
  unless options[:trace] then
166
173
  log.item "Traceless execution", session
167
- if @config.commands[@name.to_sym][:user] then
168
- log.item "Execute with user : #{@config.commands[@name.to_sym][:user]}.", session
169
- system("sudo -u #{@config.commands[@name.to_sym][:user]} #{@config.commands[@name.to_sym][:command]} > /dev/null 2>&1")
174
+ if command[:user] then
175
+ log.item "Execute with user : #{command[:user]}.", session
176
+ system("sudo -u #{command[:user]} #{command[:command]} > /dev/null 2>&1")
170
177
  else
171
- system("#{@config.commands[@name.to_sym][:command]} > /dev/null 2>&1")
178
+ system("#{command[:command]} > /dev/null 2>&1")
172
179
  end
173
180
  time = Time.now - start
174
181
  exit_code = $?.exitstatus
175
182
  else
176
183
  log.item "Tracefull execution", session
177
- if @config.commands[@name.to_sym][:user] then
178
- log.item "Execute with user : #{@config.commands[@name.to_sym][:user]}.", session
179
- stdout, stderr, status = Open3.capture3("sudo -u #{@config.commands[@name.to_sym][:user]} #{@config.commands[@name.to_sym][:command]}")
184
+ if command[:user] then
185
+ log.item "Execute with user : #{command[:user]}.", session
186
+ stdout, stderr, status = Open3.capture3("sudo -u #{command[:user]} #{command[:command]}")
180
187
  else
181
- stdout, stderr, status = Open3.capture3(@config.commands[@name.to_sym][:command])
188
+ stdout, stderr, status = Open3.capture3(command[:command])
182
189
  end
183
190
  time = Time.now - start
184
191
  data = Hash::new
185
192
  data[:start_date] = start_date
186
193
  data[:end_date] = DateTime.now.to_s
187
194
  data[:cmd_name] = @name
188
- data[:cmd_line] = @config.commands[@name.to_sym][:command]
189
- data[:desc] = @config.commands[@name.to_sym][:desc]
195
+ data[:cmd_line] = command[:command]
196
+ data[:desc] = command[:desc]
190
197
  data[:status] = status.to_s
191
198
  data[:stdout] = stdout
192
199
  data[:stderr] = stderr
193
200
  data[:exec_time] = time.to_s
194
201
  cmdrec = CmdRecords::new @name
195
- cmdrec.purge(@config.commands[@name.to_sym][:retention])
202
+ cmdrec.purge(command[:retention])
196
203
  cmdrec.add_record data
197
204
  exit_code = status.exitstatus
198
205
  end
@@ -205,24 +212,26 @@ module Splash
205
212
  end
206
213
  end
207
214
  if options[:callback] then
208
- on_failure = (@config.commands[@name.to_sym][:on_failure])? @config.commands[@name.to_sym][:on_failure] : false
209
- on_success = (@config.commands[@name.to_sym][:on_success])? @config.commands[@name.to_sym][:on_success] : false
215
+ on_failure = (command[:on_failure])? command[:on_failure] : false
216
+ on_success = (command[:on_success])? command[:on_success] : false
210
217
  if on_failure and exit_code > 0 then
211
218
  log.item "On failure callback : #{on_failure}", session
212
- if @config.commands.keys.include? on_failure then
219
+ if @config.commands.select {|item| item[:name] == on_failure}.count > 0 then
213
220
  @name = on_failure.to_s
214
221
  call_and_notify options
215
222
  else
216
- acase = { :case => :configuration_error , :more => "on_failure call error : #{on_failure} command inexistant."}
223
+ log.error "on_failure call error : #{on_failure.to_s} command inexistant.", session
224
+ acase = { :case => :configuration_error , :more => "Command #{command[:name]} callback coniguration error"}
217
225
  end
218
226
  end
219
227
  if on_success and exit_code == 0 then
220
228
  log.item "On success callback : #{on_success}", session
221
- if @config.commands.keys.include? on_success then
229
+ if @config.commands.select {|item| item[:name] == on_success}.count > 0 then
222
230
  @name = on_success.to_s
223
231
  call_and_notify options
224
232
  else
225
- acase = { :case => :configuration_error , :more => "on_success call error : #{on_failure} command inexistant."}
233
+ log.error "on_success call error : #{on_success.to_s} command inexistant."
234
+ acase = { :case => :configuration_error , :more => "Command #{command[:name]} callback coniguration error"}
226
235
  end
227
236
  end
228
237
  else
@@ -14,9 +14,13 @@ module Splash
14
14
  class ConfigLinter
15
15
  def initialize
16
16
  @lints_present = {:logs => [:label, :log, :pattern ],
17
- :processes => [:process, :patterns ]}
17
+ :processes => [:process, :patterns ],
18
+ :commands => [:name, :desc, :command ]}
18
19
  @lints_types = {:logs => {:label => Symbol, :log => String, :pattern => String, :retention => Hash},
19
- :processes => {:process => Symbol, :patterns => Array, :retention => Hash}}
20
+ :processes => {:process => Symbol, :patterns => Array, :retention => Hash},
21
+ :commands => {:name => Symbol, :desc => String, :command => String, :schedule => Hash,
22
+ :retention => Hash, :on_failure => Symbol, :on_success => Symbol,
23
+ :user => String, :delegate_to => Hash}}
20
24
  end
21
25
 
22
26
  def verify(options ={})
@@ -7,7 +7,7 @@ module Splash
7
7
  module Constants
8
8
 
9
9
  # Current splash version
10
- VERSION = "0.8.4"
10
+ VERSION = "0.8.5"
11
11
  # the path to th config file, not overridable by config
12
12
  CONFIG_FILE = "/etc/splash.yml"
13
13
  # the default execution trace_path if backend file
@@ -84,7 +84,7 @@ module Splash
84
84
  if VERBS.include? content[:verb]
85
85
  @log.receive "Valid remote order, verb : #{content[:verb].to_s}", session
86
86
  res = self.send content[:verb], content
87
- get_default_client.publish queue: content[:return_to], message: res.to_yaml
87
+ get_default_client.publish queue: content[:return_to], message: res.to_yaml unless content[:return_to] == :ignore
88
88
  @log.send "Result to #{content[:return_to]}.", session
89
89
  else
90
90
  @log.receive "INVALID remote order, verb : #{content[:verb].to_s}", session
@@ -155,15 +155,14 @@ module Splash
155
155
 
156
156
  # prepare commands Scheduling
157
157
  def init_commands_scheduling
158
- config = get_config.commands
159
- commands = config.select{|key,value| value.include? :schedule}.keys
158
+ commands = @config.commands.select{|command| command.include? :schedule}
160
159
  commands.each do |command|
161
- sched,value = config[command][:schedule].flatten
162
- @log.arrow "Scheduling command #{command.to_s}"
160
+ sched,value = command[:schedule].flatten
161
+ @log.arrow "Scheduling command #{command[:name].to_s}"
163
162
  @server.send sched,value do
164
163
  session = get_session
165
- @log.trigger "Executing Scheduled command #{command.to_s} for Scheduling : #{sched.to_s} #{value.to_s}", session
166
- execute command: command.to_s, session: session
164
+ @log.trigger "Executing Scheduled command #{command[:name].to_s} for Scheduling : #{sched.to_s} #{value.to_s}", session
165
+ execute command: command[:name].to_s, session: session
167
166
  end
168
167
  end
169
168
  end
@@ -66,7 +66,7 @@ module Splash
66
66
  # @return [Hash] Exiter case
67
67
  def execute_command(content)
68
68
  payload = content[:payload]
69
- unless get_config.commands.include? payload[:name].to_sym
69
+ unless get_config.commands.select {|cmd| cmd[:name] == payload[:name].to_sym}.count > 0 then
70
70
  @log.item "Command not found", content[:session]
71
71
  return { :case => :not_found }
72
72
  end
@@ -50,6 +50,7 @@ module Splash
50
50
 
51
51
 
52
52
  # Splash
53
+ require 'splash/monkeys'
53
54
  require 'splash/constants'
54
55
  require 'splash/helpers'
55
56
  require 'splash/config'
@@ -0,0 +1,5 @@
1
+ class Object
2
+ def blank?
3
+ respond_to?(:empty?) ? !!empty? : !self
4
+ end
5
+ end
@@ -25,12 +25,17 @@ module Splash
25
25
  list[name][:definition].each do |step|
26
26
  log.info "STEP : #{step[:step]}",session
27
27
  if step[:on_host].nil? then
28
- command = CommandWrapper::new(step[:command].to_s)
28
+ if get_config.commands.select{|cmd| cmd[:name] == step[:command]}.count > 0 then
29
+ command = CommandWrapper::new(step[:command].to_s)
29
30
  step[:callback] = true if step[:callback].nil?
30
31
  step[:trace] = true if step[:trace].nil?
31
32
  step[:notify] = true if step[:notify].nil?
32
33
  step[:session] = session
33
34
  acase = command.call_and_notify step
35
+ else
36
+ log.error "Commmand #{step[:command]} not found, for STEP : #{step[:step]}", session
37
+ acase = splash_return :not_found
38
+ end
34
39
  else
35
40
  log.info "Remote execution of #{step[:command]} on #{step[:on_host]}", session
36
41
  begin
@@ -16,7 +16,7 @@ WebAdminApp.get '/api/commands/show/:name.?:format?' do
16
16
  log = get_logger
17
17
  format = (params[:format])? format_by_extensions(params[:format]) : format_by_extensions('json')
18
18
  log.call "API : commands, verb : GET, route : show, item : #{params[:name]} , format : #{format}"
19
- commands_recordset = get_config.commands[params[:name].to_sym]
19
+ commands_recordset = get_config.commands.select {|command| command[:name] == params[:name].to_sym}.first
20
20
  unless commands_recordset.nil? then
21
21
  obj = splash_return case: :quiet_exit
22
22
  obj[:data] = commands_recordset
@@ -26,3 +26,15 @@ WebAdminApp.get '/api/commands/show/:name.?:format?' do
26
26
  content_type format
27
27
  format_response(obj, (params[:format])? format_by_extensions(params[:format]): request.accept.first)
28
28
  end
29
+
30
+ WebAdminApp.get '/api/commands/history/:name.?:format?' do
31
+ log = get_logger
32
+ format = (params[:format])? format_by_extensions(params[:format]) : format_by_extensions('json')
33
+ log.call "API : commands, verb : GET, route : history, format : #{format}"
34
+ record = Splash::Commands::CmdRecords::new(params[:name]).get_all_records
35
+ history = splash_return case: :quiet_exit, :more => "command monitoring history"
36
+ history[:data] = record
37
+ content_type format
38
+ status 201
39
+ format_response(history, (params[:format])? format_by_extensions(params[:format]): request.accept.first)
40
+ end
@@ -30,6 +30,7 @@ WebAdminApp.post '/api/config/addlog.?:format?' do
30
30
  res = get_config.add_record :record => YAML::load(request.body.read), :key => :label, :type => :logs, :clean => true
31
31
  case res[:status]
32
32
  when :success
33
+ rehash_daemon
33
34
  addlog = splash_return case: :quiet_exit, :more => "add log done"
34
35
  when :already_exist
35
36
  addlog = splash_return case: :already_exist, :more => "add log twice nto allowed"
@@ -49,6 +50,7 @@ WebAdminApp.post '/api/config/addprocess.?:format?' do
49
50
  res = get_config.add_record :record => YAML::load(request.body.read), :type => :processes, :key => :process, :clean => true
50
51
  case res[:status]
51
52
  when :success
53
+ rehash_daemon
52
54
  addprocess = splash_return case: :quiet_exit, :more => "add process done"
53
55
  when :already_exist
54
56
  addprocess = splash_return case: :already_exist, :more => "add process twice not allowed"
@@ -60,6 +62,26 @@ WebAdminApp.post '/api/config/addprocess.?:format?' do
60
62
  format_response(addprocess, (params[:format])? format_by_extensions(params[:format]): request.accept.first)
61
63
  end
62
64
 
65
+ WebAdminApp.post '/api/config/addcommand.?:format?' do
66
+ log = get_logger
67
+ addcommand = {}
68
+ format = (params[:format])? format_by_extensions(params[:format]) : format_by_extensions('json')
69
+ log.call "API : config, verb : POST, route : addcommand, format : #{format}"
70
+ res = get_config.add_record :record => YAML::load(request.body.read), :type => :commands, :key => :name, :clean => true
71
+ case res[:status]
72
+ when :success
73
+ rehash_daemon
74
+ addcommand = splash_return case: :quiet_exit, :more => "add command done"
75
+ when :already_exist
76
+ addcommand = splash_return case: :already_exist, :more => "add command twice not allowed"
77
+ when :failure
78
+ addpraddcommandocess = splash_return case: :configuration_error, :more => "add command failed"
79
+ addcommand[:data] = res
80
+ end
81
+ content_type format
82
+ format_response(addcommand, (params[:format])? format_by_extensions(params[:format]): request.accept.first)
83
+ end
84
+
63
85
 
64
86
 
65
87
  WebAdminApp.delete '/api/config/deletelog/:label.?:format?' do
@@ -72,6 +94,7 @@ WebAdminApp.delete '/api/config/deletelog/:label.?:format?' do
72
94
  res = get_config.delete_record :type => :logs, key: :label, label: params[:label].to_sym
73
95
  case res[:status]
74
96
  when :success
97
+ rehash_daemon
75
98
  deletelog = splash_return case: :quiet_exit, :more => "delete log done"
76
99
  when :not_found
77
100
  deletelog = splash_return case: :not_found, :more => "nothing done for logs"
@@ -92,6 +115,7 @@ WebAdminApp.delete '/api/config/deleteprocess/:process.?:format?' do
92
115
  res = get_config.delete_record :type => :processes, :key => :process, process: params[:process].to_sym
93
116
  case res[:status]
94
117
  when :success
118
+ rehash_daemon
95
119
  deleteprocess = splash_return case: :quiet_exit, :more => "delete process done"
96
120
  when :not_found
97
121
  deleteprocess = splash_return case: :not_found, :more => "nothing done for processes"
@@ -101,3 +125,24 @@ WebAdminApp.delete '/api/config/deleteprocess/:process.?:format?' do
101
125
  content_type format
102
126
  format_response(deleteprocess, (params[:format])? format_by_extensions(params[:format]): request.accept.first)
103
127
  end
128
+
129
+ WebAdminApp.delete '/api/config/deletecommand/:command.?:format?' do
130
+ log = get_logger
131
+ format = (params[:format])? format_by_extensions(params[:format]) : format_by_extensions('json')
132
+ log.call "API : config, verb : DELETE, route : deletecommand, format : #{format}"
133
+ deletecommand = {}
134
+ cmdrec = Splash::Commands::CmdRecords::new params[:command].to_sym
135
+ cmdrec.clear
136
+ res = get_config.delete_record :type => :commands, :key => :name, name: params[:command].to_sym
137
+ case res[:status]
138
+ when :success
139
+ rehash_daemon
140
+ deletecommand = splash_return case: :quiet_exit, :more => "delete command done"
141
+ when :not_found
142
+ deletecommand = splash_return case: :not_found, :more => "nothing done for commands"
143
+ else
144
+ deletecommand = splash_return case: :configuration_error, :more => "delete command failed"
145
+ end
146
+ content_type format
147
+ format_response(deletecommand, (params[:format])? format_by_extensions(params[:format]): request.accept.first)
148
+ end
@@ -9,6 +9,7 @@ class WebAdminApp < Sinatra::Base
9
9
  include Splash::Daemon::Controller
10
10
  include Splash::Logs
11
11
  include Splash::Processes
12
+ include Splash::Transports
12
13
 
13
14
  set :server, 'thin'
14
15
  set :port, get_config.webadmin_port
@@ -21,7 +22,18 @@ class WebAdminApp < Sinatra::Base
21
22
  rehash_config
22
23
  end
23
24
 
24
-
25
+ def rehash_daemon
26
+ status = get_processes({ :pattern => get_config.daemon_process_name}).empty?
27
+ if status == false then
28
+ transport = get_default_client
29
+ unless transport.class == Hash and transport.include? :case then
30
+ transport.publish queue: "splash.#{Socket.gethostname}.input",
31
+ message: { :verb => :reset,
32
+ :return_to => :ignore,
33
+ :queue => "splash.#{Socket.gethostname}.input" }.to_yaml
34
+ end
35
+ end
36
+ end
25
37
 
26
38
  end
27
39
 
@@ -1,9 +1,107 @@
1
- WebAdminApp.get '/commands' do
1
+ WebAdminApp.get '/commands/?:status?/?:command?' do
2
2
  get_menu 2
3
3
  log = get_logger
4
4
  log.call "WEB : commands, verb : GET, controller : /commands"
5
5
  url = "http://#{get_config.webadmin_ip}:#{get_config.webadmin_port}/api/commands/list.yml"
6
6
  raw = RestClient::Request.execute(method: 'GET', url: url,timeout: 10)
7
7
  @data = YAML::load(raw)[:data]
8
+ @command_failed = params[:command] if params[:status] == 'failure'
9
+ @command_saved = params[:command] if params[:status] == 'success'
8
10
  slim :commands, :format => :html
9
11
  end
12
+
13
+ WebAdminApp.get '/get_command_history/:command' do
14
+ get_menu 2
15
+ log = get_logger
16
+ log.call "WEB : commands, verb : GET, controller : /get_command_history/:command"
17
+ @data = {}
18
+ url = "http://#{get_config.webadmin_ip}:#{get_config.webadmin_port}/api/commands/history/#{params[:command].to_s}.yml"
19
+ raw = RestClient::Request.execute(method: 'GET', url: url,timeout: 10)
20
+ res = YAML::load(raw)
21
+ @data = res[:data] if res[:status] == :success
22
+ @command = params[:command].to_s
23
+ slim :command_history, :format => :html
24
+ end
25
+
26
+ WebAdminApp.get '/add_modify_command/?:command?' do
27
+ get_menu 2
28
+ log = get_logger
29
+ log.call "WEB : commands, verb : GET, controller : /add_modify_command/?:command?"
30
+ @data = {}
31
+ if params[:command] then
32
+ url = "http://#{get_config.webadmin_ip}:#{get_config.webadmin_port}/api/commands/show/#{params[:command].to_s}.yml"
33
+ raw = RestClient::Request.execute(method: 'GET', url: url,timeout: 10)
34
+ res = YAML::load(raw)
35
+ @data = res[:data] if res[:status] == :success
36
+ if @data[:retention].class == Hash then
37
+ prov = @data[:retention].flatten.reverse.join(' ')
38
+ @data[:retention] = prov
39
+ end
40
+ if @data[:schedule].class == Hash then
41
+ prov = @data[:schedule].flatten.join(' ')
42
+ @data[:schedule] = prov
43
+ end
44
+ if @data[:delegate_to].class == Hash then
45
+ prov = "#{@data[:delegate_to][:remote_command]}@#{@data[:delegate_to][:host]}"
46
+ @data[:delegate_to] = prov
47
+ end
48
+ @data[:old_command] = params[:command].to_s
49
+ end
50
+ slim :command_form, :format => :html
51
+ end
52
+
53
+
54
+ WebAdminApp.post '/save_command' do
55
+ get_menu 2
56
+ log = get_logger
57
+ log.call "WEB : commands, verb : POST, controller : /save_command"
58
+ data = {}
59
+ unless params[:retention].blank?
60
+ value, key = params[:retention].split(' ')
61
+ key = (key.nil?)? :days : key.to_sym
62
+ value = value.to_i
63
+ key = :days if key == :day
64
+ key = :hours if key == :hour
65
+ if [:hours,:days].include? key then
66
+ data[:retention] = {key => value}
67
+ end
68
+ end
69
+
70
+ unless params[:schedule].blank?
71
+ key, value = params[:schedule].split(' ')
72
+ key = key.to_sym unless key.nil?
73
+ value = '' if value.nil?
74
+ if [:in,:every,:at].include? key and value.match(/\d+[m,d,s,h]/) then
75
+ data[:schedule] = {key => value }
76
+ end
77
+ end
78
+
79
+ unless params[:delegate_to].blank?
80
+ key, value = params[:delegate_to].split('@')
81
+ unless key.blank? or value.blank? then
82
+ data[:delegate_to] = {:remote_command => key.to_sym, :host => value.to_sym }
83
+ end
84
+ end
85
+
86
+ data[:desc] = params[:desc]
87
+ data[:command] = params[:command] unless params[:command].blank?
88
+ data[:on_failure] = params[:on_failure].to_sym unless params[:on_failure].blank?
89
+ data[:on_success] = params[:on_success].to_sym unless params[:on_success].blank?
90
+ data[:user] = params[:user] unless params[:user].blank?
91
+ data[:name] = params[:name].split(' ').first.to_sym
92
+ puts params.to_yaml
93
+ puts data.to_yaml
94
+ redirect "/command/failure/#{params[:name].to_s}" if data[:command].blank? and data[:delegate_to].blank?
95
+ if params[:update] then
96
+ url = "http://#{get_config.webadmin_ip}:#{get_config.webadmin_port}/api/config/deletecommand/#{params[:old_command]}"
97
+ raw = RestClient::Request.execute(method: 'DELETE', url: url,timeout: 10)
98
+ end
99
+ url = "http://#{get_config.webadmin_ip}:#{get_config.webadmin_port}/api/config/addcommand.yml"
100
+ raw = RestClient::Request.execute(method: 'POST', url: url,timeout: 10, payload: data.to_yaml)
101
+ res = YAML::load(raw)
102
+ if res[:status] == :success then
103
+ redirect "/commands/success/#{params[:name].to_s}"
104
+ else
105
+ redirect "/commands/failure/#{params[:name].to_s}"
106
+ end
107
+ end
@@ -29,6 +29,10 @@ WebAdminApp.get '/add_modify_log/?:label?' do
29
29
  res = YAML::load(raw)
30
30
  @data = res[:data] if res[:status] == :success
31
31
  @data[:old_label] = params[:label].to_s
32
+ if @data[:retention].class == Hash then
33
+ prov = @data[:retention].flatten.reverse.join(' ')
34
+ @data[:retention] = prov
35
+ end
32
36
  end
33
37
  slim :log_form, :format => :html
34
38
  end
@@ -50,11 +54,21 @@ end
50
54
  WebAdminApp.post '/save_log' do
51
55
  get_menu 0
52
56
  log = get_logger
53
- log.call "WEB : logs, verb : POST, controller : /save_log/?:label?"
57
+ log.call "WEB : logs, verb : POST, controller : /save_log "
54
58
  data = {}
59
+ unless params[:retention].blank?
60
+ value, key = params[:retention].split(' ')
61
+ key = (key.nil?)? :days : key.to_sym
62
+ value = value.to_i
63
+ key = :days if key == :day
64
+ key = :hours if key == :hour
65
+ if [:hours,:days].include? key then
66
+ data[:retention] = {key => value}
67
+ end
68
+ end
55
69
  data[:log] = params[:log]
56
70
  data[:pattern] = params[:pattern]
57
- data[:label] = params[:label].to_sym
71
+ data[:label] = params[:label].split(' ').first.to_sym
58
72
  if params[:update] then
59
73
  url = "http://#{get_config.webadmin_ip}:#{get_config.webadmin_port}/api/config/deletelog/#{params[:old_label]}"
60
74
  raw = RestClient::Request.execute(method: 'DELETE', url: url,timeout: 10)
@@ -27,6 +27,10 @@ WebAdminApp.get '/add_modify_process/?:process?' do
27
27
  raw = RestClient::Request.execute(method: 'GET', url: url,timeout: 10)
28
28
  res = YAML::load(raw)
29
29
  @data = res[:data] if res[:status] == :success
30
+ if @data[:retention].class == Hash then
31
+ prov = @data[:retention].flatten.reverse.join(' ')
32
+ @data[:retention] = prov
33
+ end
30
34
  if @data[:patterns].class == Array then
31
35
  prov = @data[:patterns].join('|')
32
36
  @data[:patterns] = prov
@@ -53,10 +57,20 @@ end
53
57
  WebAdminApp.post '/save_process' do
54
58
  get_menu 1
55
59
  log = get_logger
56
- log.call "WEB : processes, verb : POST, controller : /save_process/?:process?"
60
+ log.call "WEB : processes, verb : POST, controller : /save_process"
57
61
  data = {}
58
62
  data[:patterns] = params[:patterns].split('|')
59
- data[:process] = params[:process].to_sym
63
+ data[:process] = params[:process].split(' ').first.to_sym
64
+ unless params[:retention].blank?
65
+ value, key = params[:retention].split(' ')
66
+ key = (key.nil?)? :days : key.to_sym
67
+ value = value.to_i
68
+ key = :days if key == :day
69
+ key = :hours if key == :hour
70
+ if [:hours,:days].include? key then
71
+ data[:retention] = {key => value}
72
+ end
73
+ end
60
74
  if params[:update] then
61
75
  url = "http://#{get_config.webadmin_ip}:#{get_config.webadmin_port}/api/config/deleteprocess/#{params[:old_process]}"
62
76
  raw = RestClient::Request.execute(method: 'DELETE', url: url,timeout: 10)
@@ -0,0 +1,45 @@
1
+ - unless @data.empty?
2
+ h2.uk-text-success <i class="uk-icon-#{@menu_icons[@current_item]} uk-icon-medium "></i>&nbsp;&nbsp;Modify Splash command definition : #{@data[:process]}
3
+ - else
4
+ h2.uk-text-success <i class="uk-icon-#{@menu_icons[@current_item]} uk-icon-medium "></i>&nbsp;&nbsp;Add new Splash command definition
5
+
6
+ script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-validate/1.19.2/jquery.validate.min.js"
7
+
8
+ form.uk-form.uk-form-horizontal#query action="/save_command" method="POST"
9
+ div.uk-text-bold Definition
10
+ label.uk-form-label for="name" Name
11
+ <input class="uk-form-width-large" id="name" type="text" placeholder="name" name="name" value="#{@data[:name].to_s}" required>
12
+ div &nbsp;
13
+ label.uk-form-label for="command" Command
14
+ <input class="uk-form-width-large" id="command" type="text" placeholder="command" name="command" value="#{@data[:command].to_s}">
15
+ div &nbsp;
16
+ label.uk-form-label for="desc" Description
17
+ <input class="uk-form-width-large" id="desc" type="text" placeholder="description" name="desc" value="#{@data[:desc]}" required>
18
+ div &nbsp;
19
+ label.uk-form-label for="desc" Become User
20
+ <input class="uk-form-width-large" id="user" type="text" placeholder="user" name="user" value="#{@data[:user]}">
21
+ div &nbsp;
22
+ label.uk-form-label for="retention" Retention (Like "2 hours, 2 days")
23
+ <input class="uk-form-width-large" id="retention" type="text" placeholder="retention" name="retention" value="#{@data[:retention]}">
24
+ div &nbsp;
25
+ label.uk-form-label for="schedule" Scheduling (Like "'every 10m', 'in 1h', 'at 12:00'")
26
+ <input class="uk-form-width-large" id="schedule" type="text" placeholder="scheduling" name="schedule" value="#{@data[:schedule]}">
27
+ div &nbsp;
28
+ label.uk-form-label for="delegate_to" Delegation (Like "task_name@hostname")
29
+ <input class="uk-form-width-large" id="delegate_to" type="text" placeholder="delegation" name="delegate_to" value="#{@data[:delegate_to]}">
30
+ div &nbsp;
31
+ div &nbsp;
32
+ div.uk-text-bold Callbacks
33
+ label.uk-form-label for="on_success" On success
34
+ <input class="uk-form-width-large" id="on_success" type="text" placeholder="on success" name="on_success" value="#{@data[:on_success]}">
35
+ div &nbsp;
36
+ label.uk-form-label for="on_success" On failure
37
+ <input class="uk-form-width-large" id="on_failure" type="text" placeholder="on failure" name="on_failure" value="#{@data[:on_failure]}">
38
+ div &nbsp;
39
+ - unless @data.empty?
40
+ input type="hidden" name="update" value="true"
41
+ input type="hidden" name="old_command" value="#{@data[:old_command].to_s}"
42
+ div.uk-align-right
43
+ input.uk-button.uk-button-small-primary type="submit" value="Submit"
44
+ javascript:
45
+ $("#query").validate();
@@ -0,0 +1,27 @@
1
+ h2.uk-text-success <i class="uk-icon-#{@menu_icons[@current_item]} uk-icon-medium "></i>&nbsp;&nbsp;History for command #{@command} executions and monitoring
2
+
3
+
4
+ -
5
+ div.uk-width-medium-1-1
6
+ div.uk-panel.uk-panel-box
7
+ span.uk-text-large.uk-text-bold List of records
8
+ br
9
+ table#logrecords.uk-table.uk-table-hover.uk-table-striped
10
+ thead
11
+ tr
12
+ th Start Date
13
+ th End Date
14
+ th Execution time (sec)
15
+ th Status
16
+ th STDOUT empty ?
17
+ th STDERR empty ?
18
+
19
+ tbody
20
+ - @data.reverse.each do |key|
21
+ tr class="#{(key[key.keys.first][:status].to_s.split.last == "0")? 'uk-text-success' : 'uk-text-danger'}"
22
+ td #{key.keys.first}
23
+ td #{key[key.keys.first][:end_date]}
24
+ td #{key[key.keys.first][:exec_time]}
25
+ td #{key[key.keys.first][:status].to_s}
26
+ td #{key[key.keys.first][:stdout].empty?}
27
+ td #{key[key.keys.first][:stderr].empty?}
@@ -1,14 +1,49 @@
1
1
  h2.uk-text-success <i class="uk-icon-#{@menu_icons[@current_item]} uk-icon-medium "></i>&nbsp;&nbsp;Commands configured in Splash
2
2
 
3
+ - unless @log_saved.nil?
4
+ javascript:
5
+ UIkit.notify("Command definition #{@command_saved} saved", {status:'success'});
6
+ - unless @log_failed.nil?
7
+ javascript:
8
+ UIkit.notify("Command definition #{@command_saved} not saved", {status:'danger'});
9
+
10
+ javascript:
11
+ $(document).on( 'click','input.delete-command',function(){
12
+ var id = this.id;
13
+ var url = "/api/config/deletecommand/" + id + ".json";
14
+ UIkit.modal.confirm('Are you sure?', function(){
15
+ console.debug(url)
16
+ $.ajax({
17
+ url: url,
18
+ type: 'DELETE',
19
+ success: function( data ) {
20
+ console.debug(data)
21
+ if (data['status'] == 'success') {
22
+ $('div#commandrecords h3#' + id).remove();
23
+ $('div#commandrecords div#' + id).remove();
24
+ UIkit.notify("Deleting log for " + id + " done", {status:'success'});
25
+ }
26
+ else
27
+ {
28
+ UIkit.notify("Deleting log for " + id + " failed !", {status:'danger'});
29
+ }
30
+ },
31
+ error: function(e) {
32
+ UIkit.notify("Deleting log for " + id + " failed !", {status:'danger'});
33
+ }
34
+ });
35
+ });
36
+ });
37
+
3
38
  div.uk-width-medium-1-1
4
39
  div.uk-panel.uk-panel-box
5
40
  span.uk-text-large.uk-text-bold List of commands availables
6
41
  br
7
42
 
8
- div.uk-accordion(data-uk-accordion)
9
- - @data.each do |command,content|
10
- h3.uk-accordion-title <b>Name</b> : #{command}
11
- div.uk-accordion-content
43
+ div#commandrecords.uk-accordion(data-uk-accordion)
44
+ - @data.reverse.each do |command|
45
+ h3.uk-accordion-title id="#{command[:name].to_s}" <i class="uk-icon-play-circle-o"></i>&nbsp;<b>Name</b> : #{command[:name]}
46
+ div.uk-accordion-content id="#{command[:name].to_s} "
12
47
  table.uk-table.uk-table-hover.uk-table-striped
13
48
  thead
14
49
  tr
@@ -19,31 +54,46 @@ div.uk-width-medium-1-1
19
54
  td
20
55
  dl.uk-description-list-horizontal
21
56
  dt <i class="uk-icon-th-list"></i>&nbsp;Description
22
- dd #{content[:desc]}
23
- - if content[:command]
57
+ dd #{command[:desc]}
58
+ - if command[:command]
24
59
  dt <i class="uk-icon-cog"></i>&nbsp;Command Line
25
- dd #{content[:command]}
26
- - if content[:schedule]
60
+ - if command[:delegate_to]
61
+ dd.uk-text-danger #{command[:command]} <i>(ignored because delegate_to is set)</i>
62
+ - else
63
+ dd #{command[:command]}
64
+ - if command[:schedule]
27
65
  dt <i class="uk-icon-calendar"></i>&nbsp;Schedule
28
66
  dd
29
67
  <ul>
30
- <li> <b><i>Type</b></i> : #{content[:schedule].keys.first}</li>
31
- <li> <b><i>Value</b></i> : #{content[:schedule].values.first}</li>
68
+ <li> <b><i>Type</b></i> : #{command[:schedule].keys.first}</li>
69
+ <li> <b><i>Value</b></i> : #{command[:schedule].values.first}</li>
32
70
  </ul>
33
- - if content[:on_success]
71
+ - if command[:on_success]
34
72
  dt <i class="uk-icon-check"></i>&nbsp;Execute on success
35
- dd #{content[:on_success]}
36
- - if content[:on_failure]
73
+ dd #{command[:on_success]}
74
+ - if command[:on_failure]
37
75
  dt <i class="uk-icon-bolt"></i>&nbsp;Execute on failure
38
- dd #{content[:on_failure]}
39
- - if content[:user]
76
+ dd #{command[:on_failure]}
77
+ - if command[:user]
40
78
  dt <i class="uk-icon-user"></i>&nbsp;become user
41
- dd #{content[:user]}
42
- - if content[:delegate_to]
79
+ dd #{command[:user]}
80
+ - if command[:delegate_to]
43
81
  dt <i class="uk-icon-chevron-circle-right"></i>&nbsp;Remote delegation
44
82
  dd
45
83
  <ul>
46
- <li> <i><b>Host</b></i> : #{content[:delegate_to][:host]}</li>
47
- <li> <b><i>Remote Command</b></i> : #{content[:delegate_to][:remote_command]}</li>
84
+ <li> <i><b>Host</b></i> : #{command[:delegate_to][:host]}</li>
85
+ <li> <b><i>Remote Command</b></i> : #{command[:delegate_to][:remote_command]}</li>
48
86
  </ul>
87
+ - if command[:retention].class == Hash
88
+ dt <i class="uk-icon-calendar-minus-o"></i>&nbsp;History retention
89
+ dd #{command[:retention].flatten.reverse.join(' ')}
49
90
  td
91
+ input.delete-command.uk-button.uk-button-mini.uk-button-danger id="#{command[:name].to_s}" value="Delete"
92
+ br
93
+ input.modify-process.uk-button.uk-button-mini.uk-button-primary id="#{command[:name].to_s}" value="Modify" onclick="location.href='/add_modify_command/#{command[:name].to_s}';"
94
+ br
95
+ input.history-command.uk-button.uk-button-mini.uk-button-primary id="#{command[:name].to_s}" value="History" onclick="location.href='/get_command_history/#{command[:name].to_s}';"
96
+ div.uk-align-right
97
+ form.uk-form.uk-form-horizontal#query action="/add_modify_command" method="GET"
98
+ div &nbsp;
99
+ input.add-process.uk-button type="submit" value="Add new process"
@@ -15,6 +15,9 @@ form.uk-form.uk-form-horizontal#query action="/save_log" method="POST"
15
15
  label.uk-form-label for="log" Log file
16
16
  <input class="uk-form-width-large" id="log" type="text" placeholder="log" name="log" value="#{@data[:log]}" required>
17
17
  div &nbsp;
18
+ label.uk-form-label for="retention" Retention (Like "2 hours, 2 days")
19
+ <input class="uk-form-width-large" id="retention" type="text" placeholder="retention" name="retention" value="#{@data[:retention]}">
20
+ div &nbsp;
18
21
  - unless @data.empty?
19
22
  input type="hidden" name="update" value="true"
20
23
  input type="hidden" name="old_label" value="#{@data[:old_label].to_s}"
@@ -15,8 +15,8 @@ div.uk-width-medium-1-1
15
15
  th Nb Errors
16
16
  th Full Nb of lines
17
17
  tbody
18
- - @data.each do |key|
19
- tr
18
+ - @data.reverse.each do |key|
19
+ tr class="#{(key[key.keys.first][:status] == :clean)? 'uk-text-success' : 'uk-text-danger'}"
20
20
  td #{key.keys.first}
21
21
  td #{key[key.keys.first][:file]}
22
22
  td #{key[key.keys.first][:status]}
@@ -74,23 +74,25 @@ div.uk-width-medium-1-1
74
74
  tbody
75
75
  - @data.each do |log|
76
76
  tr id="#{log[:label].to_s}"
77
- td <b>Label</b> : #{log[:label]}
77
+ td <i class="uk-icon-tag"></i>&nbsp;<b>Label</b> : #{log[:label]}
78
78
  td
79
79
  ul
80
- li <b>File</b> : #{log[:log]}
81
- li <b>Pattern</b> : #{log[:pattern]}
80
+ li <i class="uk-icon-file"></i>&nbsp;<b>File</b> : #{log[:log]}
81
+ li <i class="uk-icon-binoculars"></i>&nbsp;<b>Pattern</b> : #{log[:pattern]}
82
+ - if log[:retention].class == Hash
83
+ li <i class="uk-icon-calendar-minus-o"></i>&nbsp;<b>History retention</b> : #{log[:retention].flatten.reverse.join(' ')}
82
84
  td
83
85
  - if @result[log[:label]][:status] == :missing
84
86
  div.uk-badge.uk-badge-warning missing
85
87
  - if @result[log[:label]][:status] == :clean
86
88
  div.uk-badge.uk-badge-success success
87
89
  ul
88
- li <b>Lines count</b> : #{@result[log[:label]][:lines]}
90
+ li <i class="uk-icon-asterisk"></i>&nbsp;<b>Lines count</b> : #{@result[log[:label]][:lines]}
89
91
  - if @result[log[:label]][:status] == :matched
90
92
  div.uk-badge.uk-badge-danger matched
91
93
  ul
92
- li <b>Lines count</b> : #{@result[log[:label]][:lines]}
93
- li <b class="uk-text-danger">Matchs count : #{@result[log[:label]][:count]} </b>
94
+ li <i class="uk-icon-asterisk"></i>&nbsp;<b>Lines count</b> : #{@result[log[:label]][:lines]}
95
+ li <i class="uk-icon-bolt"></i>&nbsp;<b class="uk-text-danger">Matchs count : #{@result[log[:label]][:count]} </b>
94
96
  td
95
97
  input.delete-log.uk-button.uk-button-mini.uk-button-danger id="#{log[:label].to_s}" value="Delete"
96
98
  br
@@ -9,9 +9,12 @@ form.uk-form.uk-form-horizontal#query action="/save_process" method="POST"
9
9
  label.uk-form-label for="process" Process
10
10
  <input class="uk-form-width-large" id="process" type="text" placeholder="process" name="process" value="#{@data[:process].to_s}" required>
11
11
  div &nbsp;
12
- label.uk-form-label for="patterns" Patterns
12
+ label.uk-form-label for="patterns" Patterns (separator is "|")
13
13
  <input class="uk-form-width-large" id="patterns" type="text" placeholder="patterns" name="patterns" value="#{@data[:patterns]}" required>
14
14
  div &nbsp;
15
+ label.uk-form-label for="retention" Retention (Like "2 hours, 2 days")
16
+ <input class="uk-form-width-large" id="retention" type="text" placeholder="retention" name="retention" value="#{@data[:retention]}">
17
+ div &nbsp;
15
18
  - unless @data.empty?
16
19
  input type="hidden" name="update" value="true"
17
20
  input type="hidden" name="old_process" value="#{@data[:old_process].to_s}"
@@ -15,10 +15,10 @@ div.uk-width-medium-1-1
15
15
  th % CPU
16
16
  th % MEM
17
17
  tbody
18
- - @data.each do |key|
19
- tr
18
+ - @data.reverse.each do |key|
19
+ tr class="#{(key[key.keys.first][:status] == :running)? 'uk-text-success' : 'uk-text-danger'}"
20
20
  td #{key.keys.first}
21
21
  td #{key[key.keys.first][:process]}
22
22
  td #{key[key.keys.first][:status]}
23
- td #{key[key.keys.first][:cpu]}
24
- td #{key[key.keys.first][:mem]}
23
+ td #{key[key.keys.first][:cpu_percent]}
24
+ td #{key[key.keys.first][:mem_percent]}
@@ -72,20 +72,23 @@ div.uk-width-medium-1-1
72
72
  tbody
73
73
  - @data.each do |process|
74
74
  tr id="#{process[:process].to_s}"
75
- td <b>Process</b> : #{process[:process]}
75
+ td <i class="uk-icon-cog"></i>&nbsp;<b>Process</b> : #{process[:process]}
76
76
  td
77
- span.uk-text-bold Patterns
77
+ - if process[:retention].class == Hash
78
+ div <i class="uk-icon-calendar-minus-o"></i>&nbsp;<b>History retention</b> : #{process[:retention].flatten.reverse.join(' ')}
79
+ span.uk-text-bold <i class="uk-icon-binoculars"></i>&nbsp; Patterns
78
80
  ul
79
81
  - process[:patterns].each do |pattern|
80
82
  li= pattern
83
+
81
84
  td
82
85
  - if @result[process[:process]][:status] == :inexistant
83
86
  div.uk-badge.uk-badge-danger not running
84
87
  - if @result[process[:process]][:status] == :running
85
88
  div.uk-badge.uk-badge-success running
86
89
  ul
87
- li <b>CPU usage</b> : #{@result[process[:process]][:cpu]}
88
- li <b>MEM usage</b> : #{@result[process[:process]][:mem]}
90
+ li <i class="uk-icon-percent"></i>&nbsp;<b>CPU usage</b> : #{@result[process[:process]][:cpu]}
91
+ li <i class="uk-icon-percent"></i>&nbsp;<b>MEM usage</b> : #{@result[process[:process]][:mem]}
89
92
  td
90
93
  input.delete-process.uk-button.uk-button-mini.uk-button-danger id="#{process[:process].to_s}" value="Delete"
91
94
  br
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: prometheus-splash
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.8.4
4
+ version: 0.8.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Romain GEORGES
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-11-02 00:00:00.000000000 Z
11
+ date: 2020-11-06 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: thor
@@ -431,6 +431,7 @@ files:
431
431
  - lib/splash/loggers/dual.rb
432
432
  - lib/splash/loggers/web.rb
433
433
  - lib/splash/logs.rb
434
+ - lib/splash/monkeys.rb
434
435
  - lib/splash/processes.rb
435
436
  - lib/splash/sequences.rb
436
437
  - lib/splash/templates.rb
@@ -464,6 +465,8 @@ files:
464
465
  - lib/splash/webadmin/portal/public/images/logo_splash.png
465
466
  - lib/splash/webadmin/portal/public/images/logo_splash_reduce.png
466
467
  - lib/splash/webadmin/portal/public/images/logo_splash_tiny.png
468
+ - lib/splash/webadmin/portal/views/command_form.slim
469
+ - lib/splash/webadmin/portal/views/command_history.slim
467
470
  - lib/splash/webadmin/portal/views/commands.slim
468
471
  - lib/splash/webadmin/portal/views/documentation.slim
469
472
  - lib/splash/webadmin/portal/views/home.slim