Ejemplo n.º 1
0
    def _create_dispatcher(self, output):
        """Create a dispatcher for the given output.

        Args:
            output (str): Alert output, e.g. "aws-sns:topic-name"

        Returns:
            OutputDispatcher: Based on the output type.
                Returns None if the output is invalid or not defined in the config.
        """
        try:
            service, descriptor = output.split(':')
        except ValueError:
            LOGGER.error(
                'Improperly formatted output [%s]. Outputs for rules must '
                'be declared with both a service and a descriptor for the '
                'integration (ie: \'slack:my_channel\')', output)
            return None

        if service not in self.config or descriptor not in self.config[service]:
            LOGGER.error('The output \'%s\' does not exist!', output)
            return None

        return StreamAlertOutput.create_dispatcher(service, self.region,
                                                   self.account_id,
                                                   self.prefix, self.config)
Ejemplo n.º 2
0
def test_create_dispatcher():
    """StreamAlertOutput - Create Dispatcher"""
    dispatcher = StreamAlertOutput.create_dispatcher(
        'aws-s3',
        REGION,
        FUNCTION_NAME,
        CONFIG
    )
    assert_is_instance(dispatcher, S3Output)
Ejemplo n.º 3
0
def run(alert, region, function_name, config):
    """Send an Alert to its described outputs.

    Args:
        alert (dict): dictionary representating an alert with the
            following structure:

            {
                'record': record,
                'rule_name': rule.rule_name,
                'rule_description': rule.rule_function.__doc__,
                'log_source': str(payload.log_source),
                'log_type': payload.type,
                'outputs': rule.outputs,
                'source_service': payload.service,
                'source_entity': payload.entity
            }

        region (str): The AWS region of the currently executing Lambda function
        function_name (str): The name of the lambda function
        config (dict): The loaded configuration for outputs from conf/outputs.json

    Yields:
        (bool, str): Dispatch status and name of the output to the handler
    """
    if not validate_alert(alert):
        LOGGER.error('Invalid alert format:\n%s', json.dumps(alert, indent=2))
        return

    LOGGER.debug('Sending alert to outputs:\n%s', json.dumps(alert, indent=2))

    # strip out unnecessary keys and sort
    alert = _sort_dict(alert)

    outputs = alert['outputs']
    # Get the output configuration for this rule and send the alert to each
    for output in set(outputs):
        try:
            service, descriptor = output.split(':')
        except ValueError:
            LOGGER.error(
                'Improperly formatted output [%s]. Outputs for rules must '
                'be declared with both a service and a descriptor for the '
                'integration (ie: \'slack:my_channel\')', output)
            continue

        if service not in config or descriptor not in config[service]:
            LOGGER.error('The output \'%s\' does not exist!', output)
            continue

        # Retrieve the proper class to handle dispatching the alerts of this services
        dispatcher = StreamAlertOutput.create_dispatcher(
            service, region, function_name, config)

        if not dispatcher:
            continue

        LOGGER.debug('Sending alert to %s:%s', service, descriptor)

        sent = False
        try:
            sent = dispatcher.dispatch(descriptor=descriptor,
                                       rule_name=alert['rule_name'],
                                       alert=alert)

        except Exception as err:  # pylint: disable=broad-except
            LOGGER.exception(
                'An error occurred while sending alert '
                'to %s:%s: %s. alert:\n%s', service, descriptor, err,
                json.dumps(alert, indent=2))

        # Yield back the result to the handler
        yield sent, output