prometheus-splash 0.6.1 → 0.8.3

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.
Files changed (60) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +43 -1
  3. data/README.md +1 -1
  4. data/config/splash.yml +45 -5
  5. data/lib/splash/backends.rb +1 -0
  6. data/lib/splash/cli.rb +2 -1
  7. data/lib/splash/cli/commands.rb +125 -5
  8. data/lib/splash/cli/daemon.rb +41 -1
  9. data/lib/splash/cli/logs.rb +111 -47
  10. data/lib/splash/cli/process.rb +112 -52
  11. data/lib/splash/cli/sequences.rb +2 -0
  12. data/lib/splash/cli/transfers.rb +213 -0
  13. data/lib/splash/cli/webadmin.rb +3 -3
  14. data/lib/splash/commands.rb +85 -19
  15. data/lib/splash/config.rb +142 -52
  16. data/lib/splash/constants.rb +7 -3
  17. data/lib/splash/daemon/metrics.rb +6 -6
  18. data/lib/splash/daemon/orchestrator.rb +76 -36
  19. data/lib/splash/daemon/orchestrator/grammar.rb +16 -1
  20. data/lib/splash/dependencies.rb +6 -1
  21. data/lib/splash/exiter.rb +1 -1
  22. data/lib/splash/helpers.rb +12 -3
  23. data/lib/splash/loggers/cli.rb +2 -10
  24. data/lib/splash/logs.rb +90 -16
  25. data/lib/splash/processes.rb +87 -16
  26. data/lib/splash/transfers.rb +229 -0
  27. data/lib/splash/webadmin.rb +3 -3
  28. data/lib/splash/webadmin/api/routes/commands.rb +2 -2
  29. data/lib/splash/webadmin/api/routes/config.rb +53 -2
  30. data/lib/splash/webadmin/api/routes/logs.rb +32 -17
  31. data/lib/splash/webadmin/api/routes/process.rb +4 -4
  32. data/lib/splash/webadmin/api/routes/sequences.rb +28 -0
  33. data/lib/splash/webadmin/main.rb +1 -0
  34. data/lib/splash/webadmin/portal/controllers/commands.rb +2 -0
  35. data/lib/splash/webadmin/portal/controllers/documentation.rb +3 -1
  36. data/lib/splash/webadmin/portal/controllers/home.rb +24 -0
  37. data/lib/splash/webadmin/portal/controllers/logs.rb +44 -1
  38. data/lib/splash/webadmin/portal/controllers/processes.rb +2 -0
  39. data/lib/splash/webadmin/portal/controllers/proxy.rb +13 -4
  40. data/lib/splash/webadmin/portal/controllers/restclient.rb +7 -2
  41. data/lib/splash/webadmin/portal/controllers/sequences.rb +9 -0
  42. data/lib/splash/webadmin/portal/init.rb +2 -2
  43. data/lib/splash/webadmin/portal/public/css/ultragreen.css +6 -0
  44. data/lib/splash/webadmin/portal/public/favicon.ico +0 -0
  45. data/lib/splash/webadmin/portal/views/commands.slim +1 -1
  46. data/lib/splash/webadmin/portal/views/documentation.slim +1 -1
  47. data/lib/splash/webadmin/portal/views/home.slim +53 -9
  48. data/lib/splash/webadmin/portal/views/layout.slim +2 -2
  49. data/lib/splash/webadmin/portal/views/logs.slim +68 -21
  50. data/lib/splash/webadmin/portal/views/logs_form.slim +24 -0
  51. data/lib/splash/webadmin/portal/views/nav.slim +1 -1
  52. data/lib/splash/webadmin/portal/views/not_found.slim +1 -1
  53. data/lib/splash/webadmin/portal/views/processes.slim +1 -1
  54. data/lib/splash/webadmin/portal/views/proxy.slim +5 -2
  55. data/lib/splash/webadmin/portal/views/restclient.slim +7 -4
  56. data/lib/splash/webadmin/portal/views/restclient_result.slim +24 -20
  57. data/lib/splash/webadmin/portal/views/sequences.slim +50 -0
  58. data/prometheus-splash.gemspec +7 -4
  59. data/ultragreen_roodi_coding_convention.yml +4 -4
  60. metadata +75 -12
@@ -16,7 +16,7 @@ module Splash
16
16
  include Splash::Loggers
17
17
 
18
18
  # list of known verbs for Splash orchestrator
