def _compose(self, snapshot_time, snapshot_timestamp, status,
                 inventory_pipelines):
        """Compose the email content.

        Args:
            snapshot_time (datetime): Snapshot time, in UTC.
            snapshot_timestamp (str): Snapshot timestamp,
                formatted as YYYYMMDDTHHMMSSZ.
            status (str): Overall status of current snapshot cycle.
            inventory_pipelines (list): Inventory pipelines.

        Returns:
            string: Email subject.
            unicode: Email template content rendered with the provided
                variables.
        """
        email_subject = 'Inventory Snapshot Complete: {0} {1}'.format(
            snapshot_timestamp, status)

        email_content = EmailUtil.render_from_template(
            'inventory_snapshot_summary.jinja', {
                'snapshot_time':
                snapshot_time.strftime('%Y %b %d, %H:%M:%S (UTC)'),
                'snapshot_timestamp': snapshot_timestamp,
                'status_summary': status,
                'pipelines': inventory_pipelines
            })

        return email_subject, email_content
    def _compose(  # pylint: disable=arguments-differ
            self, snapshot_time, snapshot_timestamp, status,
            inventory_pipelines):
        """Compose the email content.

        Args:
            snapshot_time: Datetime object of the cycle, in UTC.
            snapshot_timestamp: String of timestamp,
                formatted as YYYYMMDDTHHMMSSZ.
            status: String of the overall status of current snapshot cycle.
            inventory_pipelines: List of inventory pipelines.

        Returns:
            email_subject: String of the email subject.
            email_content: String of template content rendered with
                the provided variables.
        """
        email_subject = 'Inventory Snapshot Complete: {0} {1}'.format(
            snapshot_timestamp, status)

        email_content = EmailUtil.render_from_template(
            'inventory_snapshot_summary.jinja', {
                'snapshot_time':
                snapshot_time.strftime('%Y %b %d, %H:%M:%S (UTC)'),
                'snapshot_timestamp': snapshot_timestamp,
                'status_summary': status,
                'pipelines': inventory_pipelines
            })

        return email_subject, email_content
Ejemplo n.º 3
0
    def _send(  # pylint: disable=arguments-differ
            self, csv_name, output_filename, now_utc, violation_errors,
            total_violations, resource_summaries, email_sender,
            email_recipient, email_description):
        """Send a summary email of the scan.

        Args:
            csv_name (str): The full path of the local csv filename.
            output_filename (str): The output filename.
            now_utc (datetime): The UTC datetime right now.
            violation_errors (iterable): Iterable of violation errors.
            total_violations (int): The total violations.
            resource_summaries (dict): Maps resource to violations.
                {'organization':
                    {'pluralized_resource_type': 'Organizations',
                     'total': 1,
                     'violations': OrderedDict([('660570133860', 67)])},
                 'project':
                    {'pluralized_resource_type': 'Projects',
                     'total': 41,
                     'violations': OrderedDict([('foo1_project', 111),
                                                ('foo2_project', 222),
                                                ('foo3_project', 333)])}}
            email_sender (str): The sender of the email.
            email_recipient (str): The recipient of the email.
            email_description (str): Brief scan description to include in the
                subject of the email, e.g. 'Policy Scan'.
        """
        # Render the email template with values.
        scan_date = now_utc.strftime('%Y %b %d, %H:%M:%S (UTC)')
        email_content = EmailUtil.render_from_template(
            'scanner_summary.jinja', {
                'scan_date':  scan_date,
                'resource_summaries': resource_summaries,
                'violation_errors': violation_errors,
            })

        # Create an attachment out of the csv file and base64 encode the
        # content.
        attachment = EmailUtil.create_attachment(
            file_location=csv_name,
            content_type='text/csv',
            filename=output_filename,
            disposition='attachment',
            content_id='Scanner Violations'
        )
        scanner_subject = '{} Complete - {} violation(s) found'.format(
            email_description, total_violations)
        try:
            self.email_util.send(
                email_sender=email_sender,
                email_recipient=email_recipient,
                email_subject=scanner_subject,
                email_content=email_content,
                content_type='text/html',
                attachment=attachment)
        except util_errors.EmailSendError:
            LOGGER.warn('Unable to send Scanner Summary email')
