gat 0.2.8
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.
- data/History.txt +84 -0
- data/PostInstall.txt +22 -0
- data/README.txt +49 -0
- data/Rakefile +12 -0
- data/bin/gat +15 -0
- data/lib/gat.rb +323 -0
- data/lib/gat/action/base.rb +197 -0
- data/lib/gat/action/ruby_method.rb +35 -0
- data/lib/gat/action/shell_command.rb +185 -0
- data/lib/gat/boot.rb +63 -0
- data/lib/gat/checks.rb +136 -0
- data/lib/gat/debug.rb +29 -0
- data/lib/gat/dependence/argument.rb +62 -0
- data/lib/gat/dependence/base.rb +54 -0
- data/lib/gat/dependence/folder.rb +104 -0
- data/lib/gat/dependence/program.rb +36 -0
- data/lib/gat/email.rb +80 -0
- data/lib/gat/exceptions.rb +163 -0
- data/lib/gat/extends.rb +102 -0
- data/lib/gat/help.rb +79 -0
- data/lib/gat/interpreter.rb +93 -0
- data/lib/gat/launcher.rb +100 -0
- data/lib/gat/logger.rb +331 -0
- data/lib/gat/operation.rb +253 -0
- data/lib/gat/version.rb +20 -0
- data/lib/gatgets/dar_backup/dar_backup.rb +367 -0
- data/lib/gatgets/dar_backup/dar_backup.yml +387 -0
- data/lib/gatgets/dar_backup/launcher.rb +44 -0
- data/lib/gatgets/dar_backup/templates/list_backups.erb +31 -0
- data/lib/gatgets/dar_backup/templates/search.erb +33 -0
- data/lib/gatgets/gatgets_manager/gatgets_manager.rb +65 -0
- data/lib/gatgets/gatgets_manager/gatgets_manager.yml +71 -0
- data/lib/gatgets/gatgets_manager/templates/list.erb +9 -0
- data/lib/gatgets/synchronization/README +26 -0
- data/lib/gatgets/synchronization/launcher.rb +20 -0
- data/lib/gatgets/synchronization/launcher_cron.sh +69 -0
- data/lib/gatgets/synchronization/synchronization.rb +123 -0
- data/lib/gatgets/synchronization/synchronization.yml +144 -0
- data/test/test_gat.rb +36 -0
- data/test/test_helper.rb +3 -0
- metadata +131 -0
data/lib/gat/checks.rb
ADDED
@@ -0,0 +1,136 @@
|
|
1
|
+
=begin
|
2
|
+
|
3
|
+
:file => checks.rb
|
4
|
+
:author => (c) 2008-2009 A.C. Gnoxys info@gnoxys.net
|
5
|
+
|
6
|
+
######################################################################################
|
7
|
+
## This file is part of GAT: http://gat.rubyforge.org ##
|
8
|
+
## ##
|
9
|
+
## GAT (Gnoxys Administration Tools) is released under the GPL License 3 or higher. ##
|
10
|
+
## You can get a copy of the license easily at http://www.gnu.org/licenses/gpl.html.##
|
11
|
+
######################################################################################
|
12
|
+
|
13
|
+
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
|
14
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
15
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
16
|
+
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
17
|
+
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
18
|
+
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
19
|
+
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
20
|
+
|
21
|
+
=end
|
22
|
+
|
23
|
+
module Gat
|
24
|
+
|
25
|
+
# Gat::Checks Module
|
26
|
+
#
|
27
|
+
# Check methods return true or false through some arguments. Extend module if you want to add more checkable methods
|
28
|
+
#
|
29
|
+
# Check methods are hash based to better human arguments readeable. I mean, when you make a comparation beetwen two
|
30
|
+
# values, it is better to use arguments[:small] > arguments[:big] thatn arguments[0] > arguments[1]
|
31
|
+
#
|
32
|
+
# So, need_arguments method is avaible as public inside this module. This function will check the arguments hash
|
33
|
+
# and raise a GatgetConfixException if check_method miss one argument. For example
|
34
|
+
#
|
35
|
+
# def check_minor_than(arguments)
|
36
|
+
# need_arguments(['minor', 'major'], arguments)
|
37
|
+
# arguments['minor'] < arguments['major']
|
38
|
+
# end
|
39
|
+
#
|
40
|
+
# check_minor_than('minor' => 10, 'bigger' => 20) # => raise GatgetConfigException
|
41
|
+
# check_minor_than('minor' => 10, 'major' => 20) # => true
|
42
|
+
# check_minor_than('minor' => 20, 'major' => 10) # => false
|
43
|
+
module Checks
|
44
|
+
|
45
|
+
# Files checkers!!!!!!
|
46
|
+
# --------------------
|
47
|
+
|
48
|
+
# Check if file exist
|
49
|
+
def check_file_exists(arguments)
|
50
|
+
need_arguments(['file_url'], arguments)
|
51
|
+
File.exists?(arguments['file_url'])
|
52
|
+
end
|
53
|
+
|
54
|
+
# Check if file exist
|
55
|
+
def check_file_not_exists(arguments)
|
56
|
+
need_arguments(['file_url'], arguments)
|
57
|
+
!File.exists?(arguments['file_url'])
|
58
|
+
end
|
59
|
+
|
60
|
+
def check_enough_space(arguments)
|
61
|
+
need_arguments(['where', 'space_needed'], arguments)
|
62
|
+
# get space at where
|
63
|
+
space = %x[ df -B 1 #{ arguments['where'] }].split("\n").last.split(" ")[3].to_i
|
64
|
+
space > arguments['space_needed'].to_i
|
65
|
+
end
|
66
|
+
|
67
|
+
def check_true(arguments)
|
68
|
+
need_arguments(['true_expression'], arguments)
|
69
|
+
eval("#{ arguments['true_expression'] }")
|
70
|
+
end
|
71
|
+
|
72
|
+
def check_false(arguments)
|
73
|
+
need_arguments(['false_expression'], arguments)
|
74
|
+
!eval(arguments['false_expression'])
|
75
|
+
end
|
76
|
+
|
77
|
+
|
78
|
+
|
79
|
+
# need_arguments checks that all the needed arguments are in array
|
80
|
+
# raise GagetConfigException if someone is not avaliable
|
81
|
+
def need_arguments(needed, avalaible)
|
82
|
+
needed.each do |need|
|
83
|
+
unless avalaible.keys.include?(need)
|
84
|
+
raise GatgetConfigException.new("needed argument #{ need } not avalaible at #{ self.class.name }", "need_arguments")
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
def exit_if_i_am_running(myname = nil)
|
90
|
+
if check_i_am_running(myname)
|
91
|
+
exit 0
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
def check_i_am_running(myname = nil)
|
96
|
+
# lock dirs/files
|
97
|
+
myname ||= File.basename($0, ".rb")
|
98
|
+
lockdir="/tmp/#{myname}-lock"
|
99
|
+
pidfile="#{lockdir}/PID"
|
100
|
+
|
101
|
+
### start locking attempt
|
102
|
+
|
103
|
+
r = FileUtils.mkdir(lockdir) rescue r = nil
|
104
|
+
if not r.nil?
|
105
|
+
# lock succeeded, install signal handlers and store the PID
|
106
|
+
trap 0, proc { p "Trapped"
|
107
|
+
FileUtils.rm_rf lockdir }
|
108
|
+
r = File.open(pidfile, 'w') {|f| f.write($$) }
|
109
|
+
else
|
110
|
+
# lock failed, now check if the other PID is alive
|
111
|
+
begin
|
112
|
+
f = File.open(pidfile, 'r')
|
113
|
+
otherpid = f.readline.to_i
|
114
|
+
rescue
|
115
|
+
# if it wasn't possible to read the file anymore, another instance probably is
|
116
|
+
# about to remove the lock -- exit, we're *still* locked
|
117
|
+
return true
|
118
|
+
end
|
119
|
+
r = Process.kill(0, otherpid) rescue r = nil
|
120
|
+
if r == nil
|
121
|
+
# lock is stale, remove it and go on
|
122
|
+
trap 0, proc { p "Trapped"
|
123
|
+
FileUtils.rm_rf lockdir }
|
124
|
+
r = File.open(pidfile, 'w') {|f| f.write($$) } rescue r=nil
|
125
|
+
return false
|
126
|
+
else
|
127
|
+
# lock is valid and otherpid is active - exit, we're locked!
|
128
|
+
return true
|
129
|
+
end
|
130
|
+
end
|
131
|
+
return false
|
132
|
+
end
|
133
|
+
|
134
|
+
|
135
|
+
end
|
136
|
+
end
|
data/lib/gat/debug.rb
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
=begin
|
2
|
+
This file is part of GAT: http://gat.rubyforge.org
|
3
|
+
|
4
|
+
(c) 2008-2009 A.C. Gnoxys info@gnoxys.net
|
5
|
+
|
6
|
+
GAT (Gnoxys Administration Tools) is released under the GPL License 3 or higher.
|
7
|
+
You can get a copy of the license easily at http://www.gnu.org/licenses/gpl.html.
|
8
|
+
|
9
|
+
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
|
10
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
11
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
12
|
+
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
13
|
+
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
14
|
+
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
15
|
+
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
16
|
+
=end
|
17
|
+
|
18
|
+
module Gat
|
19
|
+
module Debug
|
20
|
+
|
21
|
+
def print_debug_msg(message)
|
22
|
+
$stdout.puts "* debug *: #{ message } \n"
|
23
|
+
end
|
24
|
+
|
25
|
+
def get_debug_levels
|
26
|
+
{ "trace" => 4, "message" => 3, "warning" => 2, "error" => 1, "direct_output" => 0 }
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,62 @@
|
|
1
|
+
module Gat
|
2
|
+
module Dependence
|
3
|
+
class Argument < Base
|
4
|
+
|
5
|
+
attr_reader :position
|
6
|
+
attr_reader :optional
|
7
|
+
attr_reader :prefix
|
8
|
+
attr_reader :type
|
9
|
+
|
10
|
+
attr :value
|
11
|
+
|
12
|
+
def initialize(name, config, operation)
|
13
|
+
|
14
|
+
super(name, config, operation)
|
15
|
+
# by default, argument is command line
|
16
|
+
@type = @config['type'] || 'command_line'
|
17
|
+
@optional = @config['optional'] || false
|
18
|
+
@prefix = @config['prefix'] || nil
|
19
|
+
|
20
|
+
@@argument_position ||= 0
|
21
|
+
@position = ( @@argument_position += 1 )
|
22
|
+
|
23
|
+
end
|
24
|
+
|
25
|
+
# Argument must come
|
26
|
+
def evalue
|
27
|
+
# command line arguments
|
28
|
+
if self.type == 'command_line' and self.operation.gatget.arguments.any? and self.operation.gatget.arguments[self.position]
|
29
|
+
|
30
|
+
# ToDo => add prefix to arguments
|
31
|
+
# if self.position == 'prefix'
|
32
|
+
#prefix_position = self.operation.gatget.arguments.index(self.prefix)
|
33
|
+
#self.value = self.operation.gatget.arguments[
|
34
|
+
# else
|
35
|
+
self.value = self.operation.gatget.arguments[self.position]
|
36
|
+
# end
|
37
|
+
|
38
|
+
# get arguments
|
39
|
+
elsif self.type == 'get' or self.type == 'get_password'
|
40
|
+
|
41
|
+
# log direct question
|
42
|
+
get_question = self.config['get_question'] || "Gatget need a value for argument #{ self.name } (#{ self.description })"
|
43
|
+
|
44
|
+
self.operation.gatget.logger.log("direct", 'get_argument', get_question)
|
45
|
+
|
46
|
+
system "stty -echo" if self.type == 'get_password' # remove letter echo
|
47
|
+
|
48
|
+
self.value = $stdin.gets.chomp
|
49
|
+
|
50
|
+
system "stty echo" if self.type == 'get_password' # remove letter echo
|
51
|
+
|
52
|
+
# argument missing but not required
|
53
|
+
elsif self.optional
|
54
|
+
self.operation.gatget.logger.log("info", "missing argument #{ self.name } at operation #{ self.operation.name }. Argument is marked as optional")
|
55
|
+
else
|
56
|
+
raise GatgetArgumentException.new("Missing dependence argument #{ self.name } (@#{ self.type}) ", "evalue_program_dependence")
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
=begin
|
2
|
+
|
3
|
+
:file => dependences.rb
|
4
|
+
:author => (c) 2008-2009 A.C. Gnoxys info@gnoxys.net
|
5
|
+
|
6
|
+
######################################################################################
|
7
|
+
## This file is part of GAT: http://gat.rubyforge.org ##
|
8
|
+
## ##
|
9
|
+
## GAT (Gnoxys Administration Tools) is released under the GPL License 3 or higher. ##
|
10
|
+
## You can get a copy of the license easily at http://www.gnu.org/licenses/gpl.html.##
|
11
|
+
######################################################################################
|
12
|
+
|
13
|
+
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
|
14
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
15
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
16
|
+
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
17
|
+
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
18
|
+
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
19
|
+
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
20
|
+
|
21
|
+
=end
|
22
|
+
|
23
|
+
|
24
|
+
module Gat
|
25
|
+
module Dependence
|
26
|
+
class Base
|
27
|
+
|
28
|
+
attr_reader :operation
|
29
|
+
attr_reader :config
|
30
|
+
attr_reader :name
|
31
|
+
attr_reader :type
|
32
|
+
attr_reader :description
|
33
|
+
|
34
|
+
|
35
|
+
attr_accessor :value
|
36
|
+
|
37
|
+
|
38
|
+
def initialize(name, config, operation)
|
39
|
+
operation.gatget.logger.log("trace", "dependence", "Initialize dependence #{ self.class } @#{ name }")
|
40
|
+
@operation = operation
|
41
|
+
@config = config
|
42
|
+
@name = name
|
43
|
+
@description = @config['description'] || "Another #{ self.class } dependence named #{ self.name }"
|
44
|
+
end
|
45
|
+
|
46
|
+
|
47
|
+
def evalue
|
48
|
+
raise GatgetException.new("Evalue method is not available at Gat::Dependece. Create your own at #{ self.class }", 'evalue_dependence_without_type')
|
49
|
+
end
|
50
|
+
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
@@ -0,0 +1,104 @@
|
|
1
|
+
module Gat
|
2
|
+
module Dependence
|
3
|
+
class Folder < Base
|
4
|
+
|
5
|
+
attr_reader :value
|
6
|
+
attr_reader :path
|
7
|
+
attr_reader :config
|
8
|
+
attr_reader :mode
|
9
|
+
|
10
|
+
attr :tree
|
11
|
+
|
12
|
+
def initialize(name, config, operation)
|
13
|
+
super(name, config, operation)
|
14
|
+
@type = config['type'] || 'normal'
|
15
|
+
@tree = { }
|
16
|
+
@path = config['path'] || ''
|
17
|
+
@mode = config['mode'] || 0700
|
18
|
+
end
|
19
|
+
|
20
|
+
# Folders
|
21
|
+
def evalue
|
22
|
+
if self.path.blank?
|
23
|
+
raise GatgetConfigException.new("folder #{ self.name } doesnt have a path attribute at config", 'evalue_folder_dependence')
|
24
|
+
end
|
25
|
+
|
26
|
+
# mount directory
|
27
|
+
mounted? if self.type == 'mount'
|
28
|
+
|
29
|
+
# main folder
|
30
|
+
unless File.exists?(self.path) and File.directory?(self.path)
|
31
|
+
FileUtils.mkdir_p(self.path, :mode => self.mode)
|
32
|
+
end
|
33
|
+
|
34
|
+
# tree
|
35
|
+
if self.config['tree'] and self.config['tree'].any?
|
36
|
+
self.config['tree'].each do |subfolder|
|
37
|
+
absolut_folder = "#{ self.path }/#{ subfolder }"
|
38
|
+
unless File.exists?(absolut_folder) and File.directory?(absolut_folder)
|
39
|
+
FileUtils.mkdir_p(absolut_folder, :mode => self.mode)
|
40
|
+
end
|
41
|
+
self.tree["#{ self.name }_#{ subfolder.gsub(/\//,'_') }"] = absolut_folder
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
# Folder dependence value is special, because it can be the root folder or one subfolder at tree
|
47
|
+
# so, we dont have a value attribute but method, and this method check by folder_name, which folder do we want
|
48
|
+
def value(folder_name)
|
49
|
+
ret = ''
|
50
|
+
if folder_name == self.name
|
51
|
+
ret = self.path
|
52
|
+
elsif self.tree.any?
|
53
|
+
self.tree.each_pair do |subfolder_name, subfolder_path|
|
54
|
+
ret = subfolder_path if subfolder_name == folder_name
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
if ret.blank?
|
59
|
+
raise GatgetException.new("Value for folder dependence #{ folder_name } doesnt return results", "value_folders_dependence")
|
60
|
+
end
|
61
|
+
ret
|
62
|
+
end
|
63
|
+
|
64
|
+
private
|
65
|
+
# check if folder is mounted, if not, try it, if doesnt work, launch GatgetProcessException
|
66
|
+
def mounted?
|
67
|
+
unless already_mounted?
|
68
|
+
unless mount_folder
|
69
|
+
raise Gat::GatgetProcessException.new("Unable to mount folder #{ self.name } at #{ self.path }", "mounted")
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
|
75
|
+
# Open Unix mounts folder and test that mounts table contents main folder
|
76
|
+
def already_mounted?
|
77
|
+
mounts_file = File.open('/proc/mounts', 'r')
|
78
|
+
mounted = false
|
79
|
+
mounts_file.each_line do |mount_line|
|
80
|
+
mounted = true if mount_line.split(" ")[2].include?(self.path)
|
81
|
+
end
|
82
|
+
mounted
|
83
|
+
end
|
84
|
+
|
85
|
+
|
86
|
+
def mount_folder
|
87
|
+
self.operation.gatget.logger.log("trace", "mount_folder", "Folder #{ self.name } is not mounted. Triying to mount")
|
88
|
+
|
89
|
+
pid_open4, stdin, stdout, stderr = Open4::popen4 "mount #{ self.path }"
|
90
|
+
|
91
|
+
ignored, status_open4 = Process::waitpid2 pid_open4
|
92
|
+
|
93
|
+
if status_open4.exitstatus == 0 # try to mount_folder
|
94
|
+
self.operation.gatget.logger.log("trace", "mount_folder", "Folder #{ self.name } nicely mounted ")
|
95
|
+
ret = true
|
96
|
+
else
|
97
|
+
self.operation.gatget.logger.log("error", "mount_folder", "#{ stderr.read }")
|
98
|
+
ret = false
|
99
|
+
end
|
100
|
+
ret
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
module Gat
|
2
|
+
module Dependence
|
3
|
+
class Program < Base
|
4
|
+
|
5
|
+
attr_reader :path
|
6
|
+
|
7
|
+
def initialize(name, config, operation)
|
8
|
+
super(name, config, operation)
|
9
|
+
@type = @config['type'] || 'external'
|
10
|
+
@path = @config['path'] || false
|
11
|
+
end
|
12
|
+
|
13
|
+
def evalue
|
14
|
+
self.path || evalue_from_shell
|
15
|
+
end
|
16
|
+
|
17
|
+
# Program is evalued through 'which' shell command
|
18
|
+
def evalue_from_shell
|
19
|
+
errors = ''
|
20
|
+
output = ''
|
21
|
+
process_id = ''
|
22
|
+
status = Open4.popen4 "which #{ self.name }" do |pid, stdin, stdout, stderr|
|
23
|
+
process_id = pid
|
24
|
+
errors = stderr.readlines.join('')
|
25
|
+
output = stdout.readlines.join('')
|
26
|
+
end
|
27
|
+
|
28
|
+
if not output.blank? and errors.blank? and status.exitstatus == 0
|
29
|
+
self.value = output.strip
|
30
|
+
else
|
31
|
+
raise GatgetConfigException.new("Dependece program #{ self.name } not found", "evalue_program_dependence")
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
data/lib/gat/email.rb
ADDED
@@ -0,0 +1,80 @@
|
|
1
|
+
=begin
|
2
|
+
This file is part of GAT: http://gat.rubyforge.org
|
3
|
+
|
4
|
+
(c) 2008-2009 A.C. Gnoxys info@gnoxys.net
|
5
|
+
|
6
|
+
GAT (Gnoxys Administration Tools) is released under the GPL License 3 or higher.
|
7
|
+
You can get a copy of the license easily at http://www.gnu.org/licenses/gpl.html.
|
8
|
+
|
9
|
+
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
|
10
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
11
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
12
|
+
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
13
|
+
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
14
|
+
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
15
|
+
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
16
|
+
=end
|
17
|
+
|
18
|
+
module Gat
|
19
|
+
module Email
|
20
|
+
|
21
|
+
# Create and deliver a email
|
22
|
+
def create_and_deliver_email(to, email_config, deliver_config)
|
23
|
+
email = new_email(to, deliver_config.merge(email_config))
|
24
|
+
send_email(email, deliver_config)
|
25
|
+
end
|
26
|
+
|
27
|
+
|
28
|
+
def send_email(email, smtp_config)
|
29
|
+
|
30
|
+
if !smtp_config or smtp_config.empty? or !smtp_config['send_by']
|
31
|
+
raise GatgetConfigException.new('email_config is empty or missing or send_by is not defined', 'send_email')
|
32
|
+
end
|
33
|
+
|
34
|
+
domain = self.config['server_domain'] || 'localhost'
|
35
|
+
email_from = smtp_config["send_from"] || "#{ self.class.name }@#{ domain }"
|
36
|
+
|
37
|
+
|
38
|
+
case smtp_config['send_by']
|
39
|
+
when 'smtp'
|
40
|
+
server = smtp_config['smtp_config']["server"] || 'localhost'
|
41
|
+
port = smtp_config['smtp_config']["port"] || 25
|
42
|
+
user = smtp_config['smtp_config']["user"] || ""
|
43
|
+
password = smtp_config['smtp_config']["password"] || ""
|
44
|
+
|
45
|
+
begin
|
46
|
+
Net::SMTP.start(server, port, server, user, password, :login) do |smtp|
|
47
|
+
smtp.send_mail email.encoded, email_from, email.destinations
|
48
|
+
end
|
49
|
+
rescue => error
|
50
|
+
raise GatgetConfigException.new(error, "send_email(smtp)",
|
51
|
+
{ :message => "Error sending mail to '#{email.destinations}' on '#{server}:#{port}': #{error}" })
|
52
|
+
end
|
53
|
+
|
54
|
+
when 'sendmail'
|
55
|
+
|
56
|
+
Net::SMTP.start('localhost', 25) do |smtp|
|
57
|
+
smtp.send_mail email.encoded, email_from, email.destinations
|
58
|
+
end
|
59
|
+
|
60
|
+
else
|
61
|
+
raise GatgetConfigException.new("undefined send_mail method #{ smtp_config['send_by'] } at config", 'send_email')
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
def new_email(to, options = {})
|
66
|
+
|
67
|
+
options ||= Hash.new
|
68
|
+
mail = TMail::Mail.new
|
69
|
+
mail.date = Time.now
|
70
|
+
mail.to = to
|
71
|
+
mail.subject = options['subject'] || "#{ self.class.name } email report"
|
72
|
+
mail.from = options['send_from'] || "#{ self.class.name.underscore }@#{ self.config['server_name'] }"
|
73
|
+
mail.cc = options['cc'] if options['cc']
|
74
|
+
mail.bcc = options['bcc'] if options['bcc']
|
75
|
+
|
76
|
+
mail.body = options['body'] || "empty body"
|
77
|
+
mail
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|