Package Products :: Package ZenEvents :: Module zenmail |
[hide private]
[frames] | no frames]

# Source Code for Module Products.ZenEvents.zenmail

      1  ###########################################################################
      2  #
      3  # This program is part of Zenoss Core, an open source monitoring platform.
      4  # Copyright (C) 2007, Zenoss Inc.
      5  #
      6  # This program is free software; you can redistribute it and/or modify it
      7  # under the terms of the GNU General Public License version 2 as published by
      8  # the Free Software Foundation.
      9  #
     10  # For complete information please visit: http://www.zenoss.com/oss/
     11  #
     12  ###########################################################################
     13  # Notes: database wants events in UTC time
     14  # Events page shows local time, as determined on the server where zenoss runs
     15
     16  __doc__='''zenmail
     17
     18  Turn email messages into events.
     19
     20  '''
     21
     22  from EventServer import EventServer
     23
     24  from twisted.mail import smtp
     25  from twisted.internet import reactor, protocol, defer
     26  from zope.interface import implements
     27
     28  from email.Header import Header
     29  import email
     30
     31  from MailProcessor import MailProcessor
     32
     33  import logging
     34  log = logging.getLogger("zen.mail")
     35
     36
     37 -class ZenossEventPoster(object):
     38      implements(smtp.IMessage)
     39
     40 -    def __init__(self, processor):
     41          self.lines = []
     42          self.processor = processor
     43
     44
     45 -    def lineReceived(self, line):
     46          self.lines.append(line)
     47
     48
     49 -    def postEvent(self, messageStr):
     50          email.message_from_string(messageStr)
     51          self.processor.process(messageStr)
     52
     53
     54 -    def eomReceived(self):
     55          log.info('message data completed.')
     56          self.lines.append('')
     57          messageData = '\n'.join(self.lines)
     58
     59          self.postEvent(messageData)
     60
     61          if True:
     62              return defer.succeed(None)
     63          else:
     64              return defer.failure(None)
     65
     66
     67 -    def connectionLost(self):
     68          log.info('connection lost unexpectedly')
     69          del(self.lines)
     70
     71
     72 -class ZenossDelivery(object):
     73      implements(smtp.IMessageDelivery)
     74
     75 -    def __init__(self, processor):
     76          self.processor = processor
     77
     78
     79 -    def receivedHeader(self, helo, unused, ignored):
     80          myHostname, self.clientIP = helo
     81          date = smtp.rfc822date()
     82
     83          headerValue = 'by %s from %s with ESMTP ; %s' % (
     84              myHostname, self.clientIP, date)
     85
     86          log.info('relayed (or sent directly) from: %s' % self.clientIP)
     87
     88          header = 'Received: %s' % Header(headerValue)
     89          return header
     90
     91
     92 -    def validateTo(self, user):
     93          log.info('to: %s' % user.dest)
     94          return self.makePoster
     95
     96
     97 -    def makePoster(self):
     98          return ZenossEventPoster(self.processor)
     99
    100
    101 -    def validateFrom(self, unused, originAddress):
    102          log.info("from: %s" % originAddress)
    103          return originAddress
    104
    105
    106 -class SMTPFactory(protocol.ServerFactory):
    107 -    def __init__(self, processor):
    108          self.processor = processor
    109
    110 -    def buildProtocol(self, unused):
    111          delivery = ZenossDelivery(self.processor)
    112          smtpProtocol = smtp.SMTP(delivery)
    113          smtpProtocol.factory = self
    114          return smtpProtocol
    115
    116
    117 -class ZenMail(EventServer):
    118      name = 'zenmail'
    119
    120 -    def __init__(self):
    121          EventServer.__init__(self)
    122          if (self.options.useFileDescriptor < 0 and \
    123              self.options.listenPort < 1024):
    124              self.openPrivilegedPort('--listen',
    125                  '--proto=tcp', '--port=%s:%d' % (
    126                      self.options.listenip, self.options.listenPort))
    127
    128          self.changeUser()
    129          self.processor = MailProcessor(self, self.options.eventseverity)
    130
    131          self.factory = SMTPFactory(self.processor)
    132
    133          log.info("listening on %s:%d" % (
    134              self.options.listenip, self.options.listenPort))
    135          if self.options.useFileDescriptor != -1:
    136              self.useTcpFileDescriptor(int(self.options.useFileDescriptor),
    137                                        self.factory)
    138          else:
    139              reactor.listenTCP(self.options.listenPort, self.factory,
    140                  interface=self.options.listenip)
    141
    142
    143 -    def handleError(self, error):
    144          log.error(error)
    145          log.error(error.getErrorMessage())
    146
    147          self.finish()
    148
    149
    150 -    def _finish(self):
    151          self.finish()
    152
    153
    154 -    def buildOptions(self):
    155          EventServer.buildOptions(self)
    156          self.parser.add_option('--useFileDescriptor',
    157              dest='useFileDescriptor',
    158              default=-1,
    159              type="int",
    160              help="File descriptor to use for listening")
    161          self.parser.add_option('--listenPort',
    162              dest='listenPort',
    163              default="25",
    164              type="int",
    165              help="Alternative listen port to use")
    166          self.parser.add_option('--eventseverity',
    167              dest='eventseverity',
    168              default="2",
    169              type="int",
    170              help="Severity for events created")
    171          self.parser.add_option('--listenip',
    172              dest='listenip',
    173              default='0.0.0.0',
    174              help='IP address to listen on. Default is 0.0.0.0')
    175
    176
    177  if __name__ == '__main__':
    178      ZenMail().run()
    179