prometheus-splash 0.1.0 → 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,20 @@
1
+ # coding: utf-8
2
+ Dir[File.dirname(__FILE__) + '/cli/*.rb'].each {|file| require file }
3
+
4
+ class CLI < Thor
5
+ def self.exit_on_failure?
6
+ true
7
+ end
8
+
9
+ include CLISplash
10
+ desc "commands SUBCOMMAND ...ARGS", "Managing commands/batchs supervision"
11
+ subcommand "commands", Commands
12
+ desc "logs SUBCOMMAND ...ARGS", "Managing Files/Logs supervision"
13
+ subcommand "logs", Logs
14
+ desc "daemon SUBCOMMAND ...ARGS", "Logs monitor daemon contoller"
15
+ subcommand "daemon", CLIController
16
+ desc "config SUBCOMMAND ...ARGS", "config tools for Splash"
17
+ subcommand "config", Config
18
+ desc "documentation SUBCOMMAND ...ARGS", "Documentation for Splash"
19
+ subcommand "documentation", Documentation
20
+ end
@@ -0,0 +1,164 @@
1
+ # coding: utf-8
2
+ module CLISplash
3
+
4
+
5
+ class Commands < Thor
6
+ include Splash::Config
7
+ include Splash::Backends
8
+ include Splash::Exiter
9
+
10
+ desc "execute NAME", "run for command/sequence or ack result"
11
+ long_desc <<-LONGDESC
12
+ execute command or sequence or ack result
13
+ with --no-trace prevent storing execution trace in configured backend (see config file)
14
+ with --ack, notify errorcode=0 to Prometheus PushGateway
15
+ with --no-notify, bypass Prometheus notification
16
+ with --no-callback, never execute callback (:on_failure, :on_success)
17
+ never follow sequences
18
+ LONGDESC
19
+ option :trace, :type => :boolean, :default => true
20
+ option :ack, :type => :boolean, negate: false
21
+ option :notify, :type => :boolean, :default => true
22
+ option :callback, :type => :boolean, :default => true
23
+ def execute(name)
24
+ if is_root? then
25
+ command = Splash::CommandWrapper::new(name)
26
+ if options[:ack] then
27
+ splash_exit command.ack
28
+ end
29
+ acase = command.call_and_notify trace: options[:trace], notify: options[:notify], callback: options[:callback]
30
+ splash_exit acase
31
+ else
32
+ splash_exit case: :not_root, :more => "Command execution"
33
+ end
34
+ end
35
+
36
+
37
+ desc "treeview", "Show commands sequence tree"
38
+ def treeview(command, depht = 0)
39
+ puts "Command : #{command.to_s}" if depht == 0
40
+ cmd = get_config.commands[command.to_sym]
41
+ if cmd[:on_failure] then
42
+ print " " * depht + " "
43
+ puts "* on failure => #{cmd[:on_failure]}"
44
+ treeview(cmd[:on_failure], depht+2)
45
+ end
46
+ if cmd[:on_success] then
47
+ print " " * depht + " "
48
+ puts "* on success => #{cmd[:on_success]}"
49
+ treeview(cmd[:on_success],depht+2)
50
+ end
51
+ splash_exit case: :quiet_exit
52
+ end
53
+
54
+
55
+ desc "list", "Show configured commands"
56
+ long_desc <<-LONGDESC
57
+ Show configured commands
58
+ with --detail, show command details
59
+ LONGDESC
60
+ option :detail, :type => :boolean
61
+ def list
62
+ puts "Splash configured commands :"
63
+ list = get_config.commands
64
+ puts 'No configured commands found' if list.keys.empty?
65
+ list.keys.each do |command|
66
+ puts " * #{command.to_s}"
67
+ if options[:detail] then
68
+ puts " - command line : '#{list[command][:command]}'"
69
+ puts " - command description : '#{list[command][:desc]}'"
70
+ puts " - command failure callback : '#{list[command.to_sym][:on_failure]}'" if list[command.to_sym][:on_failure]
71
+ puts " - command success callback : '#{list[command.to_sym][:on_success]}'" if list[command.to_sym][:on_success]
72
+ end
73
+ end
74
+ splash_exit case: :quiet_exit
75
+ end
76
+
77
+
78
+ desc "show COMMAND", "Show specific configured command COMMAND"
79
+ def show(command)
80
+ list = get_config.commands
81
+ if list.keys.include? command.to_sym then
82
+ puts "Splash command : #{command}"
83
+ puts " - command line : '#{list[command.to_sym][:command]}'"
84
+ puts " - command description : '#{list[command.to_sym][:desc]}'"
85
+ puts " - command failure callback : '#{list[command.to_sym][:on_failure]}'" if list[command.to_sym][:on_failure]
86
+ puts " - command success callback : '#{list[command.to_sym][:on_success]}'" if list[command.to_sym][:on_success]
87
+ splash_exit case: :quiet_exit
88
+ else
89
+ splash_exit case: :not_found, :more => 'Command not configured'
90
+ end
91
+ end
92
+
93
+
94
+ desc "lastrun COMMAND", "Show last running result for specific configured command COMMAND"
95
+ long_desc <<-LONGDESC
96
+ Show last running result for specific configured command COMMAND
97
+ with --hostname <HOSTNAME>, an other Splash monitored server (only with Redis backend configured)
98
+ LONGDESC
99
+ option :hostname, :type => :string
100
+ def lastrun(command)
101
+ backend = get_backend :execution_trace
102
+ redis = (backend.class == Splash::Backends::Redis)? true : false
103
+ if not redis and options[:hostname] then
104
+ splash_exit case: :specific_config_required, :more => "Redis backend is requiered for Remote execution report request"
105
+ end
106
+ list = get_config.commands
107
+ if list.keys.include? command.to_sym then
108
+ print "Splash command #{command} previous execution report:\n\n"
109
+ req = { :key => command}
110
+ req[:hostname] = options[:hostname] if options[:hostname]
111
+ if backend.exist? req then
112
+ print backend.get req
113
+ else
114
+ puts "Command not already runned."
115
+ end
116
+ splash_exit case: :quiet_exit
117
+ else
118
+ splash_exit case: :command_not_configured
119
+ end
120
+ end
121
+
122
+ desc "getreportlist", "list all executions report results "
123
+ long_desc <<-LONGDESC
124
+ list all executions report results
125
+ with --pattern <SEARCH>, search type string, wilcard * (group) ? (char)\n
126
+ with --hostname <HOSTNAME>, an other Splash monitored server (only with Redis backend configured)\n
127
+ with --all, get all execution report for all servers (only with Redis backend configured)\n
128
+ --all and --hostname are exclusives
129
+ LONGDESC
130
+ option :pattern, :type => :string
131
+ option :hostname, :type => :string
132
+ option :all, :type => :boolean, :negate => false
133
+ def getreportlist
134
+ if options[:hostname] and options[:all] then
135
+ splash_exit case: :options_incompatibility, more: "--all, --hostname"
136
+ end
137
+ backend = get_backend :execution_trace
138
+ redis = (backend.class == Splash::Backends::Redis)? true : false
139
+ if not redis and (options[:hostname] or options[:all]) then
140
+ splash_exit case: :redis_back_required, more: "Remote execution report Request"
141
+ end
142
+ pattern = (options[:pattern])? options[:pattern] : '*'
143
+ if options[:all] then
144
+ res = backend.listall pattern
145
+ elsif options[:hostname]
146
+ res = backend.list pattern, options[:hostname]
147
+ else
148
+ res = backend.list pattern
149
+ end
150
+ print "List of Executions reports :\n\n"
151
+ puts "Not reports found" if res.empty?
152
+ res.each do |item|
153
+ if options[:all]
154
+ host,command = item.split('#')
155
+ puts " * Command : #{command} @ host : #{host}"
156
+ else
157
+ puts " * Command : #{item}"
158
+ end
159
+ end
160
+ splash_exit case: :quiet_exit
161
+ end
162
+
163
+ end
164
+ end
@@ -0,0 +1,37 @@
1
+ # coding: utf-8
2
+ module CLISplash
3
+
4
+ class Config < Thor
5
+ include Splash::Config
6
+ include Splash::Helpers
7
+ include Splash::Exiter
8
+
9
+
10
+ desc "setup", "Setup installation fo Splash"
11
+ long_desc <<-LONGDESC
12
+ Setup installation fo Splash
13
+ with --preserve, preserve from reinstallation of the config
14
+ LONGDESC
15
+ option :preserve, :type => :boolean
16
+ def setup
17
+ acase = run_as_root :setupsplash
18
+ splash_exit acase
19
+ end
20
+
21
+ desc "sanitycheck", "Verify installation fo Splash"
22
+ def sanitycheck
23
+ acase = run_as_root :checkconfig
24
+ splash_exit acase
25
+ end
26
+
27
+ desc "version", "display current Splash version"
28
+ def version
29
+ config = get_config
30
+ puts "Splash version : #{config.version}, Author : #{config.author}"
31
+ puts config.copyright
32
+ splash_exit case: :quiet_exit
33
+ end
34
+
35
+ end
36
+
37
+ end
@@ -0,0 +1,52 @@
1
+ # coding: utf-8
2
+ module CLISplash
3
+
4
+ class CLIController < Thor
5
+ include Splash::LogsMonitor::DaemonController
6
+ include Splash::Transports
7
+ include Splash::Exiter
8
+
9
+
10
+ option :foreground, :type => :boolean
11
+ desc "start", "Starting Logs Monitor Daemon"
12
+ def start
13
+ acase = run_as_root :startdaemon
14
+ splash_exit acase
15
+ end
16
+
17
+ desc "stop", "Stopping Logs Monitor Daemon"
18
+ def stop
19
+ acase = run_as_root :stopdaemon
20
+ splash_exit acase
21
+ end
22
+
23
+ desc "status", "Logs Monitor Daemon status"
24
+ def status
25
+ acase = run_as_root :statusdaemon
26
+ splash_exit acase
27
+ end
28
+
29
+ desc "ping HOSTNAME", "send a ping to HOSTNAME daemon over transport (need an active tranport), Typicallly RabbitMQ"
30
+ def ping(hostname=Socket.gethostname)
31
+ puts "ctrl+c for interrupt"
32
+ queue = "splash.#{Socket.gethostname}.returncli"
33
+ order = {:verb => :ping, :payload => {:hostname => Socket.gethostname}, :return_to => queue}
34
+
35
+ lock = Mutex.new
36
+ condition = ConditionVariable.new
37
+ begin
38
+ get_default_subscriber(queue: queue).subscribe(timeout: 10) do |delivery_info, properties, payload|
39
+ puts YAML::load(payload)
40
+ lock.synchronize { condition.signal }
41
+ end
42
+ get_default_client.publish queue: "splash.#{hostname}.input", message: order.to_yaml
43
+ lock.synchronize { condition.wait(lock) }
44
+ splash_exit case: :quiet_exit
45
+ rescue Interrupt
46
+ splash_exit status: :error, case: :interrupt, more: "Ping Command"
47
+ end
48
+ end
49
+
50
+ end
51
+
52
+ end
@@ -0,0 +1,24 @@
1
+ # coding: utf-8
2
+ module CLISplash
3
+
4
+ class Documentation < Thor
5
+ include Splash::Config
6
+ include Splash::Exiter
7
+
8
+
9
+ desc "readme", "Display README file"
10
+ option :formatted, :type => :boolean, :default => true
11
+ def readme
12
+ filename = search_file_in_gem("prometheus-splash","README.md")
13
+
14
+ if options[:formatted] then
15
+ content = TTY::Markdown.parse_file(filename)
16
+ else
17
+ conten = File::readlines(filename).join
18
+ end
19
+ pager = TTY::Pager.new
20
+ pager.page(content)
21
+ splash_exit case: :quiet_exit
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,72 @@
1
+ # coding: utf-8
2
+ module CLISplash
3
+
4
+ class Logs < Thor
5
+ include Splash::Config
6
+ include Splash::Exiter
7
+
8
+
9
+ desc "analyse", "analyze logs in config"
10
+ def analyse
11
+ results = Splash::LogScanner::new
12
+ res = results.analyse
13
+ puts "SPlash Configured logs status :"
14
+ full_status = true
15
+ results.output.each do |result|
16
+ status = (result[:status] == :clean)? "OK": "KO"
17
+ puts " * Log : #{result[:log]} : [#{status}]"
18
+ puts " - Detected pattern : #{result[:pattern]}"
19
+ puts " - detailled Status : #{result[:status].to_s}"
20
+ puts " count = #{result[:count]}" if result[:status] == :matched
21
+ puts " nb lines = #{result[:lines]}" if result[:status] != :missing
22
+ full_status = false unless result[:status] == :clean
23
+ end
24
+ display_status = (full_status)? "OK": "KO"
25
+ puts "Global Status : [#{display_status}]"
26
+ splash_exit case: :quiet_exit
27
+ end
28
+
29
+ desc "monitor", "monitor logs in config"
30
+ def monitor
31
+ result = Splash::LogScanner::new
32
+ result.analyse
33
+ result.notify
34
+ splash_exit result.notify
35
+
36
+ end
37
+
38
+ desc "show LOG", "show configured log monitoring for LOG"
39
+ def show(log)
40
+ log_record_set = get_config.logs.select{|item| item[:log] == log }
41
+ unless log_record_set.empty? then
42
+ record = log_record_set.first
43
+ puts "Splash log monitor : #{record[:log]}"
44
+ puts " -> pattern : /#{record[:pattern]}/"
45
+ splash_exit case: :quiet_exit
46
+ else
47
+ splash_exit case: :not_found, :more => "log not configured"
48
+ end
49
+ end
50
+
51
+ desc "list", "Show configured logs monitoring"
52
+ long_desc <<-LONGDESC
53
+ Show configured logs monitoring
54
+ with --detail, show logs monitor details
55
+ LONGDESC
56
+ option :detail, :type => :boolean
57
+ def list
58
+ puts "Splash configured log monitoring :"
59
+ log_record_set = get_config.logs
60
+ puts 'No configured commands found' if log_record_set.empty?
61
+ log_record_set.each do |record|
62
+ puts " * log monitor : #{record[:log]}"
63
+ if options[:detail] then
64
+ puts " -> pattern : /#{record[:pattern]}/"
65
+ end
66
+ end
67
+ splash_exit case: :quiet_exit
68
+ end
69
+
70
+ end
71
+
72
+ end
@@ -1,20 +1,17 @@
1
- require 'open3'
2
- require 'date'
3
- require 'socket'
4
-
1
+ # coding: utf-8
5
2
  module Splash