def _send_email(cycle_time,
                cycle_timestamp,
                status,
                pipelines,
                sendgrid_api_key,
                email_sender,
                email_recipient,
                email_content=None):
    """Send an email.

    Args:
        cycle_time: Datetime object of the cycle, in UTC.
        cycle_timestamp: String of timestamp, formatted as YYYYMMDDTHHMMSSZ.
        status: String of the overall status of current snapshot cycle.
        pipelines: List of pipelines and their statuses.
        sendgrid_api_key: String of the sendgrid api key to auth email service.
        email_sender: String of the sender of the email.
        email_recipient: String of the recipient of the email.
        email_content: String of the email content (aka, body).

    Returns:
         None
    """

    email_subject = 'Inventory Snapshot Complete: {0} {1}'.format(
        cycle_timestamp, status)

    email_content = EmailUtil.render_from_template(
        'inventory_snapshot_summary.jinja', {
            'cycle_time': cycle_time.strftime('%Y %b %d, %H:%M:%S (UTC)'),
            'cycle_timestamp': cycle_timestamp,
            'status_summary': status,
            'pipelines': pipelines,
        })

    try:
        email_util = EmailUtil(sendgrid_api_key)
        email_util.send(email_sender,
                        email_recipient,
                        email_subject,
                        email_content,
                        content_type='text/html')
    except util_errors.EmailSendError:
        LOGGER.error('Unable to send email that inventory snapshot completed.')
Ejemplo n.º 5
0
def _send_email(csv_name, now_utc, all_violations, total_resources,
                violation_errors):
    """Send a summary email of the scan.

    Args:
        csv_name: The full path of the csv.
        now_utc: The UTC datetime right now.
        all_violations: The list of violations.
        total_resources: A dict of the resources and their count.
        violation_errors: Iterable of violation errors.
    """

    mail_util = EmailUtil(FLAGS.sendgrid_api_key)
    total_violations, resource_summaries = _build_scan_summary(
        all_violations, total_resources)

    # Render the email template with values.
    scan_date = now_utc.strftime('%Y %b %d, %H:%M:%S (UTC)')
    email_content = EmailUtil.render_from_template(
        'scanner_summary.jinja', {
            'scan_date': scan_date,
            'resource_summaries': resource_summaries,
            'violation_errors': violation_errors,
        })

    # Create an attachment out of the csv file and base64 encode the content.
    attachment = EmailUtil.create_attachment(
        file_location=csv_name,
        content_type='text/csv',
        filename=_get_output_filename(now_utc),
        disposition='attachment',
        content_id='Scanner Violations')
    scanner_subject = 'Policy Scan Complete - {} violation(s) found'.format(
        total_violations)
    mail_util.send(email_sender=FLAGS.email_sender,
                   email_recipient=FLAGS.email_recipient,
                   email_subject=scanner_subject,
                   email_content=email_content,
                   content_type='text/html',
                   attachment=attachment)
class EmailViolationsPipeline(bnp.BaseNotificationPipeline):
    """Email pipeline to perform notifications"""

    def __init__(self, resource, cycle_timestamp,
                 violations, notifier_config, pipeline_config):
        super(EmailViolationsPipeline, self).__init__(resource,
                                                      cycle_timestamp,
                                                      violations,
                                                      notifier_config,
                                                      pipeline_config)
        self.mail_util = EmailUtil(self.pipeline_config['sendgrid_api_key'])

    def _get_output_filename(self):
        """Create the output filename.

        Returns:
            The output filename for the violations json.
        """
        now_utc = datetime.utcnow()
        output_timestamp = now_utc.strftime(OUTPUT_TIMESTAMP_FMT)
        output_filename = VIOLATIONS_JSON_FMT.format(self.resource,
                                                     self.cycle_timestamp,
                                                     output_timestamp)
        return output_filename

    def _write_temp_attachment(self):
        """Write the attachment to a temp file.

        Returns:
            The output filename for the violations json just written.
        """
        # Make attachment
        output_file_name = self._get_output_filename()
        output_file_path = '{}/{}'.format(TEMP_DIR, output_file_name)
        with open(output_file_path, 'w+') as f:
            f.write(parser.json_stringify(self.violations))
        return output_file_name

    def _make_attachment(self):
        """Create the attachment object.

        Returns:
            The attachment object.
        """
        output_file_name = self._write_temp_attachment()
        attachment = self.mail_util.create_attachment(
            file_location='{}/{}'.format(TEMP_DIR, output_file_name),
            content_type='text/json',
            filename=output_file_name,
            disposition='attachment',
            content_id='Violations'
        )

        return attachment

    def _make_content(self):
        """Create the email content.

        Returns:
            A tuple containing the email subject and the content
        """
        timestamp = datetime.strptime(
            self.cycle_timestamp, '%Y%m%dT%H%M%SZ')
        pretty_timestamp = timestamp.strftime("%d %B %Y - %H:%M:%S")
        email_content = self.mail_util.render_from_template(
            'notification_summary.jinja', {
                'scan_date':  pretty_timestamp,
                'resource': self.resource,
                'violation_errors': self.violations,
            })

        email_subject = 'Forseti Violations {} - {}'.format(
            pretty_timestamp, self.resource)
        return email_subject, email_content

    def _compose(self, **kwargs):
        """Compose the email pipeline map

        Returns:
            Returns a map with subject, content, attachemnt
        """
        email_map = {}

        attachment = self._make_attachment()
        subject, content = self._make_content()
        email_map['subject'] = subject
        email_map['content'] = content
        email_map['attachment'] = attachment
        return email_map

    def _send(self, **kwargs):
        """Send a summary email of the scan.

        Args:
            subject: Email subject
            conetent: Email content
            attachment: Attachment object
        """
        notification_map = kwargs.get('notification')
        subject = notification_map['subject']
        content = notification_map['content']
        attachment = notification_map['attachment']

        self.mail_util.send(email_sender=self.pipeline_config['sender'],
                            email_recipient=self.pipeline_config['recipient'],
                            email_subject=subject,
                            email_content=content,
                            content_type='text/html',
                            attachment=attachment)

    def run(self):
        """Run the email pipeline"""
        email_notification = self._compose()
        self._send(notification=email_notification)
