mutx 0.2.2 → 0.2.3

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 5e6d51098762a59058ac78f8d555d4b1e1dde841
4
- data.tar.gz: 837b24fa28e238b47c02306fc7d3fe51082d2b96
3
+ metadata.gz: 59c6ec4325709306828982280037d2b948a596d6
4
+ data.tar.gz: 142bbcdf1c0f8153f909235e5b5e750cb0681bf5
5
5
  SHA512:
6
- metadata.gz: 033846539b9d85ba30524db05c7b0962e15518efc3165696e9e87fc523ad1cef1bdfeea2b96403c707928149cc49c882972d4a97aa68253f6a513a093c51b08c
7
- data.tar.gz: 7a29987b8674b5d012c07fad2bffdc049e6c052574e82aacd386b03d1f89a5607a73fbabefd2f64dbabd8739db4bd556460c3264616b196ac59b74a2d56da1f6
6
+ metadata.gz: 4ef36addee27851f1b8fb2fb6c85beba0cfe3326486cb0f256bcdc83ab0a30fe372752344286ca123bf33c015b5cfccd97c8750c53e082d559c9e1741a46a827
7
+ data.tar.gz: e11d4425d9b651ee628cec0b52c823e907b61fdc5bbc5192326e0b4a36f6e36beea99e9a347c1e3e79de49921fdb88847ce4bdd1596f7bc4b3e19b9ffe3fadb5
@@ -0,0 +1,45 @@
1
+ require 'colorize'
2
+ module Mutx
3
+ class CreateAlert < Thor::Group
4
+
5
+ include Thor::Actions
6
+
7
+ desc "Create an Alert in Mutx"
8
+ argument :name, type: :string, desc: 'alert name'
9
+
10
+ def self.source_root
11
+ File.dirname(__FILE__) + "/templates/"
12
+ end
13
+
14
+ def self.alert_folder
15
+ "#{Dir.pwd}/alerts"
16
+ end
17
+
18
+ def self.alert_filename(alert_name)
19
+ File.join(self.alert_folder, "#{alert_name}_alert.rb")
20
+ end
21
+
22
+ def check_alert_folder
23
+ unless Dir.exist? self.class.alert_folder
24
+ say "creating alert folder: #{self.class.alert_folder}".green
25
+ empty_directory(self.class.alert_folder)
26
+ else
27
+ say "alert folder exists ( #{self.class.alert_folder} )".green
28
+ end
29
+ end
30
+
31
+ def check_not_exist_alert
32
+ raise Error, "alert exists ( #{ self.class.alert_filename(name) } )" if File.exists? self.class.alert_filename(name)
33
+ end
34
+
35
+ def create_alarm
36
+ template 'mutx_alert.rb.tt', self.class.alert_filename(name)
37
+ end
38
+
39
+ def finish_message
40
+ say 'Alert created!'.green
41
+ say "please, edit: #{self.class.alert_filename(name)}".green
42
+ end
43
+
44
+ end
45
+ end
@@ -3,6 +3,7 @@
3
3
  require 'mutx'
4
4
  require 'sidekiq'
5
5
  require 'sidekiq/web'
6
+ require 'sidekiq/cron/web'
6
7
 
7
8
  #Sidekiq.configure_client do |config|
8
9
  # config.redis = { :url => 'redis://10.211.15.195:6379/0' }
@@ -0,0 +1,10 @@
1
+ # TODO cron: * * * * *
2
+ # TODO email: a email or emails
3
+ # TODO telegram: a group id
4
+
5
+ require 'mutx'
6
+ include Mutx::Alert::Script
7
+
8
+ # put your code here!
9
+
10
+ # write success! warning! or critical! to finish script
data/lib/mutx.rb CHANGED
@@ -13,6 +13,7 @@ require 'byebug'
13
13
  require 'digest'
14
14
  require 'basica'
15
15
  require 'sidetiq'
16
+ require 'sidekiq-cron'
16
17
 
17
18
  require_rel 'mutx'
18
19
  require_rel 'generators'
