notifu 1.6.3 → 1.6.4

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: 4854010e7da3616c5a97453edc92f874bee9e45f
4
- data.tar.gz: df68b5961047d135c801ae52905a5c16773ecb2a
3
+ metadata.gz: 3675e110c2b3899f1cb8a54bab95fc452b42eba6
4
+ data.tar.gz: 540012ec1cd765b36e8cfe390fa5528fe8f15032
5
5
  SHA512:
6
- metadata.gz: e2bb261159095a91c8a61581827d9b440b8080c1bcbc45a0a0c4ef04f99fd0e4b9ce4827b20e99c8e0271456e3193b53a9ea86c85ddec0a022e2d7551422ccb9
7
- data.tar.gz: 2e097437c9acd94cb1589235697af481300ef7e26f76e293cab3851e17616a2f5bffc659aba9a2d1cb8737b8c87d951a9539e04f08345584ab87d545503d305a
6
+ metadata.gz: 902f012ad82d980285c8f010bbf508ba1963f1ef03c835aa585324a201b14e788367c8e7b847bf2961350c9c4882a5720fe8d9d7fd5121a22282c627b48fdf4f
7
+ data.tar.gz: f8b27fa397401295ffad30e762a1b4d9ee519f6d85b24b2b38242c41a70198768f7816897660c3ce0e3ec77b44ecd4426407b85233286b2d802b17d92aebefb8
@@ -7,24 +7,11 @@ module Notifu
7
7
  self.retry = 3
8
8
 
9
9
  def act
10
- data = OpenStruct.new({
11
- notifu_id: self.issue.notifu_id,
12
- host: self.issue.host,
13
- message: self.issue.message,
14
- service: self.issue.service,
15
- status: self.issue.code.to_state,
16
- first_event: Time.at(self.issue.time_created.to_i),
17
- duration: (Time.now.to_i - self.issue.time_created.to_i).duration,
18
- occurrences_count: self.issue.occurrences_count,
19
- occurrences_trigger: self.issue.occurrences_trigger
20
- })
21
- message = ERB.new(self.template).result(data.instance_eval {binding})
22
-
23
10
  self.contacts.each do |contact|
24
11
  cell = contact.cell
25
- template = ERB.new File.new("sms.erb").read, nil, "%"
26
- message = "template.result(self.issue)"
27
-
12
+ tmpl = contact.sms_template
13
+ tmpl ||= default_template
14
+ message = self.apply_template tmpl
28
15
  # send message to sms-bridge
29
16
  socket = TCPSocket.new Notifu::CONFIG[:actors][:gammu_sms_bridge][:host], Notifu::CONFIG[:actors][:gammu_sms_bridge][port]
30
17
  socket.send contact.cell.to_s + "--" + message
@@ -33,9 +20,6 @@ module Notifu
33
20
  end
34
21
  end
35
22
 
36
- def template
37
- "<%= data[:status] %> [<%= data[:host] %>/<%= data[:service] %>]: (<%= data[:message] %>) <%= data[:duration] %> [<%= data[:notifu_id] %>]"
38
- end
39
23
  end
40
24
  end
41
- end
25
+ end
@@ -3,7 +3,6 @@ module Notifu
3
3
  class Pagerduty < Notifu::Actor
4
4
 
5
5
  require 'excon'
6
- require 'erb'
7
6
 
8
7
  self.name = "pagerduty"
9
8
  self.desc = "Sends event to pagerduty"
@@ -16,11 +15,12 @@ module Notifu
16
15
  description: self.text,
17
16
  incident_key: self.issue.notifu_id,
18
17
  details: {
19
- status: self.issue.code.to_state,
20
- dc: self.issue.datacenter,
21
18
  host: self.issue.host,
19
+ address: self.issue.address,
22
20
  service: self.issue.service,
23
21
  message: self.issue.message,
22
+ status: self.issue.code.to_state,
23
+ datacenter: self.issue.datacenter,
24
24
  first_event: Time.at(self.issue.time_created.to_i),
25
25
  },