19
- VERBS=[:ping,:list_commands,:execute_command,:ack_command, :shutdown]
19
+ VERBS=[:ping,:list_commands,:execute_command,:ack_command, :shutdown, :get_jobs, :reset]
20
20
 
21
21
  # shutdown verb : stop the Splash daemon gracefully
22
22
  # @param [Hash] content message content Hash Structure, ignored
@@ -46,6 +46,21 @@ module Splash
46
46
  return execute command: content[:payload][:name], ack: true
47
47
  end
48
48
 
49
+
50
+ # get_jobs verb : return list of scheduled jobs for internal scheduler
51
+ # @param [Hash] content message content Hash Structure, ignored
52
+ # @return [String] YAML dataset
53
+ def get_jobs(content)
54
+ return @server.jobs.to_yaml
55
+ end
56
+
57
+ # reset verb : reset the internal scheduler
58
+ # @param [Hash] content message content Hash Structure, ignored
59
+ # @return [String] "Scheduler reset" static
60
+ def reset(content)
61
+ return "Scheduler reset" if reset_orchestrator
62
+ end
63
+
49
64
  # execute_command verb : execute command specified in payload
50
65
  # @param [Hash] content message content Hash Structure, include mandatory payload[:name]
51
66
  # @return [Hash] Exiter case
@@ -17,8 +17,12 @@ module Splash
17
17
 
18
18
 
19
19
 
20
+
21
+
20
22
  # Rubygems
21
23
  begin
24
+ require 'net/ssh'
25
+ require 'net/scp'
22
26
  require 'prometheus/client'
23
27
  require 'prometheus/client/push'
24
28
  require 'thor'
@@ -35,6 +39,7 @@ module Splash
35
39
  require 'rest-client'
36
40
  require 'kramdown'
37
41
  require 'rack/reverse_proxy'
42
+ require 'tty-table'
38
43
 
39
44
 
40
45
  rescue Gem::GemNotFoundException
@@ -57,9 +62,9 @@ module Splash
57
62
 
58
63
  require 'splash/commands'
59
64
  require 'splash/sequences'
60
-
61
65
  require 'splash/logs'
62
66
  require 'splash/processes'
67
+ require 'splash/transfers'
63
68
 
64
69
  require 'splash/daemon'
65
70
  require 'splash/webadmin'
@@ -60,7 +60,7 @@ module Splash
60
60
 
61
61
  def splash_return(options = {})
62
62
 
63
- data = EXIT_MAP[options[:case]]
63
+ data = EXIT_MAP[options[:case]].clone
64
64
  data[:status] = (data[:code]>0)? :failure : :success
65
65
  data[:more] = options[:more] if options[:more]
66
66
  return data
@@ -252,7 +252,7 @@ module Splash
252
252
  # check folder
253
253
  # @return [Array] of Symbol with error type : [:inexistant,:mode,:owner,:group]
254
254
  # @param [Hash] options
255
- # @option options [String] :path folder path (relative or absolute)
255
+ # @option options [String] :name folder path (relative or absolute)
256
256
  # @option options [String] :mode String for OCTAL rights like "644", optionnal
257
257
  # @option options [String] :owner file owner for folder, optionnal
258
258
  # @option options [String] :group file group for folder, optionnal
@@ -336,12 +336,11 @@ module Splash
336
336
  end
337
337
  #!@endgroup
338
338
 
339
-
340
339
  def format_response(data, format)
341
340
  response = case format
342
341
  when 'application/json' then JSON.pretty_generate(data)
343
342
  when 'text/x-yaml' then data.to_yaml
344
- else JSON.pretty_generate(data)
343
+ else data.to_yaml
345
344
  end
346
345
  return response
347
346
  end
@@ -355,6 +354,16 @@ module Splash
355
354
  return result[extension]
356
355
  end
357
356
 
357
+ # check if unicode must be used with term ENV
358
+ # @return [Boolean]
359
+ def check_unicode_term
360
+ return false unless ENV.include? "TERM"
361
+ if ENV.values_at("LC_ALL","LC_CTYPE","LANG").compact.first.include?("UTF-8") and ENV.values_at('TERM').first.include? "xterm" then
362
+ return true
363
+ else
364
+ return false
365
+ end
366
+ end
358
367
 
359
368
  end
360
369
  end
@@ -10,6 +10,7 @@ module Splash
10
10
  class Cli < Splash::Loggers::LoggerTemplate