class EmailViolationsPipeline(bnp.BaseNotificationPipeline):
    """Email pipeline to perform notifications"""
    def __init__(self, resource, cycle_timestamp, violations, global_configs,
                 notifier_config, pipeline_config):
        """Initialization.

        Args:
            resource (str): Violation resource name.
            cycle_timestamp (str): Snapshot timestamp,
               formatted as YYYYMMDDTHHMMSSZ.
            violations (dict): Violations.
            global_configs (dict): Global configurations.
            notifier_config (dict): Notifier configurations.
            pipeline_config (dict): Pipeline configurations.
        """
        super(EmailViolationsPipeline,
              self).__init__(resource, cycle_timestamp, violations,
                             global_configs, notifier_config, pipeline_config)
        self.mail_util = EmailUtil(self.pipeline_config['sendgrid_api_key'])

    def _get_output_filename(self):
        """Create the output filename.

        Returns:
            str: The output filename for the violations json.
        """
        now_utc = datetime.utcnow()
        output_timestamp = now_utc.strftime(OUTPUT_TIMESTAMP_FMT)
        output_filename = VIOLATIONS_JSON_FMT.format(self.resource,
                                                     self.cycle_timestamp,
                                                     output_timestamp)
        return output_filename

    def _write_temp_attachment(self):
        """Write the attachment to a temp file.

        Returns:
            str: The output filename for the violations json just written.
        """
        # Make attachment
        output_file_name = self._get_output_filename()
        output_file_path = '{}/{}'.format(TEMP_DIR, output_file_name)
        with open(output_file_path, 'w+') as f:
            f.write(parser.json_stringify(self.violations))
        return output_file_name

    def _make_attachment(self):
        """Create the attachment object.

        Returns:
            attachment: SendGrid attachment object.
        """
        output_file_name = self._write_temp_attachment()
        attachment = self.mail_util.create_attachment(
            file_location='{}/{}'.format(TEMP_DIR, output_file_name),
            content_type='text/json',
            filename=output_file_name,
            disposition='attachment',
            content_id='Violations')

        return attachment

    def _make_content(self):
        """Create the email content.

        Returns:
            str: Email subject.
            unicode: Email template content rendered with
                the provided variables.
        """
        timestamp = datetime.strptime(self.cycle_timestamp, '%Y%m%dT%H%M%SZ')
        pretty_timestamp = timestamp.strftime("%d %B %Y - %H:%M:%S")
        email_content = self.mail_util.render_from_template(
            'notification_summary.jinja', {
                'scan_date': pretty_timestamp,
                'resource': self.resource,
                'violation_errors': self.violations,
            })

        email_subject = 'Forseti Violations {} - {}'.format(
            pretty_timestamp, self.resource)
        return email_subject, email_content

    def _compose(self, **kwargs):
        """Compose the email pipeline map

        Args:
            **kwargs: Arbitrary keyword arguments.

        Returns:
            dict: A map of the email with subject, content, attachemnt
        """
        del kwargs

        email_map = {}

        attachment = self._make_attachment()
        subject, content = self._make_content()
        email_map['subject'] = subject
        email_map['content'] = content
        email_map['attachment'] = attachment
        return email_map

    def _send(self, **kwargs):
        """Send a summary email of the scan.

        Args:
            **kwargs: Arbitrary keyword arguments.
                subject: Email subject
                conetent: Email content
                attachment: Attachment object
        """
        notification_map = kwargs.get('notification')
        subject = notification_map['subject']
        content = notification_map['content']
        attachment = notification_map['attachment']

        try:
            self.mail_util.send(
                email_sender=self.pipeline_config['sender'],
                email_recipient=self.pipeline_config['recipient'],
                email_subject=subject,
                email_content=content,
                content_type='text/html',
                attachment=attachment)
        except util_errors.EmailSendError:
            LOGGER.warn('Unable to send Violations email')

    def run(self):
        """Run the email pipeline"""
        email_notification = self._compose()
        self._send(notification=email_notification)