26
26
  client: "Sensu",
@@ -28,40 +28,31 @@ module Notifu
28
28
  }
29
29
  end
30
30
 
31
- def text
32
- data = OpenStruct.new({
33
- notifu_id: self.issue.notifu_id,
34
- datacenter: self.issue.datacenter,
35
- host: self.issue.host,
36
- service: self.issue.service,
37
- message: self.issue.message,
38
- status: self.issue.code.to_state
39
- })
40
- ERB.new(self.template).result(data.instance_eval {binding})
31
+ def text(c)
32
+ t = c.pagerduty_template
33
+ t ||= self.default_template
34
+ self.apply_template t
41
35
  end
42
36
 
43
- def template
44
- "<%= data[:status] %> [<%= data[:datacenter] %>/<%= data[:host] %>/<%= data[:service] %>]: <%= data[:message] %>"
45
- end
46
37
 
47
38
  def act
48
39
  type = "resolve" if self.issue.code.to_i == 0
49
40
  type ||= "trigger"
50
41
 
51
42
  self.contacts.each do |contact|
43
+ contact.pagerduty_id || next
44
+
52
45
  begin
53
- c = contact.pagerduty_id
54
- rescue
55
- c = false
46
+ Excon.post(Notifu::CONFIG[:actors][:pagerduty][:url],
47
+ tcp_nodelay: true,
48
+ headers: { "ContentType" => "application/json" },
49
+ body: self.post_data(type, c).to_json,
50
+ expects: [ 200 ],
51
+ idempotent: true,
52
+ )
53
+ rescue Exception => e
54
+ log "error", "Failed to send event to PagerDuty - #{e.class}: #{e.message}"
56
55
  end
57
-
58
- Excon.post(Notifu::CONFIG[:actors][:pagerduty][:url],
59
- tcp_nodelay: true,
60
- headers: { "ContentType" => "application/json" },
61
- body: self.post_data(type, c).to_json,
62
- expects: [ 200 ],
63
- idempotent: true,
64
- ) if c
65
56
  end
66
57
  end
67
58
 
@@ -3,19 +3,18 @@ module Notifu
3
3
  class Slack < Notifu::Actor
4
4
 
5
5
  require 'excon'
6
- require 'erb'
7
6
 
8
7
  self.name = "slack"
9
8
  self.desc = "Notifies to Slack channel via Webhook"
10
9
  self.retry = 3
11
10
 
12
- def post_data(rich = false)
11
+ def post_data(template, rich)
13
12
  return {
14
13
  username: "notifu",
15
14
  icon_emoji: ":loudspeaker:",
16
15
  attachments: [
17
16
  {
18
- fallback: self.text(self.fallback_template),
17
+ fallback: self.apply_template(self.fallback_template),
19
18
  color: self.color,
20
19
  title: "#{self.issue.host} - #{self.issue.service}",
21
20
  title_link: "#{Notifu::CONFIG[:uchiwa_url]}/#/client/#{self.issue.datacenter}/#{self.issue.host}?check=#{self.issue.service}",
@@ -34,14 +33,27 @@ module Notifu
34
33
  ]
35
34
  }
36
35
  ]
37
- } if rich
38
- return {
39
- username: "notifu",
40
- icon_emoji: ":loudspeaker:",
41
- text: self.text(self.template)
42
- }
36
+ } if rich != nil
37
+
38
+ template ||= self.default_template
39
+ return { username: "notifu", icon_emoji: ":loudspeaker:", text: self.text }
40
+ end
41
+
42
+ def text(c)
43
+ t = c.slack_template
44
+ t ||= self.default_template
45
+ self.apply_template t
46
+ end
47
+
48
+ def default_template
49
+ "#{self.status_icon} *<<%= uchiwa_url %>|<%= datacenter %>/<%= host %>>* <%= address %> #{self.service_icon} *<%= service %>* - <%= message %> _<%= duration %>_"
50
+ end
51
+
52
+ def fallback_template
53
+ "<%= status %> | <%= datacenter%>/<%= host %>/<%= service %> - <%= message %>"
43
54
  end
