prometheus-splash 0.8.4 → 0.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +9 -0
- data/README.md +1 -1
- data/config/splash.yml +14 -12
- data/lib/splash/cli/commands.rb +23 -22
- data/lib/splash/cli/daemon.rb +1 -1
- data/lib/splash/cli/webadmin.rb +2 -1
- data/lib/splash/commands.rb +31 -22
- data/lib/splash/config.rb +6 -2
- data/lib/splash/constants.rb +1 -1
- data/lib/splash/daemon/orchestrator/grammar.rb +1 -1
- data/lib/splash/daemon/orchestrator.rb +8 -9
- data/lib/splash/dependencies.rb +1 -0
- data/lib/splash/helpers.rb +1 -1
- data/lib/splash/monkeys.rb +5 -0
- data/lib/splash/sequences.rb +6 -1
- data/lib/splash/webadmin/api/routes/commands.rb +13 -1
- data/lib/splash/webadmin/api/routes/config.rb +45 -0
- data/lib/splash/webadmin/main.rb +13 -1
- data/lib/splash/webadmin/portal/controllers/commands.rb +99 -1
- data/lib/splash/webadmin/portal/controllers/logs.rb +16 -2
- data/lib/splash/webadmin/portal/controllers/processes.rb +16 -2
- data/lib/splash/webadmin/portal/views/command_form.slim +45 -0
- data/lib/splash/webadmin/portal/views/command_history.slim +27 -0
- data/lib/splash/webadmin/portal/views/commands.slim +69 -19
- data/lib/splash/webadmin/portal/views/log_form.slim +3 -0
- data/lib/splash/webadmin/portal/views/log_history.slim +2 -2
- data/lib/splash/webadmin/portal/views/logs.slim +8 -6
- data/lib/splash/webadmin/portal/views/process_form.slim +4 -1
- data/lib/splash/webadmin/portal/views/process_history.slim +4 -4
- data/lib/splash/webadmin/portal/views/processes.slim +7 -4
- data/lib/splash/webadmin.rb +3 -1
- data/templates/.env +0 -0
- data/templates/Dockerfile +5 -0
- data/templates/docker-compose.yml +14 -0
- metadata +11 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 13eaca07cd4d8de11c4eb5b54798a59d2a16d2b258eab9e800405b9333b7caba
|
4
|
+
data.tar.gz: 00170e2f5a7e8b51ec9b4b638e75ed8a5dd53ba6f5a644a752f83f0c0eb77179
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 848fcec8f9d390cbd59fdd5104d32667fe03a581ee6597de6bcdd64dc923863d1a821ec417285816bcf093a955b668fa563934b599691292eceee9bfa8e3affa
|
7
|
+
data.tar.gz: 5541a02ed39ae1a86e1602886a9a0eb1590d6bae431517fd8d0a2b91ce1a62092dd641f0dac8a6d496b5b46490cf176cb2cb7707c997b1e671ca40ae55984109
|
data/CHANGELOG.md
CHANGED
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.
|
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
|
|
data/config/splash.yml
CHANGED
@@ -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: "
|
118
|
-
|
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:
|
data/lib/splash/cli/commands.rb
CHANGED
@@ -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.
|
215
|
-
list.
|
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 : '#{
|
219
|
-
log.arrow "command description : '#{
|
220
|
-
log.arrow "command failure callback : '#{
|
221
|
-
log.arrow "command success callback : '#{
|
222
|
-
if
|
223
|
-
sched,val =
|
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(
|
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
|
-
|
265
|
-
|
266
|
-
log.
|
267
|
-
log.item "command
|
268
|
-
log.item "command
|
269
|
-
log.item "command
|
270
|
-
if
|
271
|
-
|
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[:
|
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
|
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.
|
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]
|
data/lib/splash/cli/daemon.rb
CHANGED
@@ -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 "
|
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"
|
data/lib/splash/cli/webadmin.rb
CHANGED
@@ -35,9 +35,10 @@ module CLISplash
|
|
35
35
|
long_desc <<-LONGDESC
|
36
36
|
Starting Splash Daemon\n
|
37
37
|
LONGDESC
|
38
|
+
option :foreground, :type => :boolean, :aliases => "-F"
|
38
39
|
desc "start", "Splash WebAdmin Daemon status"
|
39
40
|
def start
|
40
|
-
acase = run_as_root :startweb
|
41
|
+
acase = run_as_root :startweb, options
|
41
42
|
splash_exit acase
|
42
43
|
end
|
43
44
|
|
data/lib/splash/commands.rb
CHANGED
@@ -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.
|
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
|
-
|
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 : #{
|
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 =>
|
158
|
+
payload: {:name => command[:delegate_to][:remote_command].to_s},
|
152
159
|
:return_to => "splash.#{Socket.gethostname}.return",
|
153
|
-
:queue => "splash.#{
|
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
|
168
|
-
log.item "Execute with user : #{
|
169
|
-
system("sudo -u #{
|
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("#{
|
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
|
178
|
-
log.item "Execute with user : #{
|
179
|
-
stdout, stderr, status = Open3.capture3("sudo -u #{
|
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(
|
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] =
|
189
|
-
data[: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(
|
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 = (
|
209
|
-
on_success = (
|
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.
|
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
|
-
|
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.
|
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
|
-
|
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
|
data/lib/splash/config.rb
CHANGED
@@ -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 ={})
|
data/lib/splash/constants.rb
CHANGED
@@ -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.
|
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
|
@@ -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
|
@@ -100,9 +100,9 @@ module Splash
|
|
100
100
|
else
|
101
101
|
sched,value = @config.daemon_procmon_scheduling.flatten
|
102
102
|
@log.item "Initializing logs monitorings & notifications."
|
103
|
-
@log_result = LogScanner::new
|
104
103
|
@server.send sched,value do
|
105
104
|
begin
|
105
|
+
@log_result = LogScanner::new
|
106
106
|
session = get_session
|
107
107
|
@metric_manager.inc_logs_monitoring
|
108
108
|
@log.trigger "Logs monitoring for Scheduling : #{sched.to_s} #{value.to_s}", session
|
@@ -122,9 +122,9 @@ module Splash
|
|
122
122
|
else
|
123
123
|
sched,value = @config.daemon_logmon_scheduling.flatten
|
124
124
|
@log.item "Initializing processes monitorings & notifications."
|
125
|
-
@process_result = ProcessScanner::new
|
126
125
|
@server.send sched,value do
|
127
126
|
begin
|
127
|
+
@process_result = ProcessScanner::new
|
128
128
|
session = get_session
|
129
129
|
@metric_manager.inc_processes_monitoring
|
130
130
|
@log.trigger "Processes monitoring for Scheduling : #{sched.to_s} #{value.to_s}", session
|
@@ -155,15 +155,14 @@ module Splash
|
|
155
155
|
|
156
156
|
# prepare commands Scheduling
|
157
157
|
def init_commands_scheduling
|
158
|
-
|
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 =
|
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
|
data/lib/splash/dependencies.rb
CHANGED
data/lib/splash/helpers.rb
CHANGED
@@ -358,7 +358,7 @@ module Splash
|
|
358
358
|
# @return [Boolean]
|
359
359
|
def check_unicode_term
|
360
360
|
return false unless ENV.include? "TERM"
|
361
|
-
if ENV.values_at("LC_ALL","LC_CTYPE","LANG").compact.
|
361
|
+
if ENV.values_at("LC_ALL","LC_CTYPE","LANG").compact.include?("UTF-8") and ENV.values_at('TERM').include? "xterm" then
|
362
362
|
return true
|
363
363
|
else
|
364
364
|
return false
|
data/lib/splash/sequences.rb
CHANGED
@@ -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
|
-
|
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
|
data/lib/splash/webadmin/main.rb
CHANGED
@@ -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
|
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
|
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> 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> 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
|
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
|
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
|
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
|
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
|
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
|
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
|
31
|
+
div
|
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
|
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
|
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> 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> 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
|
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> <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> Description
|
22
|
-
dd #{
|
23
|
-
- if
|
57
|
+
dd #{command[:desc]}
|
58
|
+
- if command[:command]
|
24
59
|
dt <i class="uk-icon-cog"></i> Command Line
|
25
|
-
|
26
|
-
|
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> Schedule
|
28
66
|
dd
|
29
67
|
<ul>
|
30
|
-
<li> <b><i>Type</b></i> : #{
|
31
|
-
<li> <b><i>Value</b></i> : #{
|
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
|
71
|
+
- if command[:on_success]
|
34
72
|
dt <i class="uk-icon-check"></i> Execute on success
|
35
|
-
dd #{
|
36
|
-
- if
|
73
|
+
dd #{command[:on_success]}
|
74
|
+
- if command[:on_failure]
|
37
75
|
dt <i class="uk-icon-bolt"></i> Execute on failure
|
38
|
-
dd #{
|
39
|
-
- if
|
76
|
+
dd #{command[:on_failure]}
|
77
|
+
- if command[:user]
|
40
78
|
dt <i class="uk-icon-user"></i> become user
|
41
|
-
dd #{
|
42
|
-
- if
|
79
|
+
dd #{command[:user]}
|
80
|
+
- if command[:delegate_to]
|
43
81
|
dt <i class="uk-icon-chevron-circle-right"></i> Remote delegation
|
44
82
|
dd
|
45
83
|
<ul>
|
46
|
-
<li> <i><b>Host</b></i> : #{
|
47
|
-
<li> <b><i>Remote Command</b></i> : #{
|
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> 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
|
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
|
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
|
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> <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> <b>File</b> : #{log[:log]}
|
81
|
+
li <i class="uk-icon-binoculars"></i> <b>Pattern</b> : #{log[:pattern]}
|
82
|
+
- if log[:retention].class == Hash
|
83
|
+
li <i class="uk-icon-calendar-minus-o"></i> <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> <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> <b>Lines count</b> : #{@result[log[:label]][:lines]}
|
95
|
+
li <i class="uk-icon-bolt"></i> <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
|
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
|
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
|
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][:
|
24
|
-
td #{key[key.keys.first][:
|
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> <b>Process</b> : #{process[:process]}
|
76
76
|
td
|
77
|
-
|
77
|
+
- if process[:retention].class == Hash
|
78
|
+
div <i class="uk-icon-calendar-minus-o"></i> <b>History retention</b> : #{process[:retention].flatten.reverse.join(' ')}
|
79
|
+
span.uk-text-bold <i class="uk-icon-binoculars"></i> 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> <b>CPU usage</b> : #{@result[process[:process]][:cpu]}
|
91
|
+
li <i class="uk-icon-percent"></i> <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
|
data/lib/splash/webadmin.rb
CHANGED
@@ -20,6 +20,7 @@ module Splash
|
|
20
20
|
# Start the Splash Daemon
|
21
21
|
# @param [Hash] options
|
22
22
|
# @option options [Symbol] :quiet activate quiet mode for log (limit to :fatal)
|
23
|
+
# @option options [Symbol] :foreground run webadmin in foreground
|
23
24
|
# @return [Hash] Exiter Case (:quiet_exit, :already_exist, :unknown_error or other)
|
24
25
|
def startweb(options = {})
|
25
26
|
require 'splash/webadmin/main'
|
@@ -37,7 +38,8 @@ module Splash
|
|
37
38
|
daemon_config = {:description => config.webadmin_process_name,
|
38
39
|
:pid_file => config.webadmin_full_pid_path,
|
39
40
|
:stdout_trace => config.webadmin_full_stdout_trace_path,
|
40
|
-
:stderr_trace => config.webadmin_full_stderr_trace_path
|
41
|
+
:stderr_trace => config.webadmin_full_stderr_trace_path,
|
42
|
+
:foreground => options[:foreground]
|
41
43
|
}
|
42
44
|
|
43
45
|
["int","term","hup"].each do |type| daemon_config["sig#{type}_handler".to_sym] = Proc::new { WebAdminApp.quit! } end
|
data/templates/.env
ADDED
File without changes
|
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.
|
4
|
+
version: 0.9.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Romain GEORGES
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2022-05-04 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
|
@@ -483,6 +486,8 @@ files:
|
|
483
486
|
- prometheus-splash.gemspec
|
484
487
|
- spec/helpers_spec.rb
|
485
488
|
- spec/templates_spec.rb
|
489
|
+
- templates/.env
|
490
|
+
- templates/Dockerfile
|
486
491
|
- templates/ansible-splash/Vagrantfile
|
487
492
|
- templates/ansible-splash/deploy.yml
|
488
493
|
- templates/ansible-splash/group_vars/DEV.yml
|
@@ -505,6 +510,7 @@ files:
|
|
505
510
|
- templates/ansible-splash/roles/supervision_master/tasks/main.yml
|
506
511
|
- templates/ansible-splash/roles/supervision_master/templates/alertmanager.yml.j2
|
507
512
|
- templates/ansible-splash/roles/supervision_master/templates/prometheus.yml.j2
|
513
|
+
- templates/docker-compose.yml
|
508
514
|
- templates/report.txt
|
509
515
|
- templates/splashd.service
|
510
516
|
- test.sh
|
@@ -513,7 +519,7 @@ homepage: https://github.com/Ultragreen/prometheus-splash
|
|
513
519
|
licenses:
|
514
520
|
- BSD-2-Clause
|
515
521
|
metadata: {}
|
516
|
-
post_install_message:
|
522
|
+
post_install_message:
|
517
523
|
rdoc_options: []
|
518
524
|
require_paths:
|
519
525
|
- lib
|
@@ -529,7 +535,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
529
535
|
version: '0'
|
530
536
|
requirements: []
|
531
537
|
rubygems_version: 3.1.2
|
532
|
-
signing_key:
|
538
|
+
signing_key:
|
533
539
|
specification_version: 4
|
534
540
|
summary: Supervision with Prometheus of Logs and Asynchronous tasks orchestration
|
535
541
|
for Services or Hosts
|