6
3
  class CommandWrapper
7
4
  include Splash::Templates
8
5
  include Splash::Config
9
6
  include Splash::Helpers
10
7
  include Splash::Backends
8
+ include Splash::Exiter
11
9
 
12
10
  def initialize(name)
13
11
  @config = get_config
14
12
  @name = name
15
13
  unless @config.commands.keys.include? @name.to_sym then
16
- $stderr.puts "Splash : command #{@name} is not defined in configuration"
17
- exit 40
14
+ splash_exit case: :not_found, more: "command #{@name} is not defined in configuration"
18
15
  end
19
16
  @registry = Prometheus::Client.registry
20
17
  @url = "http://#{@config.prometheus_pushgateway_host}:#{@config.prometheus_pushgateway_port}"
@@ -26,26 +23,25 @@ module Splash
26
23
 
27
24
  def ack
28
25
  puts "Sending ack for command : '#{@name}'"
29
- notify(0)
30
- exit 0
26
+ notify(0,0)
31
27
  end
32
28
 
33
29
  def notify(value,time)
34
30
  unless verify_service host: @config.prometheus_pushgateway_host ,port: @config.prometheus_pushgateway_port then
35
- $stderr.puts "Prometheus PushGateway Service IS NOT running"
36
- $stderr.puts "Exit without notification."
37
- exit 30
31
+ return { :case => :service_dependence_missing, :more => "Prometheus Notification not send."}
38
32
  end