@@ -81,6 +82,11 @@ module Mutx
81
82
  Mutx::Commands.reset_tasks
82
83
  end
83
84
 
85
+ desc 'create_alert NAME', "Create a new alert"
86
+ def create_alert(name)
87
+ Mutx::Commands.create_alert(name)
88
+ end
89
+
84
90
  desc "Say bye to mutx", ""
85
91
  def bye
86
92
  if yes? "Are you sure to say bye to Mutx? (yes/no)"
@@ -0,0 +1,37 @@
1
+ # encoding: utf-8
2
+ require 'sidekiq'
3
+
4
+ module Mutx
5
+ module Workers
6
+ class AlertsWorker
7
+ include Sidekiq::Worker
8
+
9
+ sidekiq_options retry: false
10
+
11
+ def perform(args)
12
+ stringio = StringIO.new
13
+ @alert = Alert.find(name: args['name'])
14
+ status = nil
15
+ begin
16
+ PTY.spawn("ruby #{args['path']}") do |stdout, stdin, pid|
17
+ begin
18
+ stdout.each do |line|
19
+ stringio.puts line
20
+ end
21
+ rescue Errno::EIO
22
+ ensure
23
+ Process.wait pid
24
+ status = $?.exitstatus
25
+ end
26
+ end
27
+ rescue => e
28
+ logger.debug(e.message)
29
+ logger.debug(e.backtrace)
30
+ raise e
31
+ ensure
32
+ @alert.update_status(status, info: stringio.string)
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
@@ -30,9 +30,9 @@ module Mutx
30
30
 
31
31
  efective_command = []
32
32
  efective_command << Mutx::Support::Configuration.headless? if result.gui_task?
33
+ efective_command << result.custom_params_values
33
34
  efective_command << result.command
34
35
  efective_command << "-f pretty -f html -o mutx/temp/#{result.mutx_report_file_name}" if result.is_cucumber?
35
- efective_command << result.custom_params_values
36
36
  efective_command << "_id=#{result.id}" # to use inside execution the possibility to add information to the result
37
37
  puts "[#{result.id}]| Command: #{efective_command.join(" ")}"
38
38
  result.mutx_command = efective_command.join(" ")
@@ -0,0 +1,23 @@
1
+ # encoding: utf-8
2
+ require 'telegramsender'
3
+
4
+ module Mutx
5
+ module Workers
6
+ class Notificator
7
+ include Sidekiq::Worker
8
+
9
+ def perform(type, destination, args= {})
10
+ simbolized = args.map { |k, v| [k.to_sym, v] }.to_h
11
+ self.send(type.to_sym, destination, **simbolized)
12
+ end
13
+
14
+ def telegram(group_id, message: '')
15
+ TelegramSender.send_message(group_id, message)
16
+ end
17
+
18
+ def email(mail_to, subject: '', body: '', attachment: nil)
19
+ # TODO
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,10 @@
1
+ # encoding: utf-8
2
+ module Mutx
3
+ module Commands
4
+ def self.create_alert(name)
5
+ begin
6
+ Mutx::CreateAlert.start([name])
7
+ end
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,18 @@
1
+
2
+ module Mutx
3
+ class Notification
4
+
5
+ def self.send_email(destination, subject: nil, body: nil, attachment: nil)
6
+ self.send(:email, destination, subject: subject, body: body, attachment: attachment)
7
+ end
8
+
9
+ def self.send_telegram(destination, message: '')
10
+ self.send(:telegram, destination, message: message)
11
+ end
12
+
13
+ def self.send(type, destination, options={})
14
+ Mutx::Workers::Notificator.perform_async(type, destination, options)
15
+ end
16
+
17
+ end
18
+ end
@@ -54,6 +54,11 @@ module Mutx
54
54
  tests_run: '/tests/:test_name/run',
55
55
  tests_status: '/tests/:test_name/status',
56
56
 