44
55
 
56
+
45
57
  def color
46
58
  case self.issue.code.to_i
47
59
  when 0
@@ -76,50 +88,25 @@ module Notifu
76
88
  @service_icon ||= ":gear:"
77
89
  end
78
90
 
79
- # fallback simple message (templated, see below)
80
- def text(tmpl)
81
- data = OpenStruct.new({
82
- notifu_id: self.issue.notifu_id,
83
- datacenter: self.issue.datacenter,
84
- host: self.issue.host,
85
- address: self.issue.address,
86
- service: self.issue.service,
87
- message: self.issue.message,
88
- status: self.issue.code.to_state,
89
- duration: (Time.now.to_i - self.issue.time_created.to_i).duration,
90
- uchiwa_url: "#{Notifu::CONFIG[:uchiwa_url]}/#/client/#{self.issue.datacenter}/#{self.issue.host}?check=#{self.issue.service}",
91
- service_icon: self.service_icon,
92
- status_icon: self.status_icon
93
- })
94
- ERB.new(tmpl).result(data.instance_eval {binding})
95
- end
96
-
97
- # template for fallback message
98
- def fallback_template
99
- "*<%= data[:status] %>* <%= data[:datacenter]%> <%= data[:host] %> <%= data[:service] %> - <%= data[:message] %> (<%= data[:duration] %>) <%= data[:uchiwa_url] %>"
100
- end
101
-
102
- # template for plain message
103
- def template
104
- "<%= data[:status_icon] %> *<<%= data[:uchiwa_url] %>|<%= data[:datacenter] %>/<%= data[:host] %>>* <%= data[:address] %> <%= data[:service_icon] %> *<%= data[:service] %>* - <%= data[:message] %> _<%= data[:duration] %>_"
105
- end
106
-
107
91
  def act
108
92
  self.contacts.each do |contact|
93
+ if contact.slack_id != nil
94
+ data = self.post_data(contact.slack_template, contact.slack_rich).merge({ channel: contact.slack_id })
95
+ else
96
+ data = self.post_data(contact.slack_template, contact.slack_rich)
97
+ end
98
+
109
99
  begin
110
- data = { channel: contact.slack_id }.merge(self.post_data(contact.slack_rich)) if contact.slack_rich
111
- data ||= { channel: contact.slack_id }.merge(self.post_data)
112
- rescue
113
- data = self.post_data
100
+ Excon.post(Notifu::CONFIG[:actors][:slack][:url],
101
+ tcp_nodelay: true,
102
+ headers: { "ContentType" => "application/json" },
103
+ body: data.to_json,
104
+ expects: [ 200 ],
105
+ idempotent: true
106
+ )
107
+ rescue Exception => e
108
+ log "error", "Failed to send message to Slack - #{e.class}: #{e.message}"
114
109
  end
115
- puts data.to_yaml
116
- Excon.post(Notifu::CONFIG[:actors][:slack][:url],
117
- tcp_nodelay: true,
118
- headers: { "ContentType" => "application/json" },
119
- body: data.to_json,
120
- expects: [ 200 ],
121
- idempotent: true
122
- )
123
110
  end
124
111
  end
125
112
 
@@ -2,7 +2,6 @@ module Notifu
2
2
  module Actors
3
3
  class Smtp < Notifu::Actor
4
4
 
5
- require 'ostruct'
6
5
  require 'mail'
7
6
 
8
7
  self.name = "smtp"
@@ -10,23 +9,12 @@ module Notifu
10
9
  self.retry = 2
11
10
 
12
11
  def act
13
- data = OpenStruct.new({
14
- notifu_id: self.issue.notifu_id,
15
- host: self.issue.host,
16
- message: self.issue.message,
17
- service: self.issue.service,
18
- status: self.issue.code.to_state,
19
- first_event: Time.at(self.issue.time_created.to_i),
20
- duration: (Time.now.to_i - self.issue.time_created.to_i).duration,
21
- occurrences_count: self.issue.occurrences_count,
22
- occurrences_trigger: self.issue.occurrences_trigger
23
- })
24
12
  contacts = self.contacts.map { |contact| "#{contact.full_name} <#{contact.mail}>"}
