Beispiel #1
0
    def publish(self, title, report_parts, rawfh):
        """
        Publish the report parts to local files. Each report part is a text
        with a title and specific extension. For html and plaintext publishing
        the report part is unique, for csv publishing the stats and unparsed
        string are plain text and report items are csv texts.
        """
        logger.info('Checking and creating the report directories')

        workdir = os.path.join(self.pubdir, self.dirname)
        filename = None

        if not os.path.isdir(workdir):
            try: 
                os.makedirs(workdir)
            except OSError as e:
                logger.error('Error creating directory "{0}": {0}'.format(
                             workdir, e))
                logger.error('File publisher exiting.')
                return

        fmtname = '{0}-{1}-{2}.{3}' if len(report_parts) > 1 else '{0}.{3}'

        for i in range(len(report_parts)):
            ext = report_parts[i].ext

            # Skip report formats not related with this publisher
            if not self.has_format(ext):
                continue

            filename = fmtname.format(self.filename, i, report_parts[i].title, ext)
            repfile = os.path.join(workdir, filename)
            
            logger.info('Dumping the report part {1} into {0}'.format(repfile, i))
            
            fh = open(repfile, 'w')
            fh.write(report_parts[i].text)
            fh.close()
            print('Report {0}saved in: {1}'.format('part ' if ext == 'csv' else '', repfile))

        if self.notify:
            logger.info('Creating an email message')
            publoc = '{0}/{1}/{2}'.format(self.pubroot, self.dirname, filename)

            from email.mime.text import MIMEText
            eml = MIMEText('New Lograptor report is available at:\r\n{0}'.format(
                           publoc))

            eml['Subject'] = '{0} (report notification)'.format(title)
            eml['To'] = ', '.join(self.notify)
            eml['X-Mailer'] = u'{0}-{1}'.format(lograptor.Lograptor.__name__, __version__)

            msg = eml.as_string()

            logger.info('Figuring out if we are using sendmail or smtplib')
            if self.smtpserv[0] == '/':
                mail_sendmail(self.smtpserv, msg)
            else:
                mail_smtp(self.smtpserv, self.fromaddr, self.notify, msg)

            print('Notification mailed to: {0}'.format(','.join(self.notify)))

        if self.rawlogs:
            logfilen = '{0}.log'.format(self.filename)
            logfile = os.path.join(workdir, '{0}.gz'.format(logfilen))

            logger.info('Gzipping logs and writing them to {0}'.format(logfilen))
            outfh = open(logfile, 'w+b')
            do_chunked_gzip(rawfh, outfh, logfilen)
            outfh.close()
            print('Gzipped logs saved in: {0}'.format(logfile))

        # Purge old reports
        self.prune_old()
Beispiel #2
0
    def publish(self, title, report_parts, rawfh):
        """
        Publish the report parts to local files. Each report part is a text
        with a title and specific extension. For html and plaintext publishing
        the report part is unique, for csv publishing the stats and unparsed
        string are plain text and report items are csv texts.
        """
        logger.info('Checking and creating the report directories')

        workdir = os.path.join(self.pubdir, self.dirname)
        filename = None

        if not os.path.isdir(workdir):
            try: 
                os.makedirs(workdir)
            except OSError as e:
                logger.error('Error creating directory "{0}": {0}'.format(
                             workdir, e))
                logger.error('File publisher exiting.')
                return

        fmtname = '{0}-{1}-{2}.{3}' if len(report_parts) > 1 else '{0}.{3}'

        for i in range(len(report_parts)):
            ext = report_parts[i].ext

            # Skip report formats not related with this publisher
            if not self.has_format(ext):
                continue

            filename = fmtname.format(self.filename, i, report_parts[i].title, ext)
            repfile = os.path.join(workdir, filename)
            
            logger.info('Dumping the report part {1} into {0}'.format(repfile, i))
            
            fh = open(repfile, 'w')
            fh.write(report_parts[i].text)
            fh.close()
            print(('Report {0}saved in: {1}'.format('part ' if ext == 'csv' else '', repfile)))

        if self.notify:
            logger.info('Creating an email message')
            publoc = '{0}/{1}/{2}'.format(self.pubroot, self.dirname, filename)

            from email.mime.text import MIMEText
            eml = MIMEText('New Lograptor report is available at:\r\n{0}'.format(
                           publoc))

            eml['Subject'] = '{0} (report notification)'.format(title)
            eml['To'] = ', '.join(self.notify)
            eml['X-Mailer'] = '{0}-{1}'.format(lograptor.Lograptor.__name__, __version__)

            msg = eml.as_string()

            logger.info('Figuring out if we are using sendmail or smtplib')
            if self.smtpserv[0] == '/':
                mail_sendmail(self.smtpserv, msg)
            else:
                mail_smtp(self.smtpserv, self.fromaddr, self.notify, msg)

            print(('Notification mailed to: {0}'.format(','.join(self.notify))))

        if self.rawlogs:
            logfilen = '{0}.log'.format(self.filename)
            logfile = os.path.join(workdir, '{0}.gz'.format(logfilen))

            logger.info('Gzipping logs and writing them to {0}'.format(logfilen))
            outfh = open(logfile, 'w+b')
            do_chunked_gzip(rawfh, outfh, logfilen)
            outfh.close()
            print(('Gzipped logs saved in: {0}'.format(logfile)))

        # Purge old reports
        self.prune_old()