39
33
  @metric_exitcode.set(value)
40
34
  @metric_time.set(time)
41
35
  hostname = Socket.gethostname
42
36
  Prometheus::Client::Push.new(@name, hostname, @url).add(@registry)
43
37
  puts " * Prometheus Gateway notified."
38
+ return { :case => :quiet_exit}
44
39
  end
45
40
 
46
41
 
47
42
  def call_and_notify(options)
48
43
  puts "Executing command : '#{@name}' "
44
+ acase = { :case => :quiet_exit }
49
45
  start = Time.now
50
46
  start_date = DateTime.now.to_s
51
47
  unless options[:trace] then
@@ -89,7 +85,7 @@ module Splash
89
85
 
90
86
  puts " => exitcode #{exit_code}"
91
87
  if options[:notify] then
92
- notify(exit_code,time.to_i)
88
+ acase = notify(exit_code,time.to_i)
93
89
  else
94
90
  puts " * Without Prometheus notification"
95
91
  end
@@ -103,7 +99,7 @@ module Splash
103
99
  @name = on_failure.to_s
104
100
  call_and_notify options
105
101
  else
106
- $stderr.puts "on_failure call error : configuration mistake : #{on_failure} command inexistant."
102
+ acase = { :case => :configuration_error , :more => "on_failure call error : #{on_failure} command inexistant."}
107
103
  end
108
104
  end
109
105
  if on_success and exit_code == 0 then
@@ -118,8 +114,7 @@ module Splash
118
114
  else
119
115
  puts " * Without callbacks sequences"
120
116
  end
121
-
122
- exit exit_code
117
+ return acase
123
118
  end
124
119
  end
125
120
  end