omnibot 0.0.9 → 0.0.10
Sign up to get free protection for your applications and to get access to all the features.
- data/Rakefile +5 -0
- data/examples/config.yaml +13 -0
- data/lib/omnibot.rb +8 -2
- data/lib/omnibot/amqpconsumer.rb +8 -8
- data/lib/omnibot/launcher.rb +32 -0
- data/lib/omnibot/loggedcommand.rb +18 -0
- data/lib/omnibot/mailchecker.rb +96 -0
- data/lib/omnibot/periodiccommand.rb +12 -14
- data/lib/omnibot/version.rb +1 -1
- metadata +59 -69
data/Rakefile
CHANGED
@@ -25,6 +25,11 @@ task :install => :build do
|
|
25
25
|
system "gem install pkg/#{gemspec.name}-#{gemspec.version}"
|
26
26
|
end
|
27
27
|
|
28
|
+
desc "Install gem locally without documentation"
|
29
|
+
task :install_nodoc => :build do
|
30
|
+
system "gem install pkg/#{gemspec.name}-#{gemspec.version} --no-rdoc --no-ri"
|
31
|
+
end
|
32
|
+
|
28
33
|
desc "Push gem"
|
29
34
|
task :push => :build do
|
30
35
|
system "gem push pkg/#{gemspec.name}-#{gemspec.version}.gem"
|
data/examples/config.yaml
CHANGED
@@ -5,3 +5,16 @@ config:
|
|
5
5
|
notifyresource: Adium.*
|
6
6
|
periodiccommands: [ 'vnstat' ]
|
7
7
|
logpath: '/tmp/omnibot.log'
|
8
|
+
mails:
|
9
|
+
- user: foobar@example.com
|
10
|
+
password: secret
|
11
|
+
host: pop.example.com
|
12
|
+
port: 995
|
13
|
+
ssl: true
|
14
|
+
mailtriggers:
|
15
|
+
- action: unpack
|
16
|
+
for: omni.notify@mail.ru
|
17
|
+
if:
|
18
|
+
subject: '^Weekly archive.*'
|
19
|
+
unpack_to: '/tmp/'
|
20
|
+
command_post: 'post-mail'
|
data/lib/omnibot.rb
CHANGED
@@ -6,9 +6,15 @@ require 'eventmachine'
|
|
6
6
|
require 'xmpp4r'
|
7
7
|
require 'xmpp4r/client'
|
8
8
|
require 'xmpp4r/roster'
|
9
|
+
require 'mail'
|
9
10
|
require 'socket'
|
10
11
|
require 'date'
|
12
|
+
require 'tmpdir'
|
13
|
+
|
14
|
+
module OmniBot
|
15
|
+
|
16
|
+
%w[ helpers jabberbot amqpconsumer omnisend launcher loggedcommand periodiccommand mailchecker ].each do |file|
|
17
|
+
require "omnibot/#{file}.rb"
|
18
|
+
end
|
11
19
|
|
12
|
-
%w[ helpers jabberbot amqpconsumer omnisend launcher periodiccommand ].each do |file|
|
13
|
-
require "omnibot/#{file}.rb"
|
14
20
|
end
|
data/lib/omnibot/amqpconsumer.rb
CHANGED
@@ -3,6 +3,8 @@ module OmniBot
|
|
3
3
|
# AMQP consumer class
|
4
4
|
class AMQPConsumer
|
5
5
|
|
6
|
+
attr_accessor :handlers
|
7
|
+
|
6
8
|
def send_message message
|
7
9
|
begin
|
8
10
|
@omnibot.add_message [Time.now, message]
|
@@ -29,14 +31,12 @@ module OmniBot
|
|
29
31
|
@omnibot.set_subscriber Jabber::JID::new(@config['notifyjid']), @config['notifyresource']
|
30
32
|
@omnibot.connect
|
31
33
|
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
periodic_command.start
|
39
|
-
pause += 20
|
34
|
+
@handlers.each_with_index do |handler, index|
|
35
|
+
OmniLog::info "Setup handler #{handler.to_s}..."
|
36
|
+
handler.timer_provider = EM
|
37
|
+
handler.set_jabber_messenger { |message| send_message message }
|
38
|
+
handler.startup_pause = index*10
|
39
|
+
handler.start
|
40
40
|
end
|
41
41
|
|
42
42
|
rescue Object => e
|
data/lib/omnibot/launcher.rb
CHANGED
@@ -15,6 +15,37 @@ module OmniBot
|
|
15
15
|
return 'omnibot.log'
|
16
16
|
end
|
17
17
|
|
18
|
+
def get_store config
|
19
|
+
store_path = config['storepath']
|
20
|
+
unless File.directory? store_path
|
21
|
+
store_path = ENV['HOME']+'/.omnibot'
|
22
|
+
FileUtils.mkdir store_path unless File.directory? store_path
|
23
|
+
end
|
24
|
+
store_path + '/omnibot.store'
|
25
|
+
end
|
26
|
+
|
27
|
+
def provide_handlers config
|
28
|
+
periodic_commands = ([config['periodiccommands']].flatten or [])
|
29
|
+
|
30
|
+
mails = ([config['mails']].flatten or [])
|
31
|
+
mail_triggers = ([config['mailtriggers']].flatten or [])
|
32
|
+
mail_triggers.each do |mt|
|
33
|
+
raise 'No mail found for a trigger' unless mails.find { |m| m['user'] == mt['for'] }
|
34
|
+
raise 'Not supported action' unless mt['action'] == 'unpack'
|
35
|
+
end
|
36
|
+
used_mails = mails.select { |m| mail_triggers.find { |mt| m['user'] == mt['for'] } }
|
37
|
+
raise 'Sorry but multiple mail addresses is not supported yet' if used_mails.size > 1
|
38
|
+
|
39
|
+
[] +
|
40
|
+
periodic_commands.map do |command|
|
41
|
+
PeriodicCommand.new command
|
42
|
+
end +
|
43
|
+
mail_triggers.map do |trigger|
|
44
|
+
mail = mails.find { |m| m['user'] == trigger['for'] }
|
45
|
+
MailChecker.new mail, trigger
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
18
49
|
def start args
|
19
50
|
config_path = get_config_path args
|
20
51
|
puts "Using config at #{config_path}"
|
@@ -26,6 +57,7 @@ module OmniBot
|
|
26
57
|
OmniLog::log.level = Logger::DEBUG
|
27
58
|
|
28
59
|
consumer = AMQPConsumer.new config
|
60
|
+
consumer.handlers = provide_handlers(config)
|
29
61
|
consumer.start
|
30
62
|
|
31
63
|
OmniLog::log.close
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module OmniBot
|
2
|
+
module LoggedCommand
|
3
|
+
|
4
|
+
def jabber_logged_command banner, command
|
5
|
+
body = `#{command}`
|
6
|
+
if $? != 0
|
7
|
+
@jabber_messenger.call "#{banner} command #{command} failed with an error #{$?}:\n" + body
|
8
|
+
end
|
9
|
+
if body.strip != ''
|
10
|
+
@jabber_messenger.call "#{banner} command #{command_str} succeeded with:\n" + body
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
def set_jabber_messenger &block
|
15
|
+
@jabber_messenger = block
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,96 @@
|
|
1
|
+
module OmniBot
|
2
|
+
|
3
|
+
class MailChecker
|
4
|
+
|
5
|
+
include LoggedCommand
|
6
|
+
|
7
|
+
def on_first_timer
|
8
|
+
OmniLog::debug "Okay, it's near of midnight"
|
9
|
+
on_periodic_timer
|
10
|
+
@timer_provider.add_periodic_timer(3600) { on_periodic_timer }
|
11
|
+
end
|
12
|
+
|
13
|
+
def match_condition m, condition_name, mail_name = condition_name
|
14
|
+
values = m.send(mail_name)
|
15
|
+
[values].flatten.any? do |value|
|
16
|
+
@conditions[condition_name] && Regexp.new(@conditions[condition_name]).match(value.to_s)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def match_conditions m
|
21
|
+
%w{ subject from to cc date}.any? { |condition| match_condition m, condition }
|
22
|
+
end
|
23
|
+
|
24
|
+
def on_periodic_timer
|
25
|
+
OmniLog::info "Checking mail #{@mail_config['address']}"
|
26
|
+
Mail.all.each do |m|
|
27
|
+
OmniLog::info " look at message from #{m.from} about #{m.subject}"
|
28
|
+
handle_message(m) if match_conditions m
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def handle_message m
|
33
|
+
OmniLog::info "Matched " + m.inspect.to_s
|
34
|
+
attached = m.attachments.find { |a| a.mime_type =~ /application\/x-zip.*/ }
|
35
|
+
if attached
|
36
|
+
Dir.mktmpdir('omniatt') do |tmpdir|
|
37
|
+
filename = tmpdir + '/' + attached.filename
|
38
|
+
OmniLog::info "Writing attachment to #{filename}"
|
39
|
+
File.open(filename,'w') { |f| f.write attached.read }
|
40
|
+
Dir.chdir(@unpack_to) do
|
41
|
+
system("unzip -oq '#{filename}'")
|
42
|
+
raise "Error extracting file #{filename} to #{@unpack_to}" if $? != 0
|
43
|
+
end
|
44
|
+
|
45
|
+
message_body = "Received an email '#{m.subject}' from '#{m.from.join(',')}' with "+
|
46
|
+
"an attachment #{attached.filename}. Successfully extracted an attachment to #{@unpack_to}."
|
47
|
+
@jabber_messenger.call message_body
|
48
|
+
|
49
|
+
jabber_logged_command 'Mail post-receive ', "#{@command_post} #{filename} #{@unpack_to}"
|
50
|
+
end
|
51
|
+
else
|
52
|
+
OmniLog::info "No attachment found"
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
def yaml_to_mailhash yaml_config
|
57
|
+
{ :address => yaml_config['host'],
|
58
|
+
:port => yaml_config['port'],
|
59
|
+
:user_name => yaml_config['user'],
|
60
|
+
:password => yaml_config['password'],
|
61
|
+
:enable_ssl => yaml_config['ssl']
|
62
|
+
}
|
63
|
+
end
|
64
|
+
|
65
|
+
public
|
66
|
+
attr_writer :timer_provider
|
67
|
+
attr_writer :startup_pause
|
68
|
+
|
69
|
+
def initialize mail_config, trigger_config
|
70
|
+
@startup_pause = 0
|
71
|
+
@mail_config = mail_config
|
72
|
+
@conditions = trigger_config['if']
|
73
|
+
@unpack_to = trigger_config['unpack_to']
|
74
|
+
@command_post = trigger_config['command_post']
|
75
|
+
@send_to = trigger_config['send_to']
|
76
|
+
|
77
|
+
mailhash = yaml_to_mailhash(mail_config)
|
78
|
+
Mail.defaults do
|
79
|
+
retriever_method :pop3, mailhash
|
80
|
+
end
|
81
|
+
|
82
|
+
raise 'Wrong command' if (@command_post or '') == ''
|
83
|
+
raise 'No dir to extract to' unless File.directory? @unpack_to
|
84
|
+
end
|
85
|
+
|
86
|
+
def to_s
|
87
|
+
"Mail checker for #{@send_to}"
|
88
|
+
end
|
89
|
+
|
90
|
+
def start
|
91
|
+
@timer_provider.add_timer(@startup_pause) { on_first_timer }
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
end
|
96
|
+
|
@@ -3,6 +3,8 @@ module OmniBot
|
|
3
3
|
# Send to jabber user result of a daily command
|
4
4
|
class PeriodicCommand
|
5
5
|
|
6
|
+
include OmniBot::LoggedCommand
|
7
|
+
|
6
8
|
def on_first_timer
|
7
9
|
OmniLog::debug "Okay, it's near of midnight"
|
8
10
|
on_periodic_timer
|
@@ -11,35 +13,31 @@ module OmniBot
|
|
11
13
|
|
12
14
|
def on_periodic_timer
|
13
15
|
OmniLog::info "Reporting command #{@command}"
|
14
|
-
|
15
|
-
raise 'Error launching command ' if $? != 0
|
16
|
-
if body.strip != ''
|
17
|
-
message_body = "Results of daily executed command #{@command}:\n" + body
|
18
|
-
@jabber_messenger.call message_body
|
19
|
-
end
|
16
|
+
jabber_logged_command 'Periodic command', @command
|
20
17
|
end
|
21
18
|
|
22
19
|
public
|
23
20
|
attr_writer :timer_provider
|
21
|
+
attr_writer :startup_pause
|
24
22
|
|
25
|
-
def initialize command
|
23
|
+
def initialize command
|
26
24
|
@command = command
|
27
|
-
@
|
25
|
+
@startup_pause = 0
|
26
|
+
|
27
|
+
raise 'Wrong command' if (@command or '') == ''
|
28
|
+
end
|
28
29
|
|
29
|
-
|
30
|
+
def to_s
|
31
|
+
"Periodic command '#{@command}'"
|
30
32
|
end
|
31
33
|
|
32
34
|
def start
|
33
35
|
now = Time.now
|
34
36
|
tomorrow = DateTime.now+1
|
35
37
|
next_report_time = Time.local(tomorrow.year, tomorrow.month, tomorrow.day, 1, 0, 0)
|
36
|
-
next_report_time = next_report_time + @
|
38
|
+
next_report_time = next_report_time + @startup_pause
|
37
39
|
@timer_provider.add_timer(next_report_time - now) { on_first_timer }
|
38
40
|
end
|
39
|
-
|
40
|
-
def set_jabber_messenger &block
|
41
|
-
@jabber_messenger = block
|
42
|
-
end
|
43
41
|
end
|
44
42
|
|
45
43
|
end
|
data/lib/omnibot/version.rb
CHANGED
metadata
CHANGED
@@ -1,109 +1,99 @@
|
|
1
|
-
--- !ruby/object:Gem::Specification
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
2
|
name: omnibot
|
3
|
-
version: !ruby/object:Gem::Version
|
4
|
-
|
5
|
-
|
6
|
-
- 0
|
7
|
-
- 0
|
8
|
-
- 9
|
9
|
-
version: 0.0.9
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.10
|
5
|
+
prerelease:
|
10
6
|
platform: ruby
|
11
|
-
authors:
|
7
|
+
authors:
|
12
8
|
- theirix
|
13
9
|
autorequire:
|
14
10
|
bindir: bin
|
15
11
|
cert_chain: []
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
dependencies:
|
20
|
-
- !ruby/object:Gem::Dependency
|
21
|
-
version_requirements: &id001 !ruby/object:Gem::Requirement
|
22
|
-
requirements:
|
23
|
-
- - ">="
|
24
|
-
- !ruby/object:Gem::Version
|
25
|
-
segments:
|
26
|
-
- 0
|
27
|
-
version: "0"
|
28
|
-
requirement: *id001
|
12
|
+
date: 2011-10-28 00:00:00.000000000Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
29
15
|
name: xmpp4r
|
30
|
-
|
16
|
+
requirement: &70197902207540 !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '0'
|
31
22
|
type: :runtime
|
32
|
-
- !ruby/object:Gem::Dependency
|
33
|
-
version_requirements: &id002 !ruby/object:Gem::Requirement
|
34
|
-
requirements:
|
35
|
-
- - ">="
|
36
|
-
- !ruby/object:Gem::Version
|
37
|
-
segments:
|
38
|
-
- 0
|
39
|
-
version: "0"
|
40
|
-
requirement: *id002
|
41
|
-
name: eventmachine
|
42
23
|
prerelease: false
|
24
|
+
version_requirements: *70197902207540
|
25
|
+
- !ruby/object:Gem::Dependency
|
26
|
+
name: eventmachine
|
27
|
+
requirement: &70197902206760 !ruby/object:Gem::Requirement
|
28
|
+
none: false
|
29
|
+
requirements:
|
30
|
+
- - ! '>='
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: '0'
|
43
33
|
type: :runtime
|
44
|
-
- !ruby/object:Gem::Dependency
|
45
|
-
version_requirements: &id003 !ruby/object:Gem::Requirement
|
46
|
-
requirements:
|
47
|
-
- - ">="
|
48
|
-
- !ruby/object:Gem::Version
|
49
|
-
segments:
|
50
|
-
- 0
|
51
|
-
version: "0"
|
52
|
-
requirement: *id003
|
53
|
-
name: amqp
|
54
34
|
prerelease: false
|
35
|
+
version_requirements: *70197902206760
|
36
|
+
- !ruby/object:Gem::Dependency
|
37
|
+
name: amqp
|
38
|
+
requirement: &70197902206040 !ruby/object:Gem::Requirement
|
39
|
+
none: false
|
40
|
+
requirements:
|
41
|
+
- - ! '>='
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
version: '0'
|
55
44
|
type: :runtime
|
56
|
-
|
45
|
+
prerelease: false
|
46
|
+
version_requirements: *70197902206040
|
47
|
+
description: Works with AMQP for sending messages at server side.Sends notifications
|
48
|
+
to an user via XMPP.Can monitor system by performing daily commands.
|
57
49
|
email: theirix@gmail.com
|
58
|
-
executables:
|
50
|
+
executables:
|
59
51
|
- omnibot
|
60
52
|
- omnisend
|
61
53
|
extensions: []
|
62
|
-
|
63
54
|
extra_rdoc_files: []
|
64
|
-
|
65
|
-
files:
|
55
|
+
files:
|
66
56
|
- examples/config.yaml
|
67
57
|
- lib/omnibot/amqpconsumer.rb
|
68
58
|
- lib/omnibot/helpers.rb
|
69
59
|
- lib/omnibot/jabberbot.rb
|
70
60
|
- lib/omnibot/launcher.rb
|
61
|
+
- lib/omnibot/loggedcommand.rb
|
62
|
+
- lib/omnibot/mailchecker.rb
|
71
63
|
- lib/omnibot/omnisend.rb
|
72
64
|
- lib/omnibot/periodiccommand.rb
|
73
65
|
- lib/omnibot/version.rb
|
74
66
|
- lib/omnibot.rb
|
75
67
|
- Rakefile
|
76
68
|
- README.md
|
77
|
-
|
69
|
+
- bin/omnibot
|
70
|
+
- bin/omnisend
|
78
71
|
homepage: http://github.com/theirix/omnibot
|
79
72
|
licenses: []
|
80
|
-
|
81
73
|
post_install_message:
|
82
74
|
rdoc_options: []
|
83
|
-
|
84
|
-
require_paths:
|
75
|
+
require_paths:
|
85
76
|
- lib
|
86
|
-
required_ruby_version: !ruby/object:Gem::Requirement
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
segments:
|
77
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
78
|
+
none: false
|
79
|
+
requirements:
|
80
|
+
- - ! '>='
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '1.8'
|
83
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
84
|
+
none: false
|
85
|
+
requirements:
|
86
|
+
- - ! '>='
|
87
|
+
- !ruby/object:Gem::Version
|
88
|
+
version: '0'
|
89
|
+
segments:
|
99
90
|
- 0
|
100
|
-
|
101
|
-
requirements:
|
91
|
+
hash: -556400770793257517
|
92
|
+
requirements:
|
102
93
|
- AMQP-compatible server (for example, RabbitMQ)
|
103
94
|
rubyforge_project: nowarning
|
104
|
-
rubygems_version: 1.
|
95
|
+
rubygems_version: 1.8.6
|
105
96
|
signing_key:
|
106
97
|
specification_version: 3
|
107
98
|
summary: Simple XMPP bot for server monitoring
|
108
99
|
test_files: []
|
109
|
-
|