25
- text_message = ERB.new(self.text_template).result(data.instance_eval {binding})
26
- html_message = ERB.new(self.html_template).result(data.instance_eval {binding})
13
+ text_message = self.apply_template(self.text_template)
14
+ html_message = self.apply_template(self.html_template)
27
15
  mail = Mail.new do
28
16
  from Notifu::CONFIG[:actors][:smtp][:from]
29
- subject "#{data[:status]}/#{data[:host]}/#{data[:service]}"
17
+ subject "#{self.issue.code.to_state]}: #{self.issue.host]}/#{self.issue.service]}"
30
18
  to contacts
31
19
  text_part do
32
20
  body text_message
@@ -42,32 +30,32 @@ module Notifu
42
30
 
43
31
  def text_template
44
32
  %{
45
- <%= data[:message] %>
46
-
47
- Notifu ID: <%= data[:notifu_id] %>
48
- Host: <%= data[:host] %>
49
- Service: <%= data[:service] %>
50
- Status: <%= data[:status] %>
51
- First event: <%= Time.at(data[:first_event]).to_s %>
52
- Duration: <%= data[:duration] %>
53
- Occurences: <%= data[:occurrences_count] %>/<%= data[:occurrences_trigger] %> (occured/trigger)
33
+ <%= message %>
34
+
35
+ Notifu ID: <%= notifu_id %>
36
+ Host: <%= host %>
37
+ Service: <%= service %>
38
+ Status: <%= status %>
39
+ First event: <%= Time.at(first_event).to_s %>
40
+ Duration: <%= duration %>
41
+ Occurences: <%= occurrences_count %>/<%= occurrences_trigger %> (occured/trigger)
54
42
  }
55
43
  end
56
44
 
57
45
  def html_template
58
46
  %{
59
- <h3><%= data[:message] %></h3><br/>
60
-
61
- <strong>Notifu ID: </strong><%= data[:notifu_id] %><br/>
62
- <strong>Host: </strong><%= data[:host] %><br/>
63
- <strong>Service: </strong><%= data[:service] %><br/>
64
- <strong>Status: </strong><%= data[:status] %><br/>
65
- <strong>First event: </strong><%= Time.at(data[:first_event]).to_s %><br/>
66
- <strong>Duration: </strong><%= data[:duration] %><br/>
67
- <strong>Occurences: </strong><%= data[:occurrences_count] %>/<%= data[:occurrences_trigger] %> (occured/trigger)<br/>
47
+ <h3><%= message %></h3><br/>
48
+
49
+ <strong>Notifu ID: </strong><%= notifu_id %><br/>
50
+ <strong>Host: </strong><%= host %><br/>
51
+ <strong>Service: </strong><%= service %><br/>
52
+ <strong>Status: </strong><%= status %><br/>
53
+ <strong>First event: </strong><%= Time.at(first_event).to_s %><br/>
54
+ <strong>Duration: </strong><%= duration %><br/>
55
+ <strong>Occurences: </strong><%= occurrences_count %>/<%= occurrences_trigger %> (occured/trigger)<br/>
68
56
  }
69
57
  end
70
58
 
71
59
  end
72
60
  end
73
- end
61
+ end
@@ -3,14 +3,13 @@ module Notifu
3
3
  class Stdout < Notifu::Actor
4
4
 
5
5
  self.name = "stdout"
6
- self.desc = "STDOUT notifier, useful for debug only"
6
+ self.desc = "STDOUT notifier, useful for testing"
7
7
  self.retry = 0
8
8
 
9
9
  def act
10
- puts self.issue.to_yaml
11
- puts self.contacts.to_yaml
10
+ puts self.apply_template(self.default_template)
12
11
  end
