forked from ManageIQ/manageiq
-
Notifications
You must be signed in to change notification settings - Fork 1
/
generic_mailer.rb
198 lines (169 loc) · 6.04 KB
/
generic_mailer.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
require 'hamlit'
class GenericMailer < ActionMailer::Base
include Vmdb::Logging
def self.deliver(method, options = {})
_log.info("starting: method: #{method} options: #{options} ")
options[:attachment] &&= blob_to_attachment(options[:attachment])
options[:sent_on] = Time.now
msg = send(method, options)
begin
msg.deliver_now
# catch delivery errors if raised,
rescue Net::SMTPError => e
invalid = []
# attempt to resend message to recipients individually
rcpts = [msg.to].flatten
rcpts.each do |rcpt|
rcpt.split(',').each do |to|
options[:to] = to
individual = send(method, options)
begin
individual.deliver_now
rescue Net::SMTPError
invalid << to
end
end
end
_log.error("method: #{method} options: #{options} delivery-error #{e} recipients #{invalid}")
# connection errors, and other if raised
rescue => e
_log.error("method: #{method} delivery-error: #{e} attempting to resend")
# attempt to deliver one more time
begin
msg.deliver_now
rescue => e
_log.error("method: #{method} options: #{options} delivery-error #{e}")
end
end
msg
end
def self.deliver_queue(method, options = {})
return unless MiqRegion.my_region.role_assigned?('notifier')
_log.info("starting: method: #{method} args: #{options} ")
options[:attachment] &&= attachment_to_blob(options[:attachment])
MiqQueue.submit_job(
:service => "notifier",
:class_name => name,
:method_name => 'deliver',
:args => [method, options]
)
end
def self.attachment_to_blob(attachment, attachment_filename = "evm_attachment")
return nil if attachment.nil?
case attachment
when Array
counter = 0
attachment.collect { |a| attachment_to_blob(a, "evm_attachment_#{counter += 1}") }
when Numeric # Blob ID
attachment_to_blob(:attachment_id => attachment)
when String # Actual Body
attachment_to_blob(:body => attachment)
when Hash
attachment[:filename] ||= attachment_filename
attachment[:attachment_id] ||= begin
blob = BinaryBlob.new(:name => "GenericMailer", :data_type => "text")
blob.binary = attachment.delete(:body)
blob.save
blob.id
end
attachment
else
raise "Unexpected Attachment Class: <#{attachment.class.name}>"
end
end
def self.blob_to_attachment(attachment)
return nil if attachment.nil?
case attachment
when Array
attachment.collect { |a| blob_to_attachment(a) }
when Numeric # Blob ID
blob_to_attachment(:attachment_id => attachment)
when String # Actual Body
blob_to_attachment(:attachment => attachment)
when Hash
if attachment[:attachment_id].kind_of?(Numeric)
attachment[:body] ||= begin
blob = BinaryBlob.find(attachment.delete(:attachment_id))
body = blob.binary unless blob.nil?
blob.destroy unless blob.nil?
body
end
end
attachment[:filename] ||= "evm_attachment"
attachment
else
raise "Unexpected Attachment Class: <#{attachment.class.name}>"
end
end
def generic_notification(options)
set_mailer_smtp
prepare_generic_email(options)
end
def automation_notification(options)
set_mailer_smtp
prepare_generic_email(options)
end
def policy_action_email(options)
set_mailer_smtp
@miq_action_hash = options[:miq_action_hash] || {}
prepare_generic_email(options)
end
def test_email(to, settings)
set_mailer_smtp(settings)
options = {
:to => to,
:from => settings[:from],
:subject => "#{Vmdb::Appliance.PRODUCT_NAME} Test Email",
:body => "If you have received this email, your SMTP settings are correct."
}
prepare_generic_email(options)
end
def self.default_for_enable_starttls_auto
true
end
def self.openssl_verify_modes
[
[_("None"), "none"],
[_("Peer"), "peer"],
[_("Client Once"), "client_once"],
[_("Fail If No Peer Cert"), "fail_if_no_peer_cert"]
]
end
def self.authentication_modes
[[_("login"), "login"], [_("plain"), "plain"], [_("none"), "none"]]
end
protected
def prepare_generic_email(options)
_log.info("options: #{options.inspect}")
options[:from] = ::Settings.smtp.from if options[:from].blank?
@content = options[:body]
options[:attachment] ||= []
options[:attachment].each do |a|
name = a[:filename]
next if name.nil?
attachments[name] = {:mime_type => a[:content_type], :content => a[:body]}
end
mail(:subject => options[:subject], :to => options[:to], :from => options[:from], :cc => options[:cc], :bcc => options[:bcc], :date => options[:sent_on])
end
DESTINATION_SMTP_KEYS = [:address, :port, :domain]
AUTHENTICATION_SMTP_KEYS = [:authentication, :user_name, :password]
OPTIONAL_SMTP_KEYS = [:enable_starttls_auto, :openssl_verify_mode]
def set_mailer_smtp(evm_settings = nil)
evm_settings ||= ::Settings.smtp
am_settings = {}
DESTINATION_SMTP_KEYS.each { |key| am_settings[key] = evm_settings[key] }
am_settings[:address] ||= evm_settings[:host] # vmdb.yml has key :host, ActionMailer expects :address
evm_settings[:authentication] ||= :none
case evm_settings[:authentication].to_s.to_sym
when :none then AUTHENTICATION_SMTP_KEYS.each { |key| am_settings[key] = nil }
when :plain, :login then AUTHENTICATION_SMTP_KEYS.each { |key| am_settings[key] = evm_settings[key] }
else raise ArgumentError, "authentication value #{evm_settings[:authentication].inspect} must be one of: 'none', 'plain', 'login'"
end
OPTIONAL_SMTP_KEYS.each { |key| am_settings[key] = evm_settings[key] if evm_settings.key?(key) }
ActionMailer::Base.smtp_settings = am_settings
log_smtp_settings = am_settings.dup
log_smtp_settings.delete(:password)
_log.info("Mailer settings: #{log_smtp_settings.inspect}")
nil
end
end