You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

176 lines
5.6 KiB

import re
import socket
from email.header import Header
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
import sendemail_common
import splunk.admin as admin
import splunk.entity as en
import splunk.mining.dcutils as dcu
import splunk.secure_smtplib as secure_smtplib
import splunk.ssl_context as ssl_context
logger = dcu.getLogger()
charset = "UTF-8"
EMAIL_DELIM = re.compile(r'\s*[,;]\s*')
def isASCII(str):
for i in str:
if ord(i) > 127:
return False
return True
def toBool(strVal):
if strVal == None:
return False
lStrVal = strVal.lower()
if lStrVal == "true" or lStrVal == "t" or lStrVal == "1" or lStrVal == "yes" or lStrVal == "y" :
return True
return False
class SendemailRestHandler(admin.MConfigHandler):
def __init__(self, scriptMode, ctxInfo):
admin.MConfigHandler.__init__(self, scriptMode, ctxInfo)
self.shouldAutoList = False
# get firs arg
def gfa(self, name, defaultVal=''):
if self.hasNonEmptyArg(name):
val = self.callerArgs.get(name, [defaultVal])[0]
if val != None: return val
return defaultVal
def hasNonEmptyArg(self, name):
return name in self.callerArgs and self.callerArgs.get(name) != None
def setup(self):
if self.requestedAction == admin.ACTION_CREATE or self.requestedAction == admin.ACTION_EDIT:
for arg in ['to', 'body']:
self.supportedArgs.addReqArg(arg)
for arg in ['cc', 'bcc', 'from', 'subject', 'format', 'username', 'password', 'server', 'use_ssl', 'use_tls']:
self.supportedArgs.addOptArg(arg)
userInfo = en.getEntity('/authentication/', 'current-context', sessionKey=self.getSessionKey())
if userInfo.get('username') != 'splunk-system-user':
raise admin.PermissionsException("This handler can only be called by the Splunk system user.")
def handleList(self, confInfo):
pass
def handleCreate(self, confInfo):
message = MIMEMultipart()
subject = self.gfa('subject')
body = self.gfa('body')
bodyformat = self.gfa('format', 'html')
server = self.gfa('server', 'localhost')
username = self.gfa('username')
password = self.gfa('password')
use_ssl = toBool(self.gfa('use_ssl'))
use_tls = toBool(self.gfa('use_tls'))
sessionKey = self.getSessionKey()
sslSettings = self.getAlertActions(sessionKey)
# Open debate whether we should get user and password from alert actions
# username = sslSettings.get('auth_username', '')
# password = sslSettings.get('clear_password', '')
if isASCII(subject):
message['Subject'] = subject
else:
message['Subject'] = Header(subject, charset)
recipients = []
for t in self.callerArgs.get('to'):
recipients.extend(EMAIL_DELIM.split(t))
message['To'] = ', '.join(self.callerArgs.get('to'))
if self.hasNonEmptyArg('cc') :
cc = [x for x in self.callerArgs.get('cc') if x != None]
if len(cc) > 0:
message['Cc'] = ', '.join(cc)
for t in cc:
recipients.extend(EMAIL_DELIM.split(t))
if self.hasNonEmptyArg('bcc'):
bcc = [x for x in self.callerArgs.get('bcc') if x != None]
if len(bcc) > 0:
message['Bcc'] = ', '.join(bcc)
for t in bcc:
recipients.extend(EMAIL_DELIM.split(t))
sender = 'splunk'
if self.hasNonEmptyArg('from'):
sender = self.gfa('from')
if sender.find("@") == -1:
sender = sender + '@' + socket.gethostname()
if sender.endswith("@"):
sender = sender + 'localhost'
message['From'] = sender
message.attach(MIMEText(body, bodyformat, _charset=charset))
if use_ssl or use_tls:
sslHelper = ssl_context.SSLHelper()
serverConfJSON = sslHelper.getServerSettings(sessionKey)
# Pass in settings from alert_actions.conf into context
ctx = sslHelper.createSSLContextFromSettings(
sslConfJSON=sslSettings,
serverConfJSON=serverConfJSON,
isClientContext=True)
# send the mail
if not use_ssl:
smtp = secure_smtplib.SecureSMTP(host=server)
else:
smtp = secure_smtplib.SecureSMTP_SSL(host=server, sslContext=ctx)
if use_tls:
smtp.starttls(ctx)
if len(username) > 0 and len(password) > 0:
smtp.login(username, password)
# Installed SMTP daemon may not support UTF8.
# This can only be determined if SMTPNotSupportedError is raised.
# Try without SMTPUTF8 option if raised.
audit_msg = 'Sending email for backgrounded search job: subject="%s", sender="%s", recipients="%s", server="%s"'
logger.info(audit_msg, message['Subject'], sender, str(recipients), server)
# Installed SMTP daemon may not support UTF8 as well as
# it may throw other exceptions also.
error = sendemail_common.sendEmailWithUTF8(smtp, sender, recipients, message.as_string())
if (error is not None):
logger.debug('send mail with utf8 failed. retrying without utf8 option. Error: %s', str(error))
smtp.sendmail(sender, recipients, message.as_string())
smtp.quit()
def getAlertActions(self, sessionKey):
settings = None
try:
settings = en.getEntity('/configs/conf-alert_actions', 'email', sessionKey=sessionKey)
logger.debug("sendemail_handler.getAlertActions conf file settings %s" % settings)
except Exception as e:
logger.error("Could not access or parse email stanza of alert_actions.conf. Error=%s" % str(e))
return settings
# initialize the handler
admin.init(SendemailRestHandler, admin.CONTEXT_APP_AND_USER)

Powered by BW's shoe-string budget.