13
12
 
14
13
  end
15
14
  end
16
- end
15
+ end
@@ -3,7 +3,6 @@ module Notifu
3
3
  class TwilioCall < Notifu::Actor
4
4
 
5
5
  require 'excon'
6
- require 'erb'
7
6
 
8
7
  self.name = "twilio_call"
9
8
  self.desc = "POST requst to trigger phone-call"
data/lib/notifu/mixins.rb CHANGED
@@ -13,9 +13,9 @@ class Numeric
13
13
  days = hours / 24
14
14
 
15
15
  if days > 0
16
- "#{days}d, #{hours % 24}h"
16
+ "#{days}d, #{hours % 24}h, #{mins % 60}min, #{secs % 60}s"
17
17
  elsif hours > 0
18
- "#{hours}h, #{mins % 60}min"
18
+ "#{hours}h, #{mins % 60}min, #{secs % 60}s"
19
19
  elsif mins > 0
20
20
  "#{mins}min, #{secs % 60}s"
21
21
  elsif secs >= 0
@@ -6,9 +6,12 @@ module Notifu
6
6
  attribute :full_name
7
7
  attribute :cell
8
8
  attribute :mail
9
+ attribute :pagerduty_id
10
+ attribute :pagerduty_template
9
11
  attribute :slack_id
10
12
  attribute :slack_rich
11
- attribute :pagerduty_id
13
+ attribute :slack_template
14
+ attribute :sms_template
12
15
  index :name
13
16
  unique :name
14
17
 
data/lib/notifu/util.rb CHANGED
@@ -5,5 +5,14 @@ module Notifu
5
5
  self.instance_variable_set args.keys.first, args.values.first
6
6
  end
7
7
 
8
+ def self.log(prio, msg)
9
+ $logger.log prio, "JID-#{self.jid}: " + msg.to_s
10
+ end
11
+
12
+ def self.action_log event(worker)
13
+ $logger.action_log worker, event
14
+ end
15
+
16
+
8
17
  end
9
18
  end
@@ -21,6 +21,9 @@ module Notifu
21
21
  include Notifu::Util
22
22
  include Sidekiq::Worker
23
23
 
24
+ require 'erb'
25
+ require 'ostruct'
26
+
24
27
  attr_accessor :issue
25
28
  attr_accessor :contacts
26
29
 
@@ -41,14 +44,53 @@ module Notifu
41
44
  sidekiq_options :retry => self.retry
42
45
 
43
46
  def perform *args
44
- sleep 2
45
- load_data args
47
+ sleep 1
48
+ load_data args || return
46
49
  act
47
50
  end
48
51
 
49
52
  def load_data args
50
53
  self.issue = Notifu::Model::Issue.with(:notifu_id, args[0])
51
- self.contacts = args[1].map { |contact| Notifu::Model::Contact.with(:name, contact) }
54
+ if self.issue == nil
55
+ log "error", "Issue with NID #{args[0]} doesn't exist!"
56
+ return false
57
+ end
58
+ self.contacts = Array.new
59
+ args[1].each do |contact|
60
+ c = Notifu::Model::Contact.with(:name, contact)
61
+ self.contacts << c if c
62
+ end
63
+ return true
64
+ end
65
+
66
+ def apply_template t
67
+ @data ||= OpenStruct.new({
68
+ notifu_id: self.issue.notifu_id,
69
+ datacenter: self.issue.datacenter,
70
+ host: self.issue.host,
71
+ service: self.issue.service,
72
+ status: self.issue.code.to_state,
73
+ code: self.issue.code.to_s,
74
+ message: self.issue.message,
75
+ first_event: Time.at(self.issue.time_created.to_i),
76
+ duration: (Time.now.to_i - self.issue.time_created.to_i).duration,
77
+ interval: self.issue.interval.duration,
78
+ refresh: self.issue.refresh.duration,
79
+ occurrences_count: self.issue.occurrences_count,
80
+ occurrences_trigger: self.issue.occurrences_trigger,
81
+ uchiwa_url: "#{Notifu::CONFIG[:uchiwa_url]}/#/client/#{self.issue.datacenter}/#{self.issue.host}?check=#{self.issue.service}",
82
+ playbook: self.issue.playbook
83
+ })
84
+ begin
85
+ ERB.new(t).result(@data.instance_eval { binding })
86
+ rescue Exception => e
87
+ log "error", "Failed to render ERB template - #{e.class}: #{e.message}"
88
+ ERB.new(default_template).result(@data.instance_eval {binding})
89
+ end
90
+ end
91
+
92
+ def default_template
93
+ "<%= status %> [<%= dc %>/<%= host %>/<%= service %>]: (<%= message %>) <%= duration %> [<%= notifu_id %>]"
52
94
  end