Beispiel #3
0
    def publish(self, title, report_parts, rawfh):
        """
        Publish by sending the report by e-mail
        """
        from email.mime.base import MIMEBase
        from email.mime.text import MIMEText
        from email.mime.multipart import MIMEMultipart
        from email.utils import formatdate, make_msgid

        logger.info('Creating an email message')

        logger.debug('Creating a main header')
        root_part = MIMEMultipart('mixed')
        root_part.preamble = 'This is a multi-part message in MIME format.'

        has_text_plain = any(text_part.ext == 'txt' for text_part in report_parts)

        logger.debug('Creating the text/"text_type" parts')
        for text_part in report_parts:

            # Skip report formats not related with this publisher
            if not self.has_format(text_part.ext):
                continue

            if text_part.ext == 'txt' or (not has_text_plain and text_part.ext == 'html'):
                root_part.attach(MIMEText(text_part.text, text_part.ext, 'utf-8'))
            else:
                attach_part = MIMEText(text_part.text, text_part.ext, 'utf-8')
                attach_part.add_header('Content-Disposition', 'attachment',
                                       filename='{0}.{1}'.format(text_part.title, text_part.ext))
                root_part.attach(attach_part)

        if self.rawlogs:
            try:
                import cStringIOcd
                out = cStringIO.StringIO()
            except ImportError:
                import io
                out = io.StringIO()  
            
            do_chunked_gzip(rawfh, out, filename='raw.log.gz')
            out.seek(0, os.SEEK_END)
            size = out.tell()
            
            if size > self.rawlogs_limit:
                logger.warning('{0} is over the defined max of "{1}"'
                               .format(size, self.rawlogs))
                logger.warning('Not attaching the raw logs')
            else:
                logger.debug('Creating the application/x-gzip part')
                attach_part = MIMEBase('application', 'x-gzip')
                attach_part.set_payload(out.getvalue())

                from email.encoders import encode_base64

                logger.debug('Encoding the gzipped raw logs with base64')
                encode_base64(attach_part)
                attach_part.add_header('Content-Disposition', 'attachment',
                                       filename='raw.log.gz')
                root_part.attach(attach_part)

        if self.gpg_encrypt:
            logger.info('Encrypting the message')

            from StringIO import StringIO
            try:
                import gpgme

                if self.gpg_keyringdir and os.path.exists(self.gpg_keyringdir):
                    logger.debug('Setting keyring dir to {0}'.format(
                                 self.gpg_keyringdir))
                    os.environ['GNUPGHOME'] = self.gpg_keyringdir

                msg = root_part.as_string()
                logger.debug('----Cleartext follows----')
                logger.debug(msg)
                logger.debug('----Cleartext ends----')

                cleartext = StringIO(msg)
                ciphertext = StringIO()

                ctx = gpgme.Context()

                ctx.armor = True

                recipients = []
                signers = []

                logger.debug('gpg_recipients={0}'.format(self.gpg_recipients))
                logger.debug('gpg_signers={0}'.format(self.gpg_signers))

                if self.gpg_recipients is not None:
                    for recipient in self.gpg_recipients:
                        logger.debug('Looking for an encryption key for {0}'.format(
                                     recipient))
                        recipients.append(ctx.get_key(recipient))
                else:
                    for key in ctx.keylist():
                        for subkey in key.subkeys:
                            if subkey.can_encrypt:
                                logger.debug('Found can_encrypt key={0}'.format(
                                             subkey.keyid))
                                recipients.append(key)
                                break

                if self.gpg_signers is not None:
                    for signer in self.gpg_signers:
                        logger.debug('Looking for a signing key for {0}'.format(
                                     signer))
                        signers.append(ctx.get_key(signer))

                if len(signers) > 0:
                    logger.info('Encrypting and signing the report')
                    ctx.signers = signers
                    ctx.encrypt_sign(recipients, gpgme.ENCRYPT_ALWAYS_TRUST,
                                     cleartext, ciphertext)

                else:
                    logger.info('Encrypting the report')
                    ctx.encrypt(recipients, gpgme.ENCRYPT_ALWAYS_TRUST,
                                cleartext, ciphertext)

                logger.debug('Creating the MIME envelope for PGP')

                gpg_envelope_part = MIMEMultipart('encrypted')
                gpg_envelope_part.set_param('protocol',
                                            'application/pgp-encrypted', header='Content-Type')
                gpg_envelope_part.preamble = ('This is an OpenPGP/MIME encrypted message '
                                              '(RFC 2440 and 3156)')

                gpg_mime_version_part = MIMEBase('application', 'pgp-encrypted')
                gpg_mime_version_part.add_header('Content-Disposition',
                                                 'PGP/MIME version identification')
                gpg_mime_version_part.set_payload('Version: 1')

                gpg_payload_part = MIMEBase('application', 'octet-stream', 
                                            name='encrypted.asc')
                gpg_payload_part.add_header('Content-Disposition', 
                                            'OpenPGP encrypted message')
                gpg_payload_part.add_header('Content-Disposition', 'inline',
                                            filename='encrypted.asc')
                gpg_payload_part.set_payload(ciphertext.getvalue())

                gpg_envelope_part.attach(gpg_mime_version_part)
                gpg_envelope_part.attach(gpg_payload_part)

                # envelope becomes the new root part
                root_part = gpg_envelope_part

            except ImportError:
                logger.error('Need crypto libraries for gpg_encrypt.')
                logger.error('Install pygpgme for GPG encryption support.')
                logger.error('Not mailing the report out of caution.')
                return

        # Define headers
        root_part['Date'] = formatdate()
        root_part['From'] = self.fromaddr
        root_part['To'] = ', '.join(self.mailto)
        root_part['Subject'] = title
        root_part['Message-Id'] = make_msgid()
        root_part['X-Mailer'] = u'{0}-{1}'.format(lograptor.Lograptor.__name__, __version__)
        
        logger.debug('Creating the message as string')
        msg = root_part.as_string()

        logger.debug('----Message follows----')
        logger.debug(msg)
        logger.debug('----Message ends----')

        logger.info('Figuring out if we are using sendmail or smtplib')

        if re.compile('^/').search(self.smtpserv):
            mail_sendmail(self.smtpserv, msg)
        else:   
            mail_smtp(self.smtpserv, self.fromaddr, self.mailto, msg)

        print('Mailed the report to: {0}'.format(','.join(self.mailto)))
