Exemplo n.º 1
0
def alert():
    """
    Recieves alert from AWS SNS topic
    """
    data = request.get_json(force=True)

    try:
        validatesns.validate(data)
    except validatesns.ValidationError as err:
        logging.error(err)
        abort(403)

    client = nexmo.Client(key=app.config['NEXMO_KEY'], secret=app.config['NEXMO_SECRET'])
    if data['Type'] == 'Notification':
        client.send_message({
            'from': app.config['NEXMO_FROM'],
            'to': app.config['NEXMO_TO'],
            'text': '\n'.join([data['Subject'], data['Message']]),
        })

    if data['Type'] == 'SubscriptionConfirmation':
        urllib.request.urlopen(data['SubscribeURL']).read()
        client.send_message({
            'from': app.config['NEXMO_FROM'],
            'to': app.config['NEXMO_TO'],
            'text': 'Subscribed to ' + data['TopicArn'],
        })

    return success_response()
def sns_callback_handler():
    message_type = request.headers.get('x-amz-sns-message-type')
    try:
        verify_message_type(message_type)
    except InvalidMessageTypeException:
        raise InvalidRequest("SES-SNS callback failed: invalid message type",
                             400)

    try:
        message = json.loads(request.data)
    except json.decoder.JSONDecodeError:
        raise InvalidRequest("SES-SNS callback failed: invalid JSON given",
                             400)

    try:
        validatesns.validate(message, get_certificate=get_certificate)
    except validatesns.ValidationError:
        raise InvalidRequest("SES-SNS callback failed: validation failed", 400)

    if autoconfirm_subscription(message):
        return jsonify(result="success",
                       message="SES-SNS auto-confirm callback succeeded"), 200

    ok, retry = process_ses_results(message)

    if ok:
        return jsonify(result="success",
                       message="SES-SNS callback succeeded"), 200

    if retry:
        raise InvalidRequest("SES callback failed, should retry", 500)

    raise InvalidRequest("SES-SNS callback failed", 400)
Exemplo n.º 3
0
def errors():

    data = json.loads(request.data.decode('utf-8'))

    try:
        validatesns.validate(data)
    except validatesns.ValidationError:
        abort(400)

    message_type = data['Type']

    if message_type == 'SubscriptionConfirmation':
        requests.get(data['SubscribeURL'])

    elif message_type == 'Notification':
        try:
            message_data = json.loads(data['Message'])
        except JSONDecodeError:
            # This handles the case where the notification is not an actual
            # deployment. This happens when you setup a new trigger
            channel_id = CHANNEL_MAP['semabot']
            message = '**{}**\n'.format(data['Subject'])
            message += data['Message']
            flow.send_message(ORG_ID, channel_id, message)
            return 'foop'

        new_state_value = message_data['NewStateValue']
        if new_state_value == 'ALARM':

            metric_name = message_data['Trigger']['MetricName']
            print(metric_name)

    return 'fwip'
def lambda_handler(event, context):
    validatesns.validate(event, get_certificate=get_certificate)

    if event['Type'] == 'SubscriptionConfirmation':
        r = requests.get(event['SubscribeURL'])
        r.raise_for_status()
        r.close()
        print "Subscription confirmed"
        return

    # Todo: actually handle notification

    print json.dumps(event, indent=4)
Exemplo n.º 5
0
def sns_smtp_callback_handler():
    message_type = request.headers.get('x-amz-sns-message-type')
    try:
        verify_message_type(message_type)
    except InvalidMessageTypeException:
        raise InvalidRequest(
            "SES-SNS SMTP callback failed: invalid message type", 400)

    try:
        message = json.loads(request.data)
    except decoder.JSONDecodeError:
        raise InvalidRequest(
            "SES-SNS SMTP callback failed: invalid JSON given", 400)

    try:
        validatesns.validate(message, get_certificate=get_certificate)
    except validatesns.ValidationError:
        raise InvalidRequest("SES-SNS SMTP callback failed: validation failed",
                             400)

    if message.get('Type') == 'SubscriptionConfirmation':
        url = message.get('SubscribeURL')
        response = requests.get(url)
        try:
            response.raise_for_status()
        except Exception as e:
            current_app.logger.warning("Response: {}".format(response.text))
            raise e

        return jsonify(result="success",
                       message="SES-SNS auto-confirm callback succeeded"), 200

    process_ses_smtp_results.apply_async([{
        "Message": message.get("Message")
    }],
                                         queue=QueueNames.NOTIFY)

    return jsonify(result="success", message="SES-SNS callback succeeded"), 200