53
95
 
54
96
  end
@@ -170,7 +170,7 @@ module Notifu
170
170
  :"@timestamp" => self.now.iso8601,
171
171
  }
172
172
 
173
- action_log action_log_message
173
+ action_log "processor", action_log_message
174
174
 
175
175
  end
176
176
 
@@ -365,7 +365,7 @@ module Notifu
365
365
  sensu_api = Excon.get("#{self.event.api_endpoint}/silenced", user: Notifu::CONFIG[:sensu_api][:username], password: Notifu::CONFIG[:sensu_api][:password])
366
366
  return JSON.parse sensu_api.body
367
367
  rescue Exception => e
368
- log "error", "Failed to get stashes #{self.event.api_endpoint}/stashes (#{e.message})"
368
+ log "error", "Failed to get stashes - GET #{self.event.api_endpoint}/stashes (#{e.message})"
369
369
  return []
370
370
  end
371
371
  end
@@ -382,33 +382,23 @@ module Notifu
382
382
  if self.event.unsilence
383
383
  begin
384
384
  Excon.delete("#{self.event.api_endpoint}/stashes/silence/#{self.event.host}/#{self.event.service}", user: Notifu::CONFIG[:sensu_api][:username], password: Notifu::CONFIG[:sensu_api][:password])
385
- log "info", "Unstashed #{self.event.host}/#{self.event.service} after recovery"
386
- rescue
387
- log "warning", "Failed to fetch stashes from Sensu API: #{self.event.api_endpoint}/stashes"
385
+ log "info", "Unsilenced #{self.event.host}/#{self.event.service} after recovery"
386
+ rescue Exception => e
387
+ log "warning", "Failed to unsilence - DELETE #{self.event.api_endpoint}/stashes/silence/#{self.event.host}/#{self.event.service} (#{e.message})"
388
388
  end
389
389
  else
390
- log "info", "#{self.event.host}/#{self.event.service} left stashed (auto-unstash disabled)"
390
+ log "info", "#{self.event.host}/#{self.event.service} left silenced (auto-unsilence disabled)"
391
391
  end
392
392
  else
393
- log "info", "#{self.event.host}/#{self.event.service} left stashed (auto-unstash doesn't work on checks with defined expiry)"
393
+ log "info", "#{self.event.host}/#{self.event.service} left silenced (auto-unsilence doesn't work when TTL is defined)"
394
394
  end
395
395
  end
396
396
  end
397
397
  end
398
398
 
399
- ##
400
- # logging method
401
- #
402
- def log(prio, msg)
403
- $logger.log prio, "JID-#{self.jid}: " + msg.to_s
404
- end
405
-
406
399
  ##
407
400
  # action logging method
408
401
  #
409
- def action_log event
410
- $logger.action_log "processor", event
411
- end
412
402
 
413
403
  end
414
404
  end
@@ -437,9 +427,5 @@ module Notifu
437
427
  end
438
428
  end
439
429
 
440
- def log(prio, msg)
441
- $logger.log prio, "JID-#{self.jid}: " + msg.to_s
442
- end
443
-
444
430
  end
445
431
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: notifu
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.6.3
4
+ version: 1.6.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Radek 'blufor' Slavicinsky