wakame-dolphin 0.0.2
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 +7 -0
- data/.gitignore +9 -0
- data/.rspec +4 -0
- data/.travis.yml +25 -0
- data/Gemfile +18 -0
- data/Makefile +56 -0
- data/README.md +77 -0
- data/Rakefile +67 -0
- data/bin/dolphin_server +98 -0
- data/config/db/cassandra_clear.txt +1 -0
- data/config/db/cassandra_schema.txt +14 -0
- data/config/db/sequel/migrations/0001_add_notification.rb +15 -0
- data/config/db/sequel/migrations/0002_add_event.rb +15 -0
- data/config/dolphin-mysql.conf.travis +26 -0
- data/config/dolphin.conf.example +26 -0
- data/lib/dolphin.rb +148 -0
- data/lib/dolphin/data_store.rb +55 -0
- data/lib/dolphin/data_stores/base_rdb.rb +57 -0
- data/lib/dolphin/data_stores/cassandra.rb +98 -0
- data/lib/dolphin/data_stores/mysql.rb +31 -0
- data/lib/dolphin/helpers/message/zabbix_helper.rb +16 -0
- data/lib/dolphin/helpers/request_helper.rb +72 -0
- data/lib/dolphin/mailer.rb +83 -0
- data/lib/dolphin/manager.rb +35 -0
- data/lib/dolphin/message_builder.rb +98 -0
- data/lib/dolphin/models/base.rb +8 -0
- data/lib/dolphin/models/cassandra/base.rb +11 -0
- data/lib/dolphin/models/cassandra/event.rb +42 -0
- data/lib/dolphin/models/cassandra/notification.rb +28 -0
- data/lib/dolphin/models/rdb/base.rb +12 -0
- data/lib/dolphin/models/rdb/event.rb +47 -0
- data/lib/dolphin/models/rdb/notification.rb +27 -0
- data/lib/dolphin/models/rdb/orm/base.rb +10 -0
- data/lib/dolphin/models/rdb/orm/event.rb +8 -0
- data/lib/dolphin/models/rdb/orm/notification.rb +8 -0
- data/lib/dolphin/query_processor.rb +50 -0
- data/lib/dolphin/request_handler.rb +150 -0
- data/lib/dolphin/sender.rb +47 -0
- data/lib/dolphin/util.rb +18 -0
- data/lib/dolphin/version.rb +3 -0
- data/lib/dolphin/worker.rb +149 -0
- data/script/console +13 -0
- data/spec/files/cassandra_models_spec.rb +127 -0
- data/spec/files/dolphin_spec.rb +110 -0
- data/spec/files/endpoint/event_spec.rb +123 -0
- data/spec/files/endpoint/notification_spec.rb +54 -0
- data/spec/files/message_builder_spec.rb +15 -0
- data/spec/helpers/test_helper.rb +21 -0
- data/spec/helpers/web_request_helper.rb +40 -0
- data/spec/spec_helper.rb +18 -0
- data/templates/email/alert_port.erb +24 -0
- data/templates/email/default.erb +3 -0
- data/tests/test_dolphin +10 -0
- data/tests/test_get_event +31 -0
- data/tests/test_get_notification +27 -0
- data/tests/test_post_event +37 -0
- data/tests/test_post_notification +43 -0
- data/wakame-dolphin.gemspec +40 -0
- metadata +311 -0
@@ -0,0 +1,83 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
|
3
|
+
require 'action_mailer'
|
4
|
+
require 'mail-iso-2022-jp'
|
5
|
+
|
6
|
+
module Dolphin
|
7
|
+
class Mailer < ActionMailer::Base
|
8
|
+
ActionMailer::Base.raise_delivery_errors = true
|
9
|
+
case Dolphin.settings['mail']['type']
|
10
|
+
when 'file'
|
11
|
+
ActionMailer::Base.delivery_method = :file
|
12
|
+
ActionMailer::Base.file_settings = {
|
13
|
+
:location => '/var/tmp'
|
14
|
+
}
|
15
|
+
when 'tls-mail'
|
16
|
+
ActionMailer::Base.delivery_method = :smtp
|
17
|
+
ActionMailer::Base.smtp_settings = {
|
18
|
+
:address => Dolphin.settings['mail']['host'],
|
19
|
+
:port => Dolphin.settings['mail']['port'],
|
20
|
+
:user_name => Dolphin.settings['mail']['user_name'],
|
21
|
+
:password => Dolphin.settings['mail']['password'],
|
22
|
+
:authentication => :plain,
|
23
|
+
:enable_starttls_auto => true
|
24
|
+
}
|
25
|
+
when 'mail'
|
26
|
+
ActionMailer::Base.delivery_method = :smtp
|
27
|
+
ActionMailer::Base.smtp_settings = {
|
28
|
+
:address => Dolphin.settings['mail']['host'],
|
29
|
+
:port => Dolphin.settings['mail']['port'],
|
30
|
+
}
|
31
|
+
end
|
32
|
+
|
33
|
+
default :charset => 'ISO-2022-JP'
|
34
|
+
|
35
|
+
|
36
|
+
#
|
37
|
+
# ==== Examples
|
38
|
+
#
|
39
|
+
# read_iso2022_jp_mail('/var/tmp/test@example.com')
|
40
|
+
#
|
41
|
+
def self.read_iso2022_jp_mail(path, encoding_type='UTF-8')
|
42
|
+
data = File.open(path, 'rb').read
|
43
|
+
ec = Encoding::Converter.new("ISO-2022-JP", encoding_type)
|
44
|
+
converted_data = ec.convert(data)
|
45
|
+
data = converted_data.split("\r\n\r\n")
|
46
|
+
header = data[0].split("\r\n")
|
47
|
+
body = data[1]
|
48
|
+
|
49
|
+
h = Hash.new
|
50
|
+
h[:date] = header[0]
|
51
|
+
h[:from] = header[1]
|
52
|
+
h[:to] = header[2]
|
53
|
+
h[:message_id] = header[3]
|
54
|
+
h[:subject] = header[4]
|
55
|
+
h[:mime_version] = header[5]
|
56
|
+
h[:event_id] = header[9]
|
57
|
+
h.map{|k,v| h[k] = v.split(':')[1].strip}
|
58
|
+
|
59
|
+
h[:body] = body
|
60
|
+
h
|
61
|
+
end
|
62
|
+
|
63
|
+
def notify(send_params)
|
64
|
+
if send_params[:from].blank?
|
65
|
+
raise 'Not found from field.'
|
66
|
+
end
|
67
|
+
|
68
|
+
fqdn = send_params[:from].split('@')[1]
|
69
|
+
|
70
|
+
m = mail(send_params)
|
71
|
+
m.message_id(generate_message_id(send_params[:event_id], fqdn))
|
72
|
+
m.deliver
|
73
|
+
end
|
74
|
+
|
75
|
+
private
|
76
|
+
|
77
|
+
# Refernced function from https://github.com/mikel/mail/blob/master/lib/mail/fields/message_id_field.rb#L77-L79
|
78
|
+
def generate_message_id(event_id, fqdn)
|
79
|
+
"<#{event_id}@#{fqdn}>"
|
80
|
+
end
|
81
|
+
|
82
|
+
end
|
83
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
|
3
|
+
require 'celluloid'
|
4
|
+
|
5
|
+
module Dolphin
|
6
|
+
class Manager < Celluloid::SupervisionGroup
|
7
|
+
include Dolphin::Util
|
8
|
+
|
9
|
+
trap_exit :actor_died
|
10
|
+
|
11
|
+
def actor_died(actor, reason)
|
12
|
+
logger :info, "Actor died"
|
13
|
+
restart_actor(actor, "Breaked actor")
|
14
|
+
logger :info, "Actor restarted"
|
15
|
+
end
|
16
|
+
|
17
|
+
def start
|
18
|
+
end
|
19
|
+
|
20
|
+
def shutdown
|
21
|
+
end
|
22
|
+
|
23
|
+
def run_workers
|
24
|
+
end
|
25
|
+
|
26
|
+
def terminate_workers
|
27
|
+
end
|
28
|
+
|
29
|
+
def run_request_handlers
|
30
|
+
end
|
31
|
+
|
32
|
+
def terminate_request_handlers
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,98 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
require 'erubis'
|
3
|
+
require 'extlib/blank'
|
4
|
+
|
5
|
+
module Dolphin
|
6
|
+
|
7
|
+
class TemplateBuilder
|
8
|
+
|
9
|
+
include Dolphin::Helpers::Message::ZabbixHelper
|
10
|
+
|
11
|
+
def build(template_str, params)
|
12
|
+
template = Erubis::Eruby.new(template_str)
|
13
|
+
if params.is_a? Hash
|
14
|
+
params.each {|key, val|
|
15
|
+
instance_variable_set("@#{key}", val)
|
16
|
+
}
|
17
|
+
end
|
18
|
+
template.result(binding)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
module MessageBuilder
|
23
|
+
|
24
|
+
EXT = '.erb'.freeze
|
25
|
+
|
26
|
+
class Base
|
27
|
+
|
28
|
+
include Dolphin::Util
|
29
|
+
|
30
|
+
def initialize
|
31
|
+
end
|
32
|
+
|
33
|
+
def build
|
34
|
+
raise NotImplementedError
|
35
|
+
end
|
36
|
+
|
37
|
+
def build_message(str, params)
|
38
|
+
begin
|
39
|
+
template = TemplateBuilder.new
|
40
|
+
template.build(str, params).encode("UTF-8")
|
41
|
+
rescue SyntaxError => e
|
42
|
+
logger :error, e
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
class Mail < Base
|
48
|
+
|
49
|
+
MESSAGE_BOUNDARY="----------------------------------------".freeze
|
50
|
+
|
51
|
+
def build(template_id, params)
|
52
|
+
message = ''
|
53
|
+
|
54
|
+
if template_id.blank?
|
55
|
+
template_id = 'default'
|
56
|
+
end
|
57
|
+
|
58
|
+
body_template = template(template_id)
|
59
|
+
if body_template.nil?
|
60
|
+
return nil
|
61
|
+
end
|
62
|
+
|
63
|
+
message = build_message(body_template, params['messages'])
|
64
|
+
subject, body = message.split(MESSAGE_BOUNDARY)
|
65
|
+
subject.strip! unless subject.nil?
|
66
|
+
body.strip! unless body.nil?
|
67
|
+
|
68
|
+
notification = NotificationObject.new
|
69
|
+
notification.subject = subject
|
70
|
+
notification.from = Dolphin.settings['mail']['from']
|
71
|
+
notification.to = params["to"]
|
72
|
+
notification.cc ||= params["cc"]
|
73
|
+
notification.bcc ||= params["bcc"]
|
74
|
+
notification.body = body
|
75
|
+
notification
|
76
|
+
end
|
77
|
+
|
78
|
+
private
|
79
|
+
def template(template_id)
|
80
|
+
file_path = File.join(template_path, template_file(template_id))
|
81
|
+
if File.exists? file_path
|
82
|
+
File.read(file_path, :encoding => Encoding::UTF_8)
|
83
|
+
else
|
84
|
+
logger :warn, "File not found #{file_path}"
|
85
|
+
nil
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
def template_file(template_id)
|
90
|
+
template_id + EXT
|
91
|
+
end
|
92
|
+
|
93
|
+
def template_path
|
94
|
+
File.join(Dolphin.templates_path, '/email')
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
|
3
|
+
require 'multi_json'
|
4
|
+
require 'simple_uuid'
|
5
|
+
|
6
|
+
module Dolphin
|
7
|
+
module Models
|
8
|
+
module Cassandra
|
9
|
+
class Event < Base
|
10
|
+
COLUMN_FAMILY = 'events'.freeze
|
11
|
+
ROW_KEY = 'history'.freeze
|
12
|
+
|
13
|
+
def get(params)
|
14
|
+
|
15
|
+
options = {
|
16
|
+
:count => params[:count]
|
17
|
+
}
|
18
|
+
|
19
|
+
if params[:start_id]
|
20
|
+
options[:start] = params[:start_id]
|
21
|
+
elsif params[:start_time]
|
22
|
+
options[:start] = params[:start_time]
|
23
|
+
end
|
24
|
+
|
25
|
+
db.get(COLUMN_FAMILY, ROW_KEY, options).collect do |event| {
|
26
|
+
'id' => event[0].to_guid,
|
27
|
+
'event' => MultiJson.load(event[1]),
|
28
|
+
'created_at' => SimpleUUID::UUID.new(event[0].to_guid).to_time.iso8601
|
29
|
+
}
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def put(event)
|
34
|
+
column_name = SimpleUUID::UUID.new(Time.now).to_guid
|
35
|
+
value = MultiJson.dump(event[:messages])
|
36
|
+
db.insert(COLUMN_FAMILY, ROW_KEY, {column_name => value})
|
37
|
+
column_name
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
|
3
|
+
require 'multi_json'
|
4
|
+
|
5
|
+
module Dolphin
|
6
|
+
module Models
|
7
|
+
module Cassandra
|
8
|
+
class Notification < Base
|
9
|
+
def get(id)
|
10
|
+
res = db.get('notifications', id.to_s)
|
11
|
+
MultiJson.load(res['methods'])
|
12
|
+
end
|
13
|
+
|
14
|
+
def put(id, methods)
|
15
|
+
column_name = 'methods'
|
16
|
+
row_key = id.to_s
|
17
|
+
value = MultiJson.dump(methods)
|
18
|
+
|
19
|
+
db.insert('notifications', row_key, {column_name => value})
|
20
|
+
end
|
21
|
+
|
22
|
+
def delete(id)
|
23
|
+
db.remove('notifications', id)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
|
3
|
+
require 'multi_json'
|
4
|
+
require 'simple_uuid'
|
5
|
+
|
6
|
+
module Dolphin::Models
|
7
|
+
module Rdb
|
8
|
+
class Event < Base
|
9
|
+
def get(params)
|
10
|
+
options = {
|
11
|
+
:count => params[:count]
|
12
|
+
}
|
13
|
+
|
14
|
+
if params[:start_id]
|
15
|
+
options[:start] = params[:start_id]
|
16
|
+
elsif params[:start_time]
|
17
|
+
options[:start] = params[:start_time]
|
18
|
+
end
|
19
|
+
|
20
|
+
if options[:start]
|
21
|
+
event = db.find(:uuid => params[:start_id])
|
22
|
+
h = {}
|
23
|
+
h['id'] = event.uuid
|
24
|
+
h['event'] = MultiJson.load(event.value)
|
25
|
+
h['created_at'] = SimpleUUID::UUID.new(event.uuid).to_time.iso8601
|
26
|
+
[h]
|
27
|
+
else
|
28
|
+
db.order(Sequel.desc(:id)).find_all.collect do |event| {
|
29
|
+
'id' => event.uuid,
|
30
|
+
'event' => MultiJson.load(event.value),
|
31
|
+
'created_at' => SimpleUUID::UUID.new(event.uuid).to_time.iso8601
|
32
|
+
}
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def put(event)
|
38
|
+
d = db.new
|
39
|
+
d.uuid = SimpleUUID::UUID.new(Time.now).to_guid
|
40
|
+
d.value = MultiJson.dump(event[:messages])
|
41
|
+
d.timestamp = DateTime.now
|
42
|
+
d.save
|
43
|
+
d.uuid
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
|
3
|
+
require 'multi_json'
|
4
|
+
|
5
|
+
module Dolphin::Models
|
6
|
+
module Rdb
|
7
|
+
class Notification < Base
|
8
|
+
def get(id)
|
9
|
+
res = db.find(:uuid => id)
|
10
|
+
MultiJson.load(res.value)
|
11
|
+
end
|
12
|
+
|
13
|
+
def put(id, methods)
|
14
|
+
d = db.find(:uuid => id)
|
15
|
+
d = db.new if d.nil?
|
16
|
+
d.uuid = id.to_s
|
17
|
+
d.value = MultiJson.dump(methods)
|
18
|
+
d.save
|
19
|
+
end
|
20
|
+
|
21
|
+
def delete(id)
|
22
|
+
res = db.find(:uuid => id)
|
23
|
+
res.destroy
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
|
3
|
+
require 'celluloid'
|
4
|
+
|
5
|
+
module Dolphin
|
6
|
+
class QueryProcessor
|
7
|
+
include Celluloid
|
8
|
+
include Dolphin::Util
|
9
|
+
|
10
|
+
def get_notification(id)
|
11
|
+
logger :info, "Get notification #{id}"
|
12
|
+
send('get_notification', id)
|
13
|
+
end
|
14
|
+
|
15
|
+
def put_event(event)
|
16
|
+
logger :info, "Put event #{event}"
|
17
|
+
send('put_event', event)
|
18
|
+
end
|
19
|
+
|
20
|
+
def get_event(params)
|
21
|
+
send('get_event', params)
|
22
|
+
end
|
23
|
+
|
24
|
+
def put_notification(notification)
|
25
|
+
logger :info, notification
|
26
|
+
notification_id = notification[:id]
|
27
|
+
methods = notification[:methods]
|
28
|
+
send('put_notification', notification_id, methods)
|
29
|
+
end
|
30
|
+
|
31
|
+
def delete_notification(notification)
|
32
|
+
logger :info, notification
|
33
|
+
notification_id = notification[:id]
|
34
|
+
send('delete_notification', notification_id)
|
35
|
+
end
|
36
|
+
|
37
|
+
private
|
38
|
+
def send(action, *args)
|
39
|
+
begin
|
40
|
+
ds = DataStore.current_store
|
41
|
+
ds.connect
|
42
|
+
ds.__send__(action, *args)
|
43
|
+
rescue => e
|
44
|
+
logger :error, e.backtrace
|
45
|
+
logger :error, e
|
46
|
+
false
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|