def handle_s3_sns(body_dict):
    # check SNS signature authenticity
    try:
        validatesns.validate(
            body_dict,
            get_certificate=_get_certificate,
            certificate_url_regex=VALIDATION_CERTIFICATE_URL_REGEX,
            max_age=VALIDATION_MAX_AGE,
        )
    except (validatesns.ValidationError,
            requests.exceptions.RequestException) as e:
        current_app.logger.warning(
            "SNS request body failed signature validation: {validation_error}",
            extra={
                "validation_error": e,
            })
        abort(400, "SNS request body failed signature validation")

    supported_topic_name = f"s3_file_upload_notification_{current_app.config['DM_ENVIRONMENT']}"

    if body_dict["Type"] == "SubscriptionConfirmation":
        # SNS starts out sending us a SubscriptionConfirmation message when the Topic is initially subscribed to an URL.
        # We need to handle this in a specific way to "confirm" that we do actually want these notification messages
        # sent here.
        return _handle_subscription_confirmation(body_dict,
                                                 supported_topic_name)
    elif body_dict["Type"] != "Notification":
        current_app.logger.warning("Unrecognized request type {request_type}",
                                   extra={
                                       "request_type": body_dict["Type"],
                                   })
        abort(400, f"Unrecognized request type {body_dict['Type']}")

    current_app.logger.info(
        "Processing message id {message_id} for subscription {subscription_arn}",
        extra={
            "message_id": body_dict["MessageId"],
            "subscription_arn":
            request.headers.get("x-amz-sns-subscription-arn"),
        },
    )

    try:
        body_message = json.loads(body_dict["Message"])
    except (ValueError, KeyError, TypeError):
        current_app.logger.warning(
            "Message contents didn't match expected format: {message_contents!r}",
            extra={
                "message_contents": body_dict.get("Message"),
            })
        abort(400, f"Message contents didn't match expected format")

    if "Records" in body_message:
        for record in body_message["Records"]:
            scan_and_tag_s3_object(
                s3_client=boto3.client("s3", region_name=record["awsRegion"]),
                s3_bucket_name=record["s3"]["bucket"]["name"],
                s3_object_key=unquote_plus(record["s3"]["object"]["key"]),
                s3_object_version=record["s3"]["object"]["versionId"],
                sns_message_id=body_dict["MessageId"],
            )
    elif body_message.get("Event") == "s3:TestEvent":
        # these happen sometimes - amazon keeping us on our toes
        current_app.logger.info("Received S3 test event")
    else:
        current_app.logger.warning(
            "Unrecognized message format {body_message}",
            extra={
                "body_message": body_message,
            })
        abort(400, f"Unrecognized message format {body_message}")

    return jsonify(status="ok"), 200
Exemplo n.º 7
0
def deployments():

    data = json.loads(request.data.decode('utf-8'))

    try:
        validatesns.validate(data)
    except validatesns.ValidationError:
        abort(400)

    message_type = data['Type']

    if message_type == 'SubscriptionConfirmation':
        requests.get(data['SubscribeURL'])

    elif message_type == 'Notification':

        try:
            message_data = json.loads(data['Message'])
        except JSONDecodeError:
            # This handles the case where the notification is not an actual
            # deployment. This happens when you setup a new trigger
            channel_id = CHANNEL_MAP['semabot']
            message = '**{}**\n'.format(data['Subject'])
            message += data['Message']
            flow.send_message(ORG_ID, channel_id, message)
            return 'foop'

        deployment_id = message_data['deploymentId']
        instance_id = message_data['instanceId']

        client = boto3.client('codedeploy')

        deployment_instances = client.get_deployment_instance(
            deploymentId=deployment_id, instanceId=instance_id)
        deployment_info = client.get_deployment(
            deploymentId=deployment_id)['deploymentInfo']

        logs = []

        if message_data['instanceStatus'].lower() == 'failed':

            for event in deployment_instances['instanceSummary'][
                    'lifecycleEvents']:
                if event['status'] == 'Failed':
                    logs.append({
                        'event': event['lifecycleEventName'],
                        'log': event['diagnostics']['logTail']
                    })

        client = boto3.client('ec2')
        instance_info = client.describe_instances(InstanceIds=[instance_id])
        tags = instance_info['Reservations'][0]['Instances'][0]['Tags']
        instance_name = [t['Value'] for t in tags if t['Key'] == 'Name'][0]

        message = '**{status}: AWS CodeDeploy {deployment_id} in {region} to {appname} ({group}) on {instance_name}**'

        message = message.format(status=message_data['instanceStatus'],
                                 group=deployment_info['deploymentGroupName'],
                                 deployment_id=deployment_id,
                                 region=message_data['region'],
                                 appname=deployment_info['applicationName'],
                                 instance_name=instance_name)
        if logs:
            message += '\n\n'
            for log in logs:
                message += '**[Lifecycle Event: {event}]**\n\n```\n{log}\n```'.format(
                    **log)

        try:
            channel_id = CHANNEL_MAP[deployment_info['applicationName']]
        except KeyError:
            channel_id = CHANNEL_MAP['semabot']

        flow.send_message(ORG_ID, channel_id, message)

    return 'foop'