11
11
 
12
12
  include Splash::Config
13
+ include Splash::Helpers
13
14
 
14
15
  # mapping of UTf-8 emoji for log levels or alias
15
16
  EMOJI = { :unknown => "\u{1F4A5}",
@@ -82,16 +83,7 @@ module Splash
82
83
  get_config.loggers[:cli][:color] = status
83
84
  end
84
85
 
85
- # check if unicode must be used with term ENV
86
- # @return [Boolean]
87
- def check_unicode_term
88
- return false unless ENV.include? "TERM"
89
- if ENV.values_at("LC_ALL","LC_CTYPE","LANG").compact.first.include?("UTF-8") and ENV.values_at('TERM').first.include? "xterm" then
90
- return true
91
- else
92
- return false
93
- end
94
- end
86
+
95
87
 
96
88
  end
97
89
 
@@ -6,6 +6,79 @@ module Splash
6
6
  # Logs namespace
7
7
  module Logs
8
8
 
9
+ class LogsNotifier
10
+
11
+ @@registry = Prometheus::Client::Registry::new
12
+ @@metric_missing = Prometheus::Client::Gauge.new(:logmissing, docstring: 'SPLASH metric log missing', labels: [:log ])
13
+ @@metric_count = Prometheus::Client::Gauge.new(:logerrors, docstring: 'SPLASH metric log error', labels: [:log ])
14
+ @@metric_lines = Prometheus::Client::Gauge.new(:loglines, docstring: 'SPLASH metric log lines numbers', labels: [:log ])
15
+ @@registry.register(@@metric_count)
16
+ @@registry.register(@@metric_missing)
17
+ @@registry.register(@@metric_lines)
18
+
19
+ def initialize(options={})
20
+ @config = get_config
21
+ @url = @config.prometheus_pushgateway_url
22
+ @name = options[:name]
23
+ @missing = options[:missing]
24
+ @lines = options[:lines]
25
+ @errors = options[:errors]
26
+ end
27
+
28
+ # send metrics to Prometheus PushGateway
29
+ # @return [Bool]
30
+ def notify
31
+ unless verify_service url: @url then
32
+ return { :case => :service_dependence_missing, :more => "Prometheus Notification not send."}
33
+ end
34
+ @@metric_missing.set(@missing, labels: { log: @name })
35
+ @@metric_count.set(@errors, labels: { log: @name })
36
+ @@metric_lines.set(@lines, labels: { log: @name })
37
+ hostname = Socket.gethostname
38
+ return Prometheus::Client::Push.new("Splash", hostname, @url).add(@@registry)
39
+ end
40
+
41
+ end
42
+
43
+ class LogsRecords
44
+ include Splash::Backends
45
+ include Splash::Constants
46
+ def initialize(name)
47
+ @name = name
48
+ @backend = get_backend :logs_trace
49
+ end
50
+
51
+ def purge(retention)
52
+ retention = {} if retention.nil?
53
+ if retention.include? :hours then
54
+ adjusted_datetime = DateTime.now - retention[:hours].to_f / 24
55
+ elsif retention.include? :hours then
56
+ adjusted_datetime = DateTime.now - retention[:days].to_i
57
+ else
58
+ adjusted_datetime = DateTime.now - DEFAULT_RETENTION
59
+ end
60
+
61
+ data = get_all_records
62
+
63
+ data.delete_if { |item|
64
+ DateTime.parse(item.keys.first) <= (adjusted_datetime)}
65
+ @backend.put key: @name, value: data.to_yaml
66
+ end
67
+
68
+ def add_record(record)
69
+ data = get_all_records
70
+ data.push({ DateTime.now.to_s => record })
71
+ @backend.put key: @name, value: data.to_yaml
72
+ end
73
+
74
+ def get_all_records(options={})
75
+ return (@backend.exist?({key: @name}))? YAML::load(@backend.get({key: @name})) : []
76
+ end
77
+
78
+ end
79
+
80
+
81
+
9
82
  # Log scanner and notifier
10
83
  class LogScanner
11
84
  include Splash::Constants
@@ -17,13 +90,7 @@ module Splash
17
90
  def initialize
18
91
  @logs_target = Marshal.load(Marshal.dump(get_config.logs))
19
92
  @config = get_config
20
- @registry = Prometheus::Client::Registry::new
21
- @metric_count = Prometheus::Client::Gauge.new(:logerrors, docstring: 'SPLASH metric log error', labels: [:log ])
22
- @metric_missing = Prometheus::Client::Gauge.new(:logmissing, docstring: 'SPLASH metric log missing', labels: [:log ])
23
- @metric_lines = Prometheus::Client::Gauge.new(:loglines, docstring: 'SPLASH metric log lines numbers', labels: [:log ])
24
- @registry.register(@metric_count)
25
- @registry.register(@metric_missing)
26
- @registry.register(@metric_lines)
93
+
27
94
  end
28
95
 
29
96
 
@@ -62,17 +129,24 @@ module Splash
62
129
  session = (options[:session]) ? options[:session] : log.get_session
63
130
  log.info "Sending metrics to Prometheus Pushgateway", session
64
131
  @logs_target.each do |item|
65
- missing = (item[:status] == :missing)? 1 : 0
66
- log.item "Sending metrics for #{item[:log]}", session
67
- @metric_count.set(item[:count], labels: { log: item[:log] })
68
- @metric_missing.set(missing, labels: { log: item[:log] })
132
+ logsrec = LogsRecords::new item[:label]
133
+ errors = (item[:count])? item[:count] : 0
69
134
  lines = (item[:lines])? item[:lines] : 0
70
- @metric_lines.set(lines, labels: { log: item[:log] })
135
+ missing = (item[:status] = :missing)? 1 : 0
136
+ file = item[:log]
137
+ logsrec.purge(item[:retention])
138
+ logsrec.add_record :status => item[:status],
139
+ :errors => errors,
140
+ :lines => lines,
141
+ :file => file
142
+
143
+ logsmonitor = LogsNotifier::new({name: item[:label], missing: missing, file: file, errors: errors, lines: lines})
144
+ if logsmonitor.notify then
145
+ log.ok "Sending metrics for log #{file} to Prometheus Pushgateway", session
146
+ else
147
+ log.ko "Failed to send metrics for log #{file} to Prometheus Pushgateway", session
148
+ end
71
149
  end
72
- hostname = Socket.gethostname
73
- url = @config.prometheus_pushgateway_url
74
- Prometheus::Client::Push.new('Splash',hostname, url).add(@registry)
75
- log.ok "Sending to Prometheus PushGateway done.", session
76
150
  return {:case => :quiet_exit }
77
151
  end
78
152
 
@@ -6,6 +6,81 @@ module Splash
6
6
  # Processes namespace
7
7
  module Processes
8
8
 
9
+
10
+ class ProcessNotifier
11
+
12
+ @@registry = Prometheus::Client::Registry::new
13
+ @@metric_status = Prometheus::Client::Gauge.new(:process_status, docstring: 'SPLASH metric process status', labels: [:process ])
14
+ @@metric_cpu_percent = Prometheus::Client::Gauge.new(:process_cpu_percent, docstring: 'SPLASH metric process CPU usage in percent', labels: [:process ])
15
+ @@metric_mem_percent = Prometheus::Client::Gauge.new(:process_mem_percent, docstring: 'SPLASH metric process MEM usage in percent', labels: [:process ])
16
+ @@registry.register(@@metric_status)
17
+ @@registry.register(@@metric_cpu_percent)
18
+ @@registry.register(@@metric_mem_percent)
19
+
20
+
21
+ def initialize(options={})
22
+ @config = get_config
23
+ @url = @config.prometheus_pushgateway_url
24
+ @name = options[:name]
25
+ @status = options[:status]
26
+ @cpu_percent = options[:cpu_percent]
27
+ @mem_percent = options[:mem_percent]
28
+ end
29
+
30
+ # send metrics to Prometheus PushGateway
31
+ # @return [Bool]
32
+ def notify
33
+ unless verify_service url: @url then
34
+ return { :case => :service_dependence_missing, :more => "Prometheus Notification not send."}
35
+ end
36
+ @@metric_mem_percent.set(@mem_percent, labels: { process: @name })
37
+ @@metric_cpu_percent.set(@cpu_percent, labels: { process: @name })
38
+ @@metric_status.set(@status, labels: { process: @name })
39
+ hostname = Socket.gethostname
40
+ return Prometheus::Client::Push.new("Splash", hostname, @url).add(@@registry)
41
+ end
42
+
43
+ end
44
+
45
+
46
+ class ProcessRecords
47
+ include Splash::Backends
48
+ include Splash::Constants
49
+
50
+ def initialize(name)
51
+ @name = name
52
+ @backend = get_backend :process_trace
53
+ end
54
+
55
+ def purge(retention)
56
+ retention = {} if retention.nil?
57
+ if retention.include? :hours then
58
+ adjusted_datetime = DateTime.now - retention[:hours].to_f / 24
59
+ elsif retention.include? :hours then
60
+ adjusted_datetime = DateTime.now - retention[:days].to_i
61
+ else
62
+ adjusted_datetime = DateTime.now - DEFAULT_RETENTION
63
+ end
64
+
65
+ data = get_all_records
66
+
67
+ data.delete_if { |item|
68
+ DateTime.parse(item.keys.first) <= (adjusted_datetime)}
69
+ @backend.put key: @name, value: data.to_yaml
70
+ end
71
+
72
+ def add_record(record)
73
+ data = get_all_records
74
+ data.push({ DateTime.now.to_s => record })
75
+ @backend.put key: @name, value: data.to_yaml
76
+ end
77
+
78
+ def get_all_records(options={})
79
+ return (@backend.exist?({key: @name}))? YAML::load(@backend.get({key: @name})) : []
80
+ end
81
+
82
+ end
83
+
9
84
  # Processes scanner and notifier
10
85
  class ProcessScanner
11
86
  include Splash::Constants
@@ -17,14 +92,6 @@ module Splash
17
92
  def initialize
18
93
  @processes_target = Marshal.load(Marshal.dump(get_config.processes))
19
94
  @config = get_config
20
- @registry = Prometheus::Client::Registry::new
21
- @metric_status = Prometheus::Client::Gauge.new(:process_status, docstring: 'SPLASH metric process status', labels: [:process ])
22
- @metric_cpu_percent = Prometheus::Client::Gauge.new(:process_cpu_percent, docstring: 'SPLASH metric process CPU usage in percent', labels: [:process ])
23
- @metric_mem_percent = Prometheus::Client::Gauge.new(:process_mem_percent, docstring: 'SPLASH metric process MEM usage in percent', labels: [:process ])
24
- @registry.register(@metric_status)
25
- @registry.register(@metric_cpu_percent)
26
- @registry.register(@metric_mem_percent)
27
-
28
95
  end
29
96
 
30
97
 
@@ -64,17 +131,21 @@ module Splash
64
131
  session = (options[:session]) ? options[:session] : log.get_session
65
132
  log.info "Sending metrics to Prometheus Pushgateway", session
66
133
  @processes_target.each do |item|
134
+ processrec = ProcessRecords::new item[:process]
67
135
  missing = (item[:status] == :missing)? 1 : 0
68
- log.item "Sending metrics for #{item[:process]}", session
69
136
  val = (item[:status] == :running )? 1 : 0
70
- @metric_status.set(val, labels: { process: item[:process] })
71
- @metric_cpu_percent.set(item[:cpu], labels: { process: item[:process] })
72
- @metric_mem_percent.set(item[:mem], labels: { process: item[:process] })
137
+ processrec.purge(item[:retention])
138
+ processrec.add_record :status => item[:status],
139
+ :cpu_percent => item[:cpu],
140
+ :mem_percent => item[:mem] ,
141
+ :process => item[:process]
142
+ processmonitor = ProcessNotifier::new({name: item[:process], status: val , cpu_percent: item[:cpu], mem_percent: item[:mem]})
143
+ if processmonitor.notify then
144
+ log.ok "Sending metrics for process #{item[:process]} to Prometheus Pushgateway", session
145
+ else
146
+ log.ko "Failed to send metrics for process #{item[:process]} to Prometheus Pushgateway", session
147
+ end
73
148
  end
74
- hostname = Socket.gethostname
75
- url = @config.prometheus_pushgateway_url
76
- Prometheus::Client::Push.new('Splash',hostname, url).add(@registry)
77
- log.ok "Sending to Prometheus PushGateway done.", session
78
149
  return {:case => :quiet_exit }
79
150
  end
80
151
 
@@ -0,0 +1,229 @@
1
+ # coding: utf-8
2
+
3
+ # base Splash Module
4
+ module Splash
5
+
6
+ # Transfers module
7
+ module Transfers
8
+
9
+ include Splash::Config
10
+ include Splash::Loggers
11
+ include Splash::Helpers
12
+
13
+
14
+
15
+ class TxNotifier
16
+ @@registry = Prometheus::Client::Registry::new
17
+ @@metric_nbfiles = Prometheus::Client::Gauge.new(:txnbfiles, docstring: 'SPLASH metric transfer number of files')
18
+ @@metric_nbfiles_failed = Prometheus::Client::Gauge.new(:txnbfilesfailed, docstring: 'SPLASH metric transfer number of failed files')
19
+ @@metric_time = Prometheus::Client::Gauge.new(:txtime, docstring: 'SPLASH metric transfer execution time')
20
+ @@registry.register(@@metric_nbfiles)
21
+ @@registry.register(@@metric_nbfiles_failed)
22
+ @@registry.register(@@metric_time)
23
+
24
+ def initialize(options={})
25
+ @config = get_config
26
+ @url = @config.prometheus_pushgateway_url
27
+ @name = "tx_#{options[:name].to_s}"
28
+ @nbfiles = options[:nbfiles]
29
+ @nbfiles_failed = options[:nbfiles_failed]
30
+ @time = options[:time]
31
+ end
32
+
33
+ # send metrics to Prometheus PushGateway
34
+ # @return [Bool]
35
+ def notify
36
+ unless verify_service url: @url then
37
+ return { :case => :service_dependence_missing, :more => "Prometheus Notification not send."}
38
+ end
39
+ @@metric_nbfiles.set(@nbfiles)
40
+ @@metric_nbfiles_failed.set(@nbfiles_failed)
41
+ @@metric_time.set(@time)
42
+ hostname = Socket.gethostname
43
+ return Prometheus::Client::Push.new(@name, hostname, @url).add(@@registry)
44
+ end
45
+
46
+ end
47
+
48
+
49
+
50
+ class TxRecords
51
+ include Splash::Backends
52
+ include Splash::Constants
53
+
54
+ def initialize(name)
55
+ @name = name
56
+ @backend = get_backend :transfers_trace
57
+ end
58
+
59
+ def purge(retention)
60
+ retention = {} if retention.nil?
61
+ if retention.include? :hours then
62
+ adjusted_datetime = DateTime.now - retention[:hours].to_f / 24
63
+ elsif retention.include? :hours then
64
+ adjusted_datetime = DateTime.now - retention[:days].to_i
65
+ else
66
+ adjusted_datetime = DateTime.now - DEFAULT_RETENTION
67
+ end
68
+
69
+ data = get_all_records
70
+
71
+ data.delete_if { |item|
72
+ DateTime.parse(item.keys.first) <= (adjusted_datetime)}
73
+ @backend.put key: @name, value: data.to_yaml
74
+ end
75
+
76
+ def add_record(record)
77
+ data = get_all_records
78
+ data.push({ DateTime.now.to_s => record })
79
+ @backend.put key: @name, value: data.to_yaml
80
+ end
81
+
82
+ def get_all_records(options={})
83
+ return (@backend.exist?({key: @name}))? YAML::load(@backend.get({key: @name})) : []
84
+ end
85
+
86
+ def check_prepared
87
+ return :never_run_prepare unless @backend.exist?({key: @name})
88
+ return :never_prepare unless YAML::load(@backend.get({key: @name})).select {|item|
89
+ record =item.keys.first
90
+ value=item[record]
91
+ value[:status] == :prepared
92
+ }.count > 0
93
+ return :prepared
94
+ end
95
+
96
+ end
97
+
98
+ def run_txs(options = {})
99
+ log = get_logger
100
+ log.info 'Running Transfers'
101
+ count=0
102
+ get_config.transfers.each do |record|
103
+ txrec = TxRecords::new record[:name]
104
+ txrec.purge(record[:retention])
105
+ log.item "Execute : #{record[:name]}, #{record[:desc]}"
106
+ case txrec.check_prepared
107
+ when :prepared
108
+ if record[:type] == :push then
109
+ unless push record
110
+ count += 1
111
+ end
112
+ elsif record[:type] == :pull then
113
+ unless pull record
114
+ count += 1
115
+ end
116
+ else
117
+ log.ko "Transfer type unkown"
118
+ count += 1
119
+ end
120
+ when :never_prepare
121
+ log.ko "#{record[:name]} : Never prepared, ignored"
122
+ txrec.add_record :status => :never_prepared
123
+ count += 1
124
+ when :never_run_prepare
125
+ log.ko "#{record[:name]} : Never Executed and never prepared, ignored"
126
+ txrec.add_record :status => :never_prepared
127
+ count += 1
128
+ end
129
+ end
130
+ return {:case => :error_exit, :more => "#{count} Transfer(s) failed"} if count > 0
131
+ return {:case => :quiet_exit }
132
+ end
133
+
134
+
135
+
136
+ def prepare_tx(name)
137
+ log = get_logger
138
+ record = get_config.transfers.select { |item| item[:name] == name.to_sym }.first
139
+ home = Etc.getpwnam(record[:local][:user]).dir
140
+ identity = ::File::readlines("#{home}/.ssh/id_rsa.pub").first.chomp
141
+ folder = {:mode => "755",
142
+ :owner => record[:local][:user] ,
143
+ :group => Etc.getgrgid(Etc.getpwnam(record[:local][:user]).gid).name,
144
+ :name => record[:local][:path],
145
+ :path => record[:local][:path]}
146
+ log.info "Ensure local folder : #{record[:local][:path]}"
147
+ make_folder(folder) unless verify_folder(folder).empty?
148
+ begin
149
+ log.info "Ensure RSA Key sharing for local user : #{record[:local][:user]} to remote user : #{record[:remote][:user]}@#{record[:remote][:host]}"
150
+ ssh = Net::SSH.start(record[:remote][:host],record[:remote][:user])
151
+ output = ssh.exec!(%[
152
+ /bin/bash -cl '
153
+ umask 077;
154
+ mkdir #{record[:remote][:path]};
155
+ test -d ~/.ssh || mkdir ~/.ssh;
156
+ if [ ! -f ~/.ssh/authorized_keys -o `grep "#{identity}" ~/.ssh/authorized_keys 2> /dev/null | wc -l` -eq 0 ]; then echo "#{identity}" >> ~/.ssh/authorized_keys
157
+ fi'])
158
+ log.info "Prepare remote folder : #{record[:remote][:path]}"
159
+ log.info "Prepare data file for transfer : #{record[:name]}"
160
+ txrec = TxRecords::new record[:name]
161
+ txrec.add_record :status => :prepared
162
+ log.ok "Transfer : #{record[:name]} prepared successfully"
163
+ return {:case => :quiet_exit }
164
+ rescue Interrupt
165
+ splash_exit case: :interrupt, more: "Remote command exection"
166
+ rescue TTY::Reader::InputInterrupt
167
+ splash_exit case: :interrupt, more: "Remote command exection"
168
+ end
169
+ end
170
+
171
+
172
+
173
+ def save_data
174
+
175
+ end
176
+
177
+
178
+
179
+ def push(record)
180
+ config = get_config
181
+ log = get_logger
182
+ txrec = TxRecords::new record[:name]
183
+ start = Time.now
184
+ res = true
185
+ count = 0
186
+ done =[]
187
+ start_date = DateTime.now.to_s
188
+ list = Dir.glob("#{record[:local][:path]}/#{record[:pattern]}")
189
+ count = list.count
190
+ log.arrow "Transfering #{count} file(s)"
191
+
192
+ begin
193
+ scp = Net::SCP.start(record[:remote][:host],record[:remote][:user])
194
+ list.each do|f|
195
+ log.arrow "Copy file : #{f} to #{record[:remote][:user]}@#{record[:remote][:host]}:#{record[:remote][:path]}"
196
+ scp.upload! f, record[:remote][:path]
197
+ done.push f
198
+ if record[:backup] then
199
+ log.arrow "File #{f} backuped"
200
+ FileUtils::mv(f, "#{f}.#{Time.now.getutc.to_i}")
201
+ else
202
+ FileUtils::unlink(f)
203
+ end
204
+ end
205
+
206
+ rescue
207
+ res = false
208
+ end
209
+
210
+ end_date = DateTime.now.to_s
211
+ time = Time.now - start
212
+ status = (res)? :success : :failure
213
+ txrec.add_record :status => status,
214
+ :end_date => end_date,
215
+ :time => time,
216
+ :count => count,
217
+ :wanted => list,
218
+ :done => done
219
+ count_failed = list.count - done.count
220
+ txmonitor = TxNotifier::new({name: record[:name], nbfiles: count,nbfiles_failed: count_failed, time: time})
221
+ if txmonitor.notify then
222
+ log.ok "Sending metrics to Prometheus Pushgateway"
223
+ else
224
+ log.ko "Failed to send metrics to Prometheus Pushgateway"
225
+ end
226
+ return res
227
+ end
228
+ end
229
+ end