57
+ alerts_index: '/alerts',
58
+ alerts_show: '/alerts/:alert_name',
59
+ alerts_on: '/alerts/:alert_name/run',
60
+ alerts_off: '/alerts/:alert_name/stop',
61
+
57
62
  features_index: '/features',
58
63
  features_file: '/features/file',
59
64
 
@@ -0,0 +1,174 @@
1
+ module Mutx
2
+ class Alert
3
+
4
+ module Script
5
+
6
+ def ok!
7
+ puts "Result: OK"
8
+ exit STATUS[:ok]
9
+ end
10
+
11
+ def skip!
12
+ puts "Result: SKIP"
13
+ exit STATUS[:skip]
14
+ end
15
+
16
+ def unknown!
17
+ puts "Result: UNKNOWN"
18
+ exit STATUS[:unknown]
19
+ end
20
+
21
+ def warning!
22
+ puts "Result: WARNING"
23
+ exit STATUS[:warning]
24
+ end
25
+
26
+ def critical!
27
+ puts "Result: CRITICAL"
28
+ exit STATUS[:critical]
29
+ end
30
+
31
+ end
32
+
33
+ ALERT_FOLDER = File.join("#{Dir.pwd}", 'alerts')
34
+
35
+ STATUS = {
36
+ ok: 0,
37
+ unknown: 1,
38
+ skip: 2,
39
+ warning: 3,
40
+ critical: 4
41
+ }
42
+
43
+ def self.all
44
+ alerts = Dir.entries(ALERT_FOLDER).select { |file|
45
+ file.match(/_alert.rb$/)
46
+ }.map {|file| self.new(file) }
47
+ end
48
+
49
+ def self.find(args={})
50
+ if args.is_a? Hash
51
+ filename = "#{args[:name]}_alert.rb"
52
+ if File.exists?(File.join(ALERT_FOLDER, filename))
53
+ return self.new(filename)
54
+ else
55
+ return nil
56
+ end
57
+ else
58
+ return nil
59
+ end
60
+ end
61
+
62
+ attr_reader :filename, :attributes, :job, :notification
63
+
64
+ def initialize(filename)
65
+ @filename = filename
66
+ extract_info
67
+ @enqueue = true
68
+ @job = Sidekiq::Cron::Job.find(name) || ((@enqueue = false) || create_job )
69
+ end
70
+
71
+ def name
72
+ filename.gsub('_alert.rb', '')
73
+ end
74
+
75
+ def email
76
+ attributes['email']
77
+ end
78
+
79
+ def telegram
80
+ attributes['telegram']
81
+ end
82
+
83
+ def slack
84
+ attributes['slack']
85
+ end
86
+
87
+ def cron
88
+ attributes['cron']
89
+ end
90
+
91
+ def last_enqueue
92
+ @job.last_enqueue_time
93
+ end
94
+
95
+ def enqueue?
96
+ @enqueue
97
+ end
98
+
99
+ def on!
100
+ if @job.valid?
101
+ @job.save
102
+ @enqueue = true
103
+ end
104
+ return self.enqueue?
105
+ end
106
+
107
+ def off!
108
+ @job.destroy
109
+ @enqueue = false
110
+ end
111
+
112
+ def status
113
+ STATUS.invert[self.result.to_i] || :unknown
114
+ end
115
+
116
+ def update_status(a_new_status, info: nil)
117
+ last_result = self.result
118
+ return if ((last_result.to_s == a_new_status.to_s) or (a_new_result.to_i == STATUS[:skip]))
119
+ self.result = a_new_status
120
+ notify(info) if last_result
121
+ end
122
+
123
+ def result
124
+ Sidekiq.redis do |redis|
125
+ redis.get("alerts:#{name}")
126
+ end
127
+ end
128
+
129
+ def result=(value)
130
+ Sidekiq.redis do |redis|
131
+ redis.set("alerts:#{name}", value.to_s)
132
+ end
133
+ end
134
+
135
+ private
136
+ def extract_info
137
+ content = File.read(File.join(ALERT_FOLDER, filename))
138
+ lines = content.split("\n").select {|line| line.match(/^\s*\#\s\w[\w_]+\:.+/) && !line.match(/TODO/)}
139
+ attributes = lines.map{ |line| line.gsub(/^\s*\#/,'').split(':',2).map(&:strip) }
140
+ @attributes = Hash[attributes]
141
+ @notification = @attributes.select do |k,v|
142
+ [:email, :slack, :telegram].include?(k.to_sym)
143
+ end
144
+ end
145
+
146
+ def create_job
147
+ Sidekiq::Cron::Job.new(name: name,
148
+ cron: attributes['cron'],
149
+ class: 'Mutx::Workers::AlertsWorker',
150
+ args: {
151
+ name: name,
152
+ file: filename,
153
+ path: File.join(ALERT_FOLDER, filename),
154
+ email: attributes['email']
155
+ })
156
+ end
157
+
158
+ def notify(info)
159
+ notify_telegram(self.telegram, info) if self.telegram
160
+ notify_email(self.email, info) if self.email
161
+ end
162
+
163
+ def notify_telegram(group_id, info)
164
+ return unless group_id
165
+ Notification.send_telegram(group_id, message: "Alert #{name} is #{status.upcase}")
166
+ Notification.send_telegram(group_id, message: info)
167
+ end
168
+
169
+ def notify_email(mail_to, info)
170
+ return unless mail_to
171
+ Notification.send_email(mail_to, subject: "Alert #{name} is #{status.upcase}", body: info)
172
+ end
173
+ end
174
+ end
data/lib/mutx/routes.rb CHANGED
@@ -36,6 +36,7 @@ module Mutx
36
36
  res.redirect path_for(:tasks_index)
37
37
  end
38
38
  on('admin') { run Mutx::Routes::Admin::Routes }
39
+ on('alerts') { run Mutx::Routes::Alerts::Routes }
39
40
  on('tasks') { run Mutx::Routes::Tasks::Routes }
40
41
  on('tests') { run Mutx::Routes::Tests::Routes }
41
42
  on('task-results') { run Mutx::Routes::TaskResults::Routes }
@@ -0,0 +1,40 @@
1
+ # encoding: utf-8
2
+
3
+ module Mutx
4
+ module Routes
5
+ module Alerts
6
+ class Routes < App
7
+ define do
8
+ on get do
9
+ on ":alert_name" do |alert_name|
10
+ res.write view('Alert', alert: Alert.find(name: alert_name))
11
+ end
12
+
13
+ on root do
14
+ res.write view('Alerts', alerts: Alert.all)
15
+ end
16
+ end
17
+
18
+ on post do
19
+ on ':alert_name/run' do |alert_name|
20
+ alert = Alert.find(name: alert_name)
21
+ if alert.on!
22
+ flash[:info] = "Alert add success"
23
+ else
24
+ flash[:error] = alert.job.errors.join(', ')
25
+ end
26
+ res.redirect path_for(:alerts_index)
27
+ end
28
+
29
+ on ':alert_name/stop' do |alert_name|
30
+ alert = Alert.find(name: alert_name)
31
+ alert.off!
32
+ flash[:info] = "Alert off success"
33
+ res.redirect path_for(:alerts_index)
34
+ end
35
+ end
36
+ end
37
+ end
38
+ end
39
+ end
40
+ end
data/lib/mutx/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Mutx
2
- VERSION = "0.2.2"
2
+ VERSION = "0.2.3"
3
3
  end
@@ -0,0 +1,45 @@
1
+ <td>
2
+ {{ alert.name }}
3
+ </td>
4
+ <td>
5
+ {{ alert.cron }}
6
+ </td>
7
+ <td>
8
+ % alert.notification.each do |type, destination|
9
+ <b>{{ type}}:</b> {{destination}}<br/>
10
+ % end
11
+ </td>
12
+
13
+ % if alert.enqueue?
14
+ <td>
15
+ <span class="label label-success"> Running at {{ alert.job.cron }}</span>
16
+ </td>
17
+
18
+ <td>
19
+ {{ alert.last_enqueue.strftime("at %I:%M%p") if alert.last_enqueue }}
20
+ </td>
21
+
22
+ <td>
23
+ <span class="label label-{{ { success: 'success', warning: 'warning', critical: 'danger', unknown: 'primary' }[alert.status] }}"> {{ alert.status }} </span>
24
+
25
+ </td>
26
+
27
+ <td>
28
+ <form name="{{ alert.name }}" method="POST" action="{{ path_for(:alerts_off, alert_name: alert.name )}}" >
29
+
30
+ <button type="submit">{{ Mutx::View.icon_for("off") }}</button>
31
+ </form>
32
+ </td>
33
+ % else
34
+ <td>
35
+ <span class="label label-danger"> Stopped </span>
36
+ </td>
37
+
38
+ <td/>
39
+ <td/>
40
+ <td>
41
+ <form name="{{ alert.name }}" method="POST" action="{{ path_for(:alerts_on, alert_name: alert.name)}}" >
42
+ <button type="submit">{{ Mutx::View.icon_for("on") }}</button>
43
+ </form>
44
+ </td>
45
+ % end
@@ -0,0 +1,25 @@
1
+ <div class="panel panel-default">
2
+ <div class="panel-heading">
3
+ <h4>{{section.capitalize}}</h4>
4
+ </div>
5
+ <table class="table table-striped table-hover">
6
+ <thead>
7
+ <tr>
8
+ <th>Name</th>
9
+ <th>Cron</th>
10
+ <th>Notificate to</th>
11
+ <th>Status</th>
12
+ <th>Last Exec.</th>
13
+ <th>Last Result</th>
14
+ <th/>
15
+ </tr>
16
+ </thead>
17
+ <tbody>
18
+ % alerts.each do |alert|
19
+ <tr>
20
+ {{ partial('alerts/_alert', alert: alert) }}
21
+ </tr>
22
+ % end
23
+ </tbody>
24
+ </table>
25
+ </div>
@@ -0,0 +1,8 @@
1
+ {{alert.name}}
2
+ <br/>
3
+
4
+ {{alert.filename}}
5
+
6
+ <br/>
7
+
8
+ {{alert.attributes}}
@@ -24,6 +24,9 @@ module Mutx
24
24
  'Tasks' => "tasks/index",
25
25
  'Task' => "tasks/show",
26
26
 
27
+ 'Alerts' => 'alerts/index',
28
+ 'Alert' => 'alerts/show',
29
+
27
30
  'Task Results' => 'task_results/index',
28
31
 
29
32
  "Results"=> "results/index",
data/mutx.gemspec CHANGED
@@ -42,6 +42,7 @@ Gem::Specification.new do |spec|
42
42
  spec.add_dependency 'basica'
43
43
  spec.add_dependency 'sidetiq'
44
44
  spec.add_dependency 'chronic'
45
+ spec.add_dependency 'sidekiq-cron'
45
46
  #spec.add_dependency 'zip'
46
47
 
47
48
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mutx
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.2
4
+ version: 0.2.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Roman Rodriguez
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-03-07 00:00:00.000000000 Z
11
+ date: 2017-03-10 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: thor
@@ -304,6 +304,20 @@ dependencies:
304
304
  - - ">="
305
305
  - !ruby/object:Gem::Version
306
306
  version: '0'
307
+ - !ruby/object:Gem::Dependency
308
+ name: sidekiq-cron
309
+ requirement: !ruby/object:Gem::Requirement
310
+ requirements:
311
+ - - ">="
312
+ - !ruby/object:Gem::Version
313
+ version: '0'
314
+ type: :runtime
315
+ prerelease: false
316
+ version_requirements: !ruby/object:Gem::Requirement
317
+ requirements:
318
+ - - ">="
319
+ - !ruby/object:Gem::Version
320
+ version: '0'
307
321
  - !ruby/object:Gem::Dependency
308
322
  name: bundler
309
323
  requirement: !ruby/object:Gem::Requirement
@@ -375,6 +389,7 @@ files:
375
389
  - img/mutx_logo.svg
376
390
  - lib/.DS_Store
377
391
  - lib/generators/.DS_Store
392
+ - lib/generators/create_alert.rb
378
393
  - lib/generators/task_rack.rb
379
394
  - lib/generators/templates/.DS_Store
380
395
  - lib/generators/templates/Gemfile.tt
@@ -384,6 +399,7 @@ files:
384
399
  - lib/generators/templates/cronned_task.rb.tt
385
400
  - lib/generators/templates/mutx.conf.tt
386
401
  - lib/generators/templates/mutx.log.tt
402
+ - lib/generators/templates/mutx_alert.rb.tt
387
403
  - lib/generators/templates/mutx_body_template.html.erb
388
404
  - lib/generators/templates/mutx_body_template.html.erb.zip
389
405
  - lib/generators/templates/mutx_template.html.erb
@@ -407,15 +423,18 @@ files:
407
423
  - lib/mutx/background_jobs/.DS_Store
408
424
  - lib/mutx/background_jobs/sidekiq.rb
409
425
  - lib/mutx/background_jobs/workers/.DS_Store
426
+ - lib/mutx/background_jobs/workers/alerts_worker.rb
410
427
  - lib/mutx/background_jobs/workers/connectivity_check.rb
411
428
  - lib/mutx/background_jobs/workers/email_sender.rb
412
429
  - lib/mutx/background_jobs/workers/executor.rb
413
430
  - lib/mutx/background_jobs/workers/garbage_cleaner.rb
414
431
  - lib/mutx/background_jobs/workers/listener.rb
415
432
  - lib/mutx/background_jobs/workers/mutx_cron.rb
433
+ - lib/mutx/background_jobs/workers/notificator.rb
416
434
  - lib/mutx/background_jobs/workers/update_started.rb
417
435
  - lib/mutx/commands/.DS_Store
418
436
  - lib/mutx/commands/bye.rb
437
+ - lib/mutx/commands/create_alert.rb
419
438
  - lib/mutx/commands/help.rb
420
439
  - lib/mutx/commands/install.rb
421
440
  - lib/mutx/commands/reset.rb
@@ -438,7 +457,9 @@ files:
438
457
  - lib/mutx/lib/middlewares/flash_middleware.rb
439
458
  - lib/mutx/lib/middlewares/logger_middleware.rb
440
459
  - lib/mutx/lib/monkey_patch.rb
460
+ - lib/mutx/lib/notification.rb
441
461
  - lib/mutx/lib/paths.rb
462
+ - lib/mutx/models/alert.rb
442
463
  - lib/mutx/platforms/ruby.rb
443
464
  - lib/mutx/public/css/bootstrap.min.css
444
465
  - lib/mutx/public/css/font-awesome.min.css
@@ -456,6 +477,7 @@ files:
456
477
  - lib/mutx/routes/admin_routes/custom_params_routes.rb
457
478
  - lib/mutx/routes/admin_routes/repositories_routes.rb
458
479
  - lib/mutx/routes/admin_routes/tasks_routes.rb
480
+ - lib/mutx/routes/alerts_routes.rb
459
481
  - lib/mutx/routes/api_routes.rb
460
482
  - lib/mutx/routes/api_routes/custom_params_routes.rb
461
483
  - lib/mutx/routes/api_routes/input_routes.rb
@@ -520,6 +542,9 @@ files:
520
542
  - lib/mutx/view/admin/tasks/index.mote
521
543
  - lib/mutx/view/admin/tasks/new.mote
522
544
  - lib/mutx/view/admin/tasks/show.mote
545
+ - lib/mutx/view/alerts/_alert.mote
546
+ - lib/mutx/view/alerts/index.mote
547
+ - lib/mutx/view/alerts/show.mote
523
548
  - lib/mutx/view/body.mote
524
549
  - lib/mutx/view/custom-params/_custom_params.mote
525
550
  - lib/mutx/view/custom-params/types/json.mote