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)
def test_create_dispatcher(): """StreamAlertOutput - Create Dispatcher""" dispatcher = StreamAlertOutput.create_dispatcher( 'aws-s3', REGION, FUNCTION_NAME, CONFIG ) assert_is_instance(dispatcher, S3Output)
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