notifu 1.6.3 → 1.6.4

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.
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