Beispiel #4
0
    def publish(self, title, report_parts, rawfh):
        """
        Publish by sending the report by e-mail
        """
        from email.mime.base import MIMEBase
        from email.mime.text import MIMEText
        from email.mime.multipart import MIMEMultipart
        from email.utils import formatdate, make_msgid

        logger.info('Creating an email message')

        logger.debug('Creating a main header')
        root_part = MIMEMultipart('mixed')
        root_part.preamble = 'This is a multi-part message in MIME format.'

        has_text_plain = any(text_part.ext == 'txt' for text_part in report_parts)

        logger.debug('Creating the text/"text_type" parts')
        for text_part in report_parts:

            # Skip report formats not related with this publisher
            if not self.has_format(text_part.ext):
                continue

            if text_part.ext == 'txt' or (not has_text_plain and text_part.ext == 'html'):
                root_part.attach(MIMEText(text_part.text, text_part.ext, 'utf-8'))
            else:
                attach_part = MIMEText(text_part.text, text_part.ext, 'utf-8')
                attach_part.add_header('Content-Disposition', 'attachment',
                                       filename='{0}.{1}'.format(text_part.title, text_part.ext))
                root_part.attach(attach_part)

        if self.rawlogs:
            try:
                import cStringIOcd
                out = cStringIO.StringIO()
            except ImportError:
                import io
                out = io.StringIO()  
            
            do_chunked_gzip(rawfh, out, filename='raw.log.gz')
            out.seek(0, os.SEEK_END)
            size = out.tell()
            
            if size > self.rawlogs_limit:
                logger.warning('{0} is over the defined max of "{1}"'
                               .format(size, self.rawlogs))
                logger.warning('Not attaching the raw logs')
            else:
                logger.debug('Creating the application/x-gzip part')
                attach_part = MIMEBase('application', 'x-gzip')
                attach_part.set_payload(out.getvalue())

                from email.encoders import encode_base64

                logger.debug('Encoding the gzipped raw logs with base64')
                encode_base64(attach_part)
                attach_part.add_header('Content-Disposition', 'attachment',
                                       filename='raw.log.gz')
                root_part.attach(attach_part)

        if self.gpg_encrypt:
            logger.info('Encrypting the message')

            from io import StringIO
            try:
                import gpgme

                if self.gpg_keyringdir and os.path.exists(self.gpg_keyringdir):
                    logger.debug('Setting keyring dir to {0}'.format(
                                 self.gpg_keyringdir))
                    os.environ['GNUPGHOME'] = self.gpg_keyringdir

                msg = root_part.as_string()
                logger.debug('----Cleartext follows----')
                logger.debug(msg)
                logger.debug('----Cleartext ends----')

                cleartext = StringIO(msg)
                ciphertext = StringIO()

                ctx = gpgme.Context()

                ctx.armor = True

                recipients = []
                signers = []

                logger.debug('gpg_recipients={0}'.format(self.gpg_recipients))
                logger.debug('gpg_signers={0}'.format(self.gpg_signers))

                if self.gpg_recipients is not None:
                    for recipient in self.gpg_recipients:
                        logger.debug('Looking for an encryption key for {0}'.format(
                                     recipient))
                        recipients.append(ctx.get_key(recipient))
                else:
                    for key in ctx.keylist():
                        for subkey in key.subkeys:
                            if subkey.can_encrypt:
                                logger.debug('Found can_encrypt key={0}'.format(
                                             subkey.keyid))
                                recipients.append(key)
                                break

                if self.gpg_signers is not None:
                    for signer in self.gpg_signers:
                        logger.debug('Looking for a signing key for {0}'.format(
                                     signer))
                        signers.append(ctx.get_key(signer))

                if len(signers) > 0:
                    logger.info('Encrypting and signing the report')
                    ctx.signers = signers
                    ctx.encrypt_sign(recipients, gpgme.ENCRYPT_ALWAYS_TRUST,
                                     cleartext, ciphertext)

                else:
                    logger.info('Encrypting the report')
                    ctx.encrypt(recipients, gpgme.ENCRYPT_ALWAYS_TRUST,
                                cleartext, ciphertext)

                logger.debug('Creating the MIME envelope for PGP')

                gpg_envelope_part = MIMEMultipart('encrypted')
                gpg_envelope_part.set_param('protocol',
                                            'application/pgp-encrypted', header='Content-Type')
                gpg_envelope_part.preamble = ('This is an OpenPGP/MIME encrypted message '
                                              '(RFC 2440 and 3156)')

                gpg_mime_version_part = MIMEBase('application', 'pgp-encrypted')
                gpg_mime_version_part.add_header('Content-Disposition',
                                                 'PGP/MIME version identification')
                gpg_mime_version_part.set_payload('Version: 1')

                gpg_payload_part = MIMEBase('application', 'octet-stream', 
                                            name='encrypted.asc')
                gpg_payload_part.add_header('Content-Disposition', 
                                            'OpenPGP encrypted message')
                gpg_payload_part.add_header('Content-Disposition', 'inline',
                                            filename='encrypted.asc')
                gpg_payload_part.set_payload(ciphertext.getvalue())

                gpg_envelope_part.attach(gpg_mime_version_part)
                gpg_envelope_part.attach(gpg_payload_part)

                # envelope becomes the new root part
                root_part = gpg_envelope_part

            except ImportError:
                logger.error('Need crypto libraries for gpg_encrypt.')
                logger.error('Install pygpgme for GPG encryption support.')
                logger.error('Not mailing the report out of caution.')
                return

        # Define headers
        root_part['Date'] = formatdate()
        root_part['From'] = self.fromaddr
        root_part['To'] = ', '.join(self.mailto)
        root_part['Subject'] = title
        root_part['Message-Id'] = make_msgid()
        root_part['X-Mailer'] = '{0}-{1}'.format(lograptor.Lograptor.__name__, __version__)
        
        logger.debug('Creating the message as string')
        msg = root_part.as_string()

        logger.debug('----Message follows----')
        logger.debug(msg)
        logger.debug('----Message ends----')

        logger.info('Figuring out if we are using sendmail or smtplib')

        if re.compile('^/').search(self.smtpserv):
            mail_sendmail(self.smtpserv, msg)
        else:   
            mail_smtp(self.smtpserv, self.fromaddr, self.mailto, msg)

        print(('Mailed the report to: {0}'.format(','.join(self.mailto))))