prometheus-splash 0.0.1 → 0.0.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Rakefile +7 -1
- data/bin/splash +96 -18
- data/config/splash.yml +23 -0
- data/lib/splash/commands.rb +79 -0
- data/lib/splash/config.rb +87 -7
- data/lib/splash/constants.rb +5 -1
- data/lib/splash/controller.rb +69 -13
- data/lib/splash/helpers.rb +39 -7
- data/lib/splash/templates.rb +68 -0
- data/{splash.gemspec → prometheus-splash.gemspec} +0 -0
- data/templates/report.txt +19 -0
- metadata +5 -3
- data/lib/splash/command.rb +0 -29
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1e6fae61b205672ab555b7cd28f0c0bfc0c48bacbaa81f9696a7ce16ef9eaa2e
|
4
|
+
data.tar.gz: e9167d60ea4537298014c7af7ee5214ff124d66b1b880925b18069e3a2e5db88
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 5b7e241e27d99e1ca480d387a1c87a86583113d2393756200dc1b167b069b7c24253c911a6dfd05c352f821c3d5e4c691a74a2ace2611f6adf08c545d76019aa
|
7
|
+
data.tar.gz: 6c5c3579c210e000bdac1f9220b0b89d5bb6e0f1997ea48061d7fe8734546689f18b22fa5d083c4a3fb36e6333b7cdf05637f3dd4c4b5d62ed0988050d758b26
|
data/Rakefile
CHANGED
@@ -24,7 +24,7 @@ CLEAN.include('*.tmp','*.old')
|
|
24
24
|
CLOBBER.include('*.tmp', 'build/*','#*#')
|
25
25
|
|
26
26
|
|
27
|
-
content = File::readlines(File.join(File.dirname(__FILE__), 'splash.gemspec')).join
|
27
|
+
content = File::readlines(File.join(File.dirname(__FILE__), 'prometheus-splash.gemspec')).join
|
28
28
|
spec = eval(content)
|
29
29
|
|
30
30
|
RSpec::Core::RakeTask.new('spec')
|
@@ -59,3 +59,9 @@ Rake::RDocTask.new('rdoc') do |d|
|
|
59
59
|
end
|
60
60
|
|
61
61
|
task :default => [:gem]
|
62
|
+
|
63
|
+
task :stage do
|
64
|
+
Rake::Task["clean"].invoke
|
65
|
+
Rake::Task["clobber"].invoke
|
66
|
+
Rake::Task["install"].invoke
|
67
|
+
end
|
data/bin/splash
CHANGED
@@ -1,9 +1,9 @@
|
|
1
1
|
#!/usr/bin/env ruby -W:no-deprecated
|
2
2
|
|
3
|
-
require 'prometheus/client'
|
4
|
-
require 'prometheus/client/push'
|
5
3
|
|
6
4
|
begin
|
5
|
+
require 'prometheus/client'
|
6
|
+
require 'prometheus/client/push'
|
7
7
|
require 'thor'
|
8
8
|
rescue Gem::GemNotFoundException
|
9
9
|
$stderr.puts "Loadind error, it's like you try to run Splash, with a lake of dependencies."
|
@@ -16,8 +16,9 @@ require 'yaml'
|
|
16
16
|
require 'splash/constants'
|
17
17
|
require 'splash/helpers'
|
18
18
|
require 'splash/config'
|
19
|
+
require 'splash/templates'
|
19
20
|
|
20
|
-
require 'splash/
|
21
|
+
require 'splash/commands'
|
21
22
|
require 'splash/logs'
|
22
23
|
require 'splash/controller'
|
23
24
|
|
@@ -30,14 +31,79 @@ module CLISplash
|
|
30
31
|
|
31
32
|
|
32
33
|
class Commands < Thor
|
34
|
+
include Splash::Config
|
33
35
|
|
34
|
-
option :ack, :type => :boolean
|
35
36
|
desc "wrap NAME", "wrapping for command or ack result"
|
37
|
+
long_desc <<-LONGDESC
|
38
|
+
wrapping for command or ack result
|
39
|
+
with --no-trace prevent storing execution trace in TRACE_PATH (see config file)
|
40
|
+
with --ack, notify errorcode=0 to Prometheus PushGateway
|
41
|
+
LONGDESC
|
42
|
+
option :trace, :type => :boolean, :default => true
|
43
|
+
option :ack, :type => :boolean, negate: false
|
36
44
|
def wrap(name)
|
37
|
-
|
38
|
-
|
39
|
-
|
45
|
+
if is_root? then
|
46
|
+
command = Splash::CommandWrapper::new(name)
|
47
|
+
command.ack if options[:ack]
|
48
|
+
command.call_and_notify trace: options[:trace]
|
49
|
+
else
|
50
|
+
$stderr.puts "Command wrapping need to be run as root"
|
51
|
+
exit 60
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
|
56
|
+
desc "list", "Show configured commands"
|
57
|
+
long_desc <<-LONGDESC
|
58
|
+
Show configured commands
|
59
|
+
with --detail, show command details
|
60
|
+
LONGDESC
|
61
|
+
option :detail, :type => :boolean
|
62
|
+
def list
|
63
|
+
puts "Splash configured commands :"
|
64
|
+
list = get_config.commands
|
65
|
+
puts 'No configured commands found' if list.keys.empty?
|
66
|
+
listc.keys.each do |command|
|
67
|
+
puts " * #{command.to_s}"
|
68
|
+
if options[:detail] then
|
69
|
+
puts " - command line : '#{list[command][:command]}'"
|
70
|
+
puts " - command description : '#{list[command][:desc]}'"
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
|
76
|
+
desc "show COMMAND", "Show specific configured command COMMAND"
|
77
|
+
def show(command)
|
78
|
+
list = get_config.commands
|
79
|
+
if list.keys.include? command.to_sym then
|
80
|
+
puts "Splash command : #{command}"
|
81
|
+
puts " - command line : '#{list[command.to_sym][:command]}'"
|
82
|
+
puts " - command description : '#{list[command.to_sym][:desc]}'"
|
83
|
+
else
|
84
|
+
$stderr.puts "Command not configured"
|
85
|
+
exit 50
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
|
90
|
+
desc "lastrun COMMAND", "Show last running result for specific configured command COMMAND"
|
91
|
+
def lastrun(command)
|
92
|
+
list = get_config.commands
|
93
|
+
if list.keys.include? command.to_sym then
|
94
|
+
print "Splash command #{command} previous execution report:\n\n"
|
95
|
+
filename = "#{get_config[:trace_path]}/#{command}_trace.last"
|
96
|
+
if File::exist? filename then
|
97
|
+
system("cat #{filename}")
|
98
|
+
else
|
99
|
+
puts "Command not already runned."
|
100
|
+
end
|
101
|
+
else
|
102
|
+
$stderr.puts "Command not configured"
|
103
|
+
exit 50
|
104
|
+
end
|
40
105
|
end
|
106
|
+
|
41
107
|
end
|
42
108
|
|
43
109
|
|
@@ -47,37 +113,49 @@ module CLISplash
|
|
47
113
|
option :foreground, :type => :boolean
|
48
114
|
desc "start", "Starting Logs Monitor Daemon"
|
49
115
|
def start
|
50
|
-
run_as_root :startdaemon
|
116
|
+
errorcode = run_as_root :startdaemon
|
117
|
+
exit errorcode
|
51
118
|
end
|
52
119
|
|
53
120
|
desc "stop", "Stopping Logs Monitor Daemon"
|
54
121
|
def stop
|
55
|
-
run_as_root :stopdaemon
|
122
|
+
errorcode = run_as_root :stopdaemon
|
123
|
+
exit errorcode
|
124
|
+
end
|
125
|
+
|
126
|
+
desc "status", "Logs Monitor Daemon status"
|
127
|
+
def status
|
128
|
+
errorcode = run_as_root :statusdaemon
|
129
|
+
exit errorcode
|
56
130
|
end
|
57
131
|
|
58
132
|
|
59
133
|
end
|
60
134
|
|
135
|
+
|
136
|
+
|
137
|
+
|
61
138
|
class Config < Thor
|
62
139
|
include Splash::Config
|
63
140
|
include Splash::Helpers
|
64
141
|
|
65
142
|
desc "setup", "Setup installation fo Splash"
|
66
143
|
def setup
|
67
|
-
run_as_root :setupsplash
|
68
|
-
|
144
|
+
errorcode = run_as_root :setupsplash
|
145
|
+
exit errorcode
|
69
146
|
end
|
70
147
|
|
71
148
|
desc "sanitycheck", "Verify installation fo Splash"
|
72
149
|
def sanitycheck
|
73
|
-
run_as_root :checkconfig
|
150
|
+
errorcode = run_as_root :checkconfig
|
151
|
+
exit errorcode
|
74
152
|
end
|
75
153
|
|
76
154
|
desc "version", "display current Splash version"
|
77
155
|
def version
|
78
|
-
|
79
|
-
|
80
|
-
|
156
|
+
config = get_config
|
157
|
+
puts "Splash version : #{config.version}, Author : #{config.author}"
|
158
|
+
puts config.copyright
|
81
159
|
end
|
82
160
|
|
83
161
|
|
@@ -105,9 +183,9 @@ module CLISplash
|
|
105
183
|
end
|
106
184
|
|
107
185
|
class CLI < Thor
|
108
|
-
|
109
|
-
|
110
|
-
|
186
|
+
def self.exit_on_failure?
|
187
|
+
true
|
188
|
+
end
|
111
189
|
|
112
190
|
include CLISplash
|
113
191
|
desc "commands SUBCOMMAND ...ARGS", "Managing commands/batchs supervision"
|
data/config/splash.yml
CHANGED
@@ -1,9 +1,32 @@
|
|
1
1
|
:splash:
|
2
|
+
:templates:
|
3
|
+
:execution:
|
4
|
+
:path: /etc/splash_execution_report.tpl
|
5
|
+
:tokens:
|
6
|
+
- :date
|
7
|
+
- :cmd_name
|
8
|
+
- :cmd_line
|
9
|
+
- :stdout
|
10
|
+
- :stderr
|
11
|
+
- :desc
|
12
|
+
- :status
|
2
13
|
:logs:
|
3
14
|
- :log: /tmp/test
|
4
15
|
:pattern: ERROR
|
5
16
|
- :log: /var/log/message
|
6
17
|
:pattern: error
|
18
|
+
:prometheus:
|
19
|
+
:pushgateway:
|
20
|
+
:host: "localhost"
|
21
|
+
:port: 9091
|
22
|
+
:commands:
|
23
|
+
:false_test:
|
24
|
+
:desc: "test command"
|
25
|
+
:command: "false"
|
26
|
+
:ls_slash_tmp:
|
27
|
+
:desc: list file in /tmp
|
28
|
+
:command: ls -al /tmp
|
29
|
+
:user: daemon
|
7
30
|
:daemon:
|
8
31
|
:user: daemon
|
9
32
|
:group: daemon
|
@@ -0,0 +1,79 @@
|
|
1
|
+
require 'open3'
|
2
|
+
require 'date'
|
3
|
+
|
4
|
+
|
5
|
+
module Splash
|
6
|
+
class CommandWrapper
|
7
|
+
include Splash::Templates
|
8
|
+
include Splash::Config
|
9
|
+
include Splash::Helpers
|
10
|
+
|
11
|
+
def initialize(name)
|
12
|
+
@config = get_config
|
13
|
+
@name = name
|
14
|
+
unless @config.commands.keys.include? @name.to_sym then
|
15
|
+
$stderr.puts "Splash : command #{@name} is not defined in configuration"
|
16
|
+
exit 40
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def ack
|
21
|
+
puts "Sending ack for command : '#{@name}'"
|
22
|
+
notify(0)
|
23
|
+
exit 0
|
24
|
+
end
|
25
|
+
|
26
|
+
def notify(value)
|
27
|
+
unless verify_service host: @config.prometheus_pushgateway_host ,port: @config.prometheus_pushgateway_port then
|
28
|
+
$stderr.puts "Prometheus PushGateway Service IS NOT running"
|
29
|
+
$stderr.puts "Exit without notification."
|
30
|
+
exit 30
|
31
|
+
end
|
32
|
+
registry = Prometheus::Client.registry
|
33
|
+
url = "http://#{@config.prometheus_pushgateway_host}:#{@config.prometheus_pushgateway_port}"
|
34
|
+
metric = Prometheus::Client::Gauge.new(:errorcode, docstring: 'SPLASH metric batch errorcode')
|
35
|
+
registry.register(metric)
|
36
|
+
metric.set(value)
|
37
|
+
Prometheus::Client::Push.new(@name, nil, url).add(registry)
|
38
|
+
puts "Prometheus Gateway notified."
|
39
|
+
end
|
40
|
+
|
41
|
+
|
42
|
+
def call_and_notify(options)
|
43
|
+
puts "Executing command : '#{@name}' "
|
44
|
+
unless options[:trace] then
|
45
|
+
puts "Traceless execution"
|
46
|
+
if @config.commands[@name.to_sym][:user] then
|
47
|
+
system("sudo -u #{@config.commands[@name.to_sym][:user]} #{@config.commands[@name.to_sym][:command]} > /dev/null 2>&1")
|
48
|
+
else
|
49
|
+
system("#{@config.commands[@name.to_sym][:command]} > /dev/null 2>&1")
|
50
|
+
end
|
51
|
+
exit_code = $?.exitstatus
|
52
|
+
else
|
53
|
+
puts "Tracefull execution"
|
54
|
+
if @config.commands[@name.to_sym][:user] then
|
55
|
+
stdout, stderr, status = Open3.capture3("sudo -u #{@config.commands[@name.to_sym][:user]} #{@config.commands[@name.to_sym][:command]}")
|
56
|
+
else
|
57
|
+
stdout, stderr, status = Open3.capture3(@config.commands[@name.to_sym][:command])
|
58
|
+
end
|
59
|
+
tp = Template::new(
|
60
|
+
list_token: @config.execution_template_tokens,
|
61
|
+
template_file: @config.execution_template_path)
|
62
|
+
|
63
|
+
tp.date = DateTime.now.to_s
|
64
|
+
tp.cmd_name = @name
|
65
|
+
tp.cmd_line = @config.commands[@name.to_sym][:command]
|
66
|
+
tp.desc = @config.commands[@name.to_sym][:desc]
|
67
|
+
tp.status = status.to_s
|
68
|
+
tp.stdout = stdout
|
69
|
+
tp.stderr = stderr
|
70
|
+
filename = "#{@config[:trace_path]}/#{@name}_trace.last"
|
71
|
+
File.open(filename, 'w') { |file| file.write(tp.output) }
|
72
|
+
exit_code = status.exitstatus
|
73
|
+
end
|
74
|
+
|
75
|
+
notify(exit_code)
|
76
|
+
exit exit_code
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
data/lib/splash/config.rb
CHANGED
@@ -12,8 +12,12 @@ module Splash
|
|
12
12
|
self[:version] = VERSION
|
13
13
|
self[:author] = "#{AUTHOR} <#{EMAIL}>"
|
14
14
|
self[:copyright] = "#{COPYRIGHT} #{LICENSE}"
|
15
|
+
self[:prometheus_pushgateway_host] = (config_from_file[:prometheus][:pushgateway][:host])? config_from_file[:prometheus][:pushgateway][:host] : PROMETHEUS_PUSHGATEWAY_HOST
|
16
|
+
self[:prometheus_pushgateway_port] = (config_from_file[:prometheus][:pushgateway][:port])? config_from_file[:prometheus][:pushgateway][:port] : PROMETHEUS_PUSHGATEWAY_PORT
|
15
17
|
self[:daemon_process_name] = (config_from_file[:daemon][:process_name])? config_from_file[:daemon][:process_name] : DAEMON_PROCESS_NAME
|
16
18
|
self[:daemon_user] = (config_from_file[:daemon][:user])? config_from_file[:daemon][:user] : DAEMON_USER
|
19
|
+
self[:execution_template_tokens] = (config_from_file[:templates][:execution][:tokens])? config_from_file[:templates][:execution][:tokens] : TOKENS_LIST
|
20
|
+
self[:execution_template_path] = (config_from_file[:templates][:execution][:path])? config_from_file[:templates][:execution][:path] : EXECUTION_TEMPLATE
|
17
21
|
self[:daemon_group] = (config_from_file[:daemon][:group])? config_from_file[:daemon][:group] : DAEMON_GROUP
|
18
22
|
self[:pid_path] = (config_from_file[:daemon][:paths][:pid_path])? config_from_file[:daemon][:paths][:pid_path] : PID_PATH
|
19
23
|
self[:trace_path] = (config_from_file[:daemon][:paths][:trace_path])? config_from_file[:daemon][:paths][:trace_path] : TRACE_PATH
|
@@ -21,12 +25,25 @@ module Splash
|
|
21
25
|
self[:stdout_trace] = (config_from_file[:daemon][:files][:stdout_trace])? config_from_file[:daemon][:files][:stdout_trace] : STDOUT_TRACE
|
22
26
|
self[:stderr_trace] = (config_from_file[:daemon][:files][:stderr_trace])? config_from_file[:daemon][:files][:stderr_trace] : STDERR_TRACE
|
23
27
|
self[:logs] = (config_from_file[:logs])? config_from_file[:logs] : {}
|
28
|
+
self[:commands] = (config_from_file[:commands])? config_from_file[:commands] : {}
|
29
|
+
|
30
|
+
end
|
31
|
+
|
32
|
+
def execution_template_path
|
33
|
+
return self[:execution_template_path]
|
24
34
|
end
|
25
35
|
|
36
|
+
def execution_template_tokens
|
37
|
+
return self[:execution_template_tokens]
|
38
|
+
end
|
26
39
|
def logs
|
27
40
|
return self[:logs]
|
28
41
|
end
|
29
42
|
|
43
|
+
def commands
|
44
|
+
return self[:commands]
|
45
|
+
end
|
46
|
+
|
30
47
|
def author
|
31
48
|
return self[:author]
|
32
49
|
end
|
@@ -43,6 +60,13 @@ module Splash
|
|
43
60
|
return self[:daemon_process_name]
|
44
61
|
end
|
45
62
|
|
63
|
+
def prometheus_pushgateway_host
|
64
|
+
return self[:prometheus_pushgateway_host]
|
65
|
+
end
|
66
|
+
def prometheus_pushgateway_port
|
67
|
+
return self[:prometheus_pushgateway_port]
|
68
|
+
end
|
69
|
+
|
46
70
|
def daemon_user
|
47
71
|
return self[:daemon_user]
|
48
72
|
end
|
@@ -78,46 +102,102 @@ module Splash
|
|
78
102
|
|
79
103
|
|
80
104
|
def setupsplash
|
81
|
-
conf_in_path = search_file_in_gem "splash", "config/splash.yml"
|
82
|
-
|
105
|
+
conf_in_path = search_file_in_gem "prometheus-splash", "config/splash.yml"
|
106
|
+
full_res = 0
|
107
|
+
puts "Splash -> setup : "
|
83
108
|
print "* Installing Configuration file : #{CONFIG_FILE} : "
|
84
109
|
if install_file source: conf_in_path, target: CONFIG_FILE, mode: "644", owner: "root", group: "wheel" then
|
85
110
|
puts "[OK]"
|
86
111
|
else
|
112
|
+
full_res =+ 1
|
87
113
|
puts "[KO]"
|
88
114
|
end
|
89
115
|
config = get_config
|
116
|
+
report_in_path = search_file_in_gem "prometheus-splash", "templates/report.txt"
|
117
|
+
print "* Installing template file : #{config.execution_template_path} : "
|
118
|
+
if install_file source: report_in_path, target: config.execution_template_path, mode: "644", owner: "root", group: "wheel" then
|
119
|
+
puts "[OK]"
|
120
|
+
else
|
121
|
+
full_res =+ 1
|
122
|
+
puts "[KO]"
|
123
|
+
end
|
90
124
|
|
91
|
-
print "* Checking pid file path : #{config[:pid_path]}"
|
125
|
+
print "* Creating/Checking pid file path : #{config[:pid_path]} : "
|
92
126
|
if make_folder path: config[:pid_path], mode: "644", owner: "root", group: "wheel" then
|
93
127
|
puts "[OK]"
|
94
128
|
else
|
129
|
+
full_res =+ 1
|
95
130
|
puts "[KO]"
|
96
131
|
end
|
97
132
|
|
98
|
-
print "* Checking trace file path : #{config[:trace_path]}"
|
133
|
+
print "* Creating/Checking trace file path : #{config[:trace_path]} : "
|
99
134
|
if make_folder path: config[:trace_path], mode: "777", owner: config.daemon_user, group: config.daemon_group then
|
100
135
|
puts "[OK]"
|
101
136
|
else
|
137
|
+
full_res =+ 1
|
102
138
|
puts "[KO]"
|
103
139
|
end
|
104
140
|
|
105
|
-
|
141
|
+
if full_res > 0 then
|
142
|
+
$stderr.puts "Splash config done with #{full_res} errors"
|
143
|
+
return 25
|
144
|
+
else
|
145
|
+
puts "Splash config successfully done."
|
146
|
+
return 0
|
147
|
+
end
|
106
148
|
|
107
149
|
end
|
108
150
|
|
109
151
|
def checkconfig
|
152
|
+
puts "Splash -> sanitycheck : "
|
110
153
|
config = get_config
|
111
|
-
|
154
|
+
full_res = 0
|
155
|
+
print "* Config file : #{CONFIG_FILE} : "
|
112
156
|
res = verify_file(name: CONFIG_FILE, mode: "644", owner: "root", group: "wheel")
|
113
157
|
if res.empty? then
|
114
158
|
print "[OK]\n"
|
115
159
|
else
|
116
160
|
print "[KO]\n"
|
117
|
-
|
161
|
+
full_res =+ 1
|
162
|
+
puts " pbm => #{res.map {|p| p.to_s}.join(',')}"
|
118
163
|
end
|
119
164
|
|
165
|
+
print "* PID Path : #{config[:pid_path]} : "
|
166
|
+
res = verify_folder(name: config[:pid_path], mode: "644", owner: "root", group: "wheel")
|
167
|
+
if res.empty? then
|
168
|
+
print "[OK]\n"
|
169
|
+
else
|
170
|
+
print "[KO]\n"
|
171
|
+
full_res =+ 1
|
172
|
+
puts " pbm => #{res.map {|p| p.to_s}.join(',')}"
|
120
173
|
|
174
|
+
end
|
175
|
+
|
176
|
+
print "* trace Path : #{config[:trace_path]} : "
|
177
|
+
res = verify_folder(name: config[:trace_path], mode: "777", owner: config.daemon_user, group: config.daemon_group)
|
178
|
+
if res.empty? then
|
179
|
+
print "[OK]\n"
|
180
|
+
else
|
181
|
+
print "[KO]\n"
|
182
|
+
full_res =+ 1
|
183
|
+
puts " pbm => #{res.map {|p| p.to_s}.join(',')}"
|
184
|
+
end
|
185
|
+
|
186
|
+
print "* Prometheus PushGateway Service running : "
|
187
|
+
if verify_service host: config.prometheus_pushgateway_host ,port: config.prometheus_pushgateway_port then
|
188
|
+
print "[OK]\n"
|
189
|
+
else
|
190
|
+
print "[KO]\n"
|
191
|
+
full_res =+ 1
|
192
|
+
end
|
193
|
+
|
194
|
+
if full_res > 0 then
|
195
|
+
$stderr.puts "Sanitycheck finished with #{full_res} errors"
|
196
|
+
return 20
|
197
|
+
else
|
198
|
+
puts "Sanitycheck finished with no errors"
|
199
|
+
return 0
|
200
|
+
end
|
121
201
|
end
|
122
202
|
|
123
203
|
private
|
data/lib/splash/constants.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
module Splash
|
2
2
|
module Constants
|
3
|
-
VERSION = "0.0.
|
3
|
+
VERSION = "0.0.2"
|
4
4
|
CONFIG_FILE = "/etc/splash.yml"
|
5
5
|
DAEMON_USER = "root"
|
6
6
|
DAEMON_GROUP = "wheel"
|
@@ -14,5 +14,9 @@ module Splash
|
|
14
14
|
EMAIL = "gems@ultragreen.net"
|
15
15
|
COPYRIGHT="Ultragreen (c) 2020"
|
16
16
|
LICENSE="BSD-2-Clause"
|
17
|
+
PROMETHEUS_PUSHGATEWAY_HOST = "localhost"
|
18
|
+
PROMETHEUS_PUSHGATEWAY_PORT = "9091"
|
19
|
+
EXECUTION_TEMPLATE="/etc/splash_execution_report.tpl"
|
20
|
+
TOKENS_LIST = [:date,:cmd_name,:cmd_line,:stdout,:stderr,:desc,:status]
|
17
21
|
end
|
18
22
|
end
|
data/lib/splash/controller.rb
CHANGED
@@ -8,39 +8,95 @@ module Splash
|
|
8
8
|
|
9
9
|
def startdaemon(options = {})
|
10
10
|
config = get_config
|
11
|
+
unless verify_service host: config.prometheus_pushgateway_host ,port: config.prometheus_pushgateway_port then
|
12
|
+
$stderr.puts "Prometheus PushGateway Service is not running,"
|
13
|
+
$stderr.puts " please start before running Splash daemon."
|
14
|
+
exit 11
|
15
|
+
end
|
16
|
+
|
11
17
|
unless File::exist? config.full_pid_path then
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
+
res = daemonize :description => config.daemon_process_name,
|
19
|
+
:pid_file => config.full_pid_path,
|
20
|
+
:daemon_user => config.daemon_user,
|
21
|
+
:daemon_group => config.daemon_group,
|
22
|
+
:stdout_trace => config.full_stdout_trace_path,
|
23
|
+
:stderr_trace => config.full_stderr_trace_path do
|
18
24
|
result = LogScanner::new
|
19
25
|
while true
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
26
|
+
begin
|
27
|
+
sleep 5
|
28
|
+
puts "Notify"
|
29
|
+
result.analyse
|
30
|
+
result.notify
|
31
|
+
rescue Errno::ECONNREFUSED
|
32
|
+
$stderr.puts "PushGateway seems to be done, please start it."
|
33
|
+
end
|
24
34
|
end
|
25
35
|
end
|
36
|
+
if res == 0 then
|
37
|
+
pid = `cat #{config.full_pid_path}`.to_i
|
38
|
+
puts "Splash Daemon Started, with PID : #{pid}"
|
39
|
+
else
|
40
|
+
$stderr.puts "Splash Daemon loading error"
|
41
|
+
end
|
42
|
+
return res
|
43
|
+
|
44
|
+
else
|
45
|
+
$stderr.puts "Pid File already exist, please verify if Splash daemon is running."
|
46
|
+
return 14
|
26
47
|
end
|
27
48
|
end
|
28
49
|
|
29
50
|
def stopdaemon(options = {})
|
30
51
|
config = get_config
|
52
|
+
errorcode = 0
|
31
53
|
if File.exist?(config.full_pid_path) then
|
32
54
|
|
33
55
|
begin
|
34
56
|
pid = `cat #{config.full_pid_path}`.to_i
|
35
57
|
Process.kill("TERM", pid)
|
58
|
+
puts 'Splash stopped succesfully'
|
36
59
|
rescue Errno::ESRCH
|
37
60
|
$stderr.puts "Process of PID : #{pid} not found"
|
61
|
+
errorcode = 12
|
38
62
|
end
|
39
|
-
|
40
|
-
return true
|
63
|
+
FileUtils::rm config.full_pid_path if File::exist? config.full_pid_path
|
41
64
|
else
|
42
|
-
|
65
|
+
$stderr.puts "Splash is not running"
|
66
|
+
errorcode = 13
|
43
67
|
end
|
68
|
+
return errorcode
|
69
|
+
end
|
70
|
+
|
71
|
+
def statusdaemon
|
72
|
+
config = get_config
|
73
|
+
pid = realpid = ''
|
74
|
+
pid = `cat #{config.full_pid_path}`.to_s if File.exist?(config.full_pid_path)
|
75
|
+
realpid = get_process pattern: get_config.daemon_process_name
|
76
|
+
pid.chomp!
|
77
|
+
realpid.chomp!
|
78
|
+
unless realpid.empty? then
|
79
|
+
print "Splash Process is running with PID #{realpid} "
|
80
|
+
else
|
81
|
+
print 'Splash Process not found '
|
82
|
+
end
|
83
|
+
unless pid.empty? then
|
84
|
+
puts "and PID file exist with PID #{pid}"
|
85
|
+
else
|
86
|
+
puts "and PID file don't exist"
|
87
|
+
end
|
88
|
+
if pid == realpid then
|
89
|
+
puts 'Status OK'
|
90
|
+
return 0
|
91
|
+
elsif pid.empty? then
|
92
|
+
$stderr.puts "PID File error, you have to kill process manualy, with : '(sudo )kill -TERM #{realpid}'"
|
93
|
+
$stderr.puts "Status KO"
|
94
|
+
return 16
|
95
|
+
elsif realpid.empty? then
|
96
|
+
$stderr.puts "Process Splash Dameon missing, run 'splash daemon stop' to reload properly"
|
97
|
+
$stderr.puts "Status KO"
|
98
|
+
return 17
|
99
|
+
end
|
44
100
|
end
|
45
101
|
|
46
102
|
end
|
data/lib/splash/helpers.rb
CHANGED
@@ -6,6 +6,19 @@ require 'etc'
|
|
6
6
|
module Splash
|
7
7
|
module Helpers
|
8
8
|
|
9
|
+
|
10
|
+
|
11
|
+
def get_process(options = {})
|
12
|
+
pattern = options[:pattern]
|
13
|
+
res = `ps aux|grep '#{pattern}'|grep -v grep`.to_s
|
14
|
+
unless res.empty? then
|
15
|
+
return res.split(/\s+/)[1]
|
16
|
+
else
|
17
|
+
return ''
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
|
9
22
|
def is_root?
|
10
23
|
case (Process.uid)
|
11
24
|
when 0
|
@@ -21,7 +34,7 @@ module Splash
|
|
21
34
|
$stderr.puts "Please execute with sudo, or rvmsudo."
|
22
35
|
exit 10
|
23
36
|
else
|
24
|
-
self.send method
|
37
|
+
return self.send method
|
25
38
|
end
|
26
39
|
end
|
27
40
|
|
@@ -88,7 +101,7 @@ module Splash
|
|
88
101
|
yield
|
89
102
|
|
90
103
|
end
|
91
|
-
return
|
104
|
+
return 0
|
92
105
|
end
|
93
106
|
|
94
107
|
# @!group facilités sur le système de fichier
|
@@ -141,11 +154,27 @@ module Splash
|
|
141
154
|
#@!group Vérifiers de l'application
|
142
155
|
|
143
156
|
# verifier d'existence d'un repertoire
|
144
|
-
# @return [
|
157
|
+
# @return [Array] of Symbol with error type : [:inexistant,:mode,:owner,:group]
|
145
158
|
# @param [Hash] options
|
146
|
-
# @option options [String] :path le répertoire
|
159
|
+
# @option options [String] :path le répertoire (relatif ou absolut) obligatoire
|
160
|
+
# @option options [String] :mode droit du répertoire optionnel
|
161
|
+
# @option options [String] :owner owner du répertoire optionnel
|
162
|
+
# @option options [String] :group groupe du répertoire optionnel
|
147
163
|
def verify_folder(options ={})
|
148
|
-
|
164
|
+
res = Array::new
|
165
|
+
return [:inexistant] unless File.directory?(options[:name])
|
166
|
+
stat = File.stat(options[:name])
|
167
|
+
if options[:mode] then
|
168
|
+
mode = "%o" % stat.mode
|
169
|
+
res << :mode if mode[-3..-1] != options[:mode]
|
170
|
+
end
|
171
|
+
if options[:owner] then
|
172
|
+
res << :owner if Etc.getpwuid(stat.uid).name != options[:owner]
|
173
|
+
end
|
174
|
+
if options[:group] then
|
175
|
+
res << :group if Etc.getgrgid(stat.gid).name != options[:group]
|
176
|
+
end
|
177
|
+
return res
|
149
178
|
end
|
150
179
|
|
151
180
|
# verifier d'existence d'un lien
|
@@ -157,9 +186,12 @@ module Splash
|
|
157
186
|
end
|
158
187
|
|
159
188
|
# verifier d'existence d'un fichier
|
160
|
-
# @return [
|
189
|
+
# @return [Array] of Symbol with error type : [:inexistant,:mode,:owner,:group]
|
161
190
|
# @param [Hash] options
|
162
|
-
# @option options [String] :name path du fichier
|
191
|
+
# @option options [String] :name path du fichier obligatoire
|
192
|
+
# @option options [String] :mode droit du fichier optionnel
|
193
|
+
# @option options [String] :owner owner du fichier optionnel
|
194
|
+
# @option options [String] :group groupe du fichier optionnel
|
163
195
|
def verify_file(options ={})
|
164
196
|
res = Array::new
|
165
197
|
return [:inexistant] unless File.file?(options[:name])
|
@@ -0,0 +1,68 @@
|
|
1
|
+
module Splash
|
2
|
+
module Templates
|
3
|
+
class Template
|
4
|
+
|
5
|
+
attr_reader :list_token
|
6
|
+
attr_reader :template_file
|
7
|
+
attr_reader :content
|
8
|
+
|
9
|
+
def initialize(_options)
|
10
|
+
|
11
|
+
|
12
|
+
@template_file = _options[:template_file]
|
13
|
+
raise NoTemplateFile::new('No template file found') unless File::exist?(@template_file)
|
14
|
+
begin
|
15
|
+
@content = IO::readlines(@template_file).join.chomp
|
16
|
+
rescue
|
17
|
+
raise NoTemplateFile::new('No template file found')
|
18
|
+
end
|
19
|
+
token_from_template = @content.scan(/%%(\w+)%%/).flatten.uniq.map{ |item| item.downcase.to_sym}
|
20
|
+
begin
|
21
|
+
@list_token = _options[:list_token]
|
22
|
+
@hash_token = Hash::new; @list_token.each{|_item| @hash_token[_item.to_s] = String::new('')}
|
23
|
+
rescue
|
24
|
+
raise InvalidTokenList::new("Token list malformation")
|
25
|
+
end
|
26
|
+
raise InvalidTokenList::new("Token list doesn't match the template") unless token_from_template.sort == @list_token.sort
|
27
|
+
@list_token.each{|_token| eval("def #{_token}=(_value); raise ArgumentError::new('Not a String') unless _value.class == String; @hash_token['#{_token}'] = _value ;end")}
|
28
|
+
@list_token.each{|_token| eval("def #{_token}; @hash_token['#{_token}'] ;end")}
|
29
|
+
end
|
30
|
+
|
31
|
+
def token(_token,_value)
|
32
|
+
raise ArgumentError::new('Not a String') unless _value.class == String
|
33
|
+
@hash_token[_token.to_s] = _value
|
34
|
+
end
|
35
|
+
|
36
|
+
|
37
|
+
def map(_hash)
|
38
|
+
_data = {}
|
39
|
+
_hash.each { |item,val|
|
40
|
+
raise ArgumentError::new("#{item} : Not a String") unless val.class == String
|
41
|
+
_data[item.to_s.downcase] = val
|
42
|
+
}
|
43
|
+
raise InvalidTokenList::new("Token list malformation") unless _data.keys.sort == @list_token.map{|_token| _token.to_s }.sort
|
44
|
+
@hash_token = _data
|
45
|
+
end
|
46
|
+
|
47
|
+
def method_missing(_name,*_args)
|
48
|
+
raise NotAToken
|
49
|
+
end
|
50
|
+
|
51
|
+
|
52
|
+
def output
|
53
|
+
_my_res = String::new('')
|
54
|
+
_my_res = @content
|
55
|
+
@list_token.each{|_token|
|
56
|
+
_my_res.gsub!(/%%#{_token.to_s.upcase}%%/,@hash_token[_token.to_s])
|
57
|
+
}
|
58
|
+
return _my_res
|
59
|
+
end
|
60
|
+
|
61
|
+
end
|
62
|
+
|
63
|
+
class InvalidTokenList < Exception; end
|
64
|
+
class NotAToken < Exception; end
|
65
|
+
class NoTemplateFile < Exception; end
|
66
|
+
|
67
|
+
end
|
68
|
+
end
|
File without changes
|
@@ -0,0 +1,19 @@
|
|
1
|
+
Command Execution report
|
2
|
+
========================
|
3
|
+
|
4
|
+
Date : %%DATE%%
|
5
|
+
Command : %%CMD_NAME%%
|
6
|
+
full command line : %%CMD_LINE%%
|
7
|
+
Description : %%DESC%%
|
8
|
+
errorcode : %%STATUS%%
|
9
|
+
|
10
|
+
STDOUT:
|
11
|
+
-------
|
12
|
+
|
13
|
+
%%STDOUT%%
|
14
|
+
|
15
|
+
|
16
|
+
STDERR:
|
17
|
+
-------
|
18
|
+
|
19
|
+
%%STDERR%%
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: prometheus-splash
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Romain GEORGES
|
@@ -150,13 +150,15 @@ files:
|
|
150
150
|
- Rakefile
|
151
151
|
- bin/splash
|
152
152
|
- config/splash.yml
|
153
|
-
- lib/splash/
|
153
|
+
- lib/splash/commands.rb
|
154
154
|
- lib/splash/config.rb
|
155
155
|
- lib/splash/constants.rb
|
156
156
|
- lib/splash/controller.rb
|
157
157
|
- lib/splash/helpers.rb
|
158
158
|
- lib/splash/logs.rb
|
159
|
-
- splash.
|
159
|
+
- lib/splash/templates.rb
|
160
|
+
- prometheus-splash.gemspec
|
161
|
+
- templates/report.txt
|
160
162
|
- templates/splashd.service
|
161
163
|
- ultragreen_roodi_coding_convention.yml
|
162
164
|
homepage: http://www.ultragreen.net
|
data/lib/splash/command.rb
DELETED
@@ -1,29 +0,0 @@
|
|
1
|
-
module Splash
|
2
|
-
class CommandWrapper
|
3
|
-
def initialize(name)
|
4
|
-
@name = name
|
5
|
-
end
|
6
|
-
|
7
|
-
def ack
|
8
|
-
puts "Sending ack for command : '#{@name}'"
|
9
|
-
notify(0)
|
10
|
-
exit 0
|
11
|
-
end
|
12
|
-
|
13
|
-
def notify(value)
|
14
|
-
registry = Prometheus::Client.registry
|
15
|
-
metric = Prometheus::Client::Gauge.new(:errorcode, docstring: 'SPLASH metric batch errorcode')
|
16
|
-
registry.register(metric)
|
17
|
-
metric.set(value)
|
18
|
-
Prometheus::Client::Push.new(@name).add(registry)
|
19
|
-
end
|
20
|
-
|
21
|
-
|
22
|
-
def call_and_notify
|
23
|
-
puts "Executing command : '#{@name}' and notify Prometheus PushGateway"
|
24
|
-
system("#{@name} > /dev/null")
|
25
|
-
exit_code = $?.exitstatus
|
26
|
-
notify(exit_code)
|
27
|
-
end
|
28
|
-
end
|
29
|
-
end
|