Exemple #1
0
def update_key(key):
    if not request.json:
        raise ApiError('nothing to change', 400)

    if not current_app.config['AUTH_REQUIRED']:
        key = ApiKey.find_by_id(key)
    elif Scope.admin in g.scopes or Scope.admin_keys in g.scopes:
        key = ApiKey.find_by_id(key)
    else:
        key = ApiKey.find_by_id(key, user=g.login)

    if not key:
        raise ApiError('not found', 404)

    update = request.json
    update['customer'] = assign_customer(wanted=update.get('customer'), permission=Scope.admin_keys)

    for want_scope in update.get('scopes', []):
        if not Permission.is_in_scope(want_scope, have_scopes=g.scopes):
            raise ApiError("Requested scope '{}' not in existing scopes: {}".format(
                want_scope, ','.join(g.scopes)), 403)

    admin_audit_trail.send(current_app._get_current_object(), event='apikey-updated', message='', user=g.login,
                           customers=g.customers, scopes=g.scopes, resource_id=key.id, type='apikey', request=request)

    if key.update(**request.json):
        return jsonify(status='ok')
    else:
        raise ApiError('failed to update API key', 500)
Exemple #2
0
def receive():
    try:
        incomingAlert = Alert.parse(request.json)
    except ValueError as e:
        raise ApiError(str(e), 400)

    incomingAlert.customer = assign_customer(wanted=incomingAlert.customer)
    add_remote_ip(request, incomingAlert)

    try:
        alert = process_alert(incomingAlert)
    except RejectException as e:
        raise ApiError(str(e), 403)
    except RateLimit as e:
        return jsonify(status='error', message=str(e), id=incomingAlert.id), 429
    except BlackoutPeriod as e:
        return jsonify(status='ok', message=str(e), id=incomingAlert.id), 202
    except Exception as e:
        raise ApiError(str(e), 500)

    write_audit_trail.send(current_app._get_current_object(), event='alert-received', message=alert.text, user=g.user,
                           customers=g.customers, scopes=g.scopes, resource_id=alert.id, type='alert', request=request)

    if alert:
        return jsonify(status='ok', id=alert.id, alert=alert.serialize), 201
    else:
        raise ApiError('insert or update of received alert failed', 500)
Exemple #3
0
def custom(webhook):
    try:
        incomingAlert = custom_webhooks.webhooks[webhook].incoming(
            query_string=request.args,
            payload=request.get_json() or request.get_data(as_text=True)
            or request.form)
    except KeyError as e:
        raise ApiError(
            "Webhook '%s' not found. Did you mean to use POST instead of GET?"
            % webhook, 404)
    except ValueError as e:
        raise ApiError(str(e), 400)

    incomingAlert.customer = assign_customer(wanted=incomingAlert.customer)
    add_remote_ip(request, incomingAlert)

    try:
        alert = process_alert(incomingAlert)
    except RejectException as e:
        raise ApiError(str(e), 403)
    except Exception as e:
        raise ApiError(str(e), 500)

    if alert:
        return jsonify(status='ok', id=alert.id, alert=alert.serialize), 201
    else:
        raise ApiError('insert or update via %s webhook failed' % webhook, 500)
Exemple #4
0
def prometheus():

    alerts = []
    if request.json and 'alerts' in request.json:
        external_url = request.json.get('externalURL', None)
        for alert in request.json['alerts']:
            try:
                incomingAlert = parse_prometheus(alert, external_url)
            except ValueError as e:
                raise ApiError(str(e), 400)

            incomingAlert.customer = assign_customer(
                wanted=incomingAlert.customer)
            add_remote_ip(request, incomingAlert)

            try:
                alert = process_alert(incomingAlert)
            except RejectException as e:
                raise ApiError(str(e), 403)
            except Exception as e:
                raise ApiError(str(e), 500)
            alerts.append(alert)
    else:
        raise ApiError('no alerts in Prometheus notification payload', 400)

    if len(alerts) == 1:
        return jsonify(status='ok', id=alerts[0].id,
                       alert=alerts[0].serialize), 201
    else:
        return jsonify(status='ok', ids=[alert.id for alert in alerts]), 201
Exemple #5
0
def create_key():
    try:
        key = ApiKey.parse(request.json)
    except ValueError as e:
        raise ApiError(str(e), 400)

    if Scope.admin in g.scopes or Scope.admin_keys in g.scopes:
        key.user = key.user or g.login
    else:
        key.user = g.login

    key.customer = assign_customer(wanted=key.customer, permission=Scope.admin_keys)

    if not key.user:
        raise ApiError("An API key must be associated with a 'user'. Retry with user credentials.", 400)

    for want_scope in key.scopes:
        if not Permission.is_in_scope(want_scope, have_scopes=g.scopes):
            raise ApiError("Requested scope '{}' not in existing scopes: {}".format(
                want_scope, ','.join(g.scopes)), 403)

    try:
        key = key.create()
    except Exception as e:
        raise ApiError(str(e), 500)

    write_audit_trail.send(current_app._get_current_object(), event='apikey-created', message='', user=g.login,
                           customers=g.customers, scopes=g.scopes, resource_id=key.id, type='apikey', request=request)

    if key:
        return jsonify(status='ok', key=key.key, data=key.serialize), 201
    else:
        raise ApiError('create API key failed', 500)
Exemple #6
0
def newrelic():

    try:
        incomingAlert = parse_newrelic(request.json)
    except ValueError as e:
        raise ApiError(str(e), 400)

    incomingAlert.customer = assign_customer(wanted=incomingAlert.customer)
    add_remote_ip(request, incomingAlert)

    try:
        alert = process_alert(incomingAlert)
    except RejectException as e:
        raise ApiError(str(e), 403)
    except Exception as e:
        raise ApiError(str(e), 500)

    text = 'newrelic alert received via webhook'
    write_audit_trail.send(current_app._get_current_object(),
                           event='webhook-received',
                           message=text,
                           user=g.user,
                           customers=g.customers,
                           scopes=g.scopes,
                           resource_id=alert.id,
                           type='alert',
                           request=request)

    if alert:
        return jsonify(status='ok', id=alert.id, alert=alert.serialize), 201
    else:
        raise ApiError('insert or update of New Relic alert failed', 500)
Exemple #7
0
def create_key():
    try:
        key = ApiKey.parse(request.json)
    except ValueError as e:
        raise ApiError(str(e), 400)

    if 'admin' in g.scopes or 'admin:keys' in g.scopes:
        key.user = key.user or g.user
    else:
        key.user = g.user

    key.customer = assign_customer(wanted=key.customer,
                                   permission='admin:keys')

    if not key.user:
        raise ApiError(
            "An API key must be associated with a 'user'. Retry with user credentials.",
            400)

    for want_scope in key.scopes:
        if not Permission.is_in_scope(want_scope, g.scopes):
            raise ApiError(
                "Requested scope '{}' not in existing scopes: {}".format(
                    want_scope, ','.join(g.scopes)), 403)

    try:
        key = key.create()
    except Exception as e:
        raise ApiError(str(e), 500)

    if key:
        return jsonify(status='ok', key=key.key, data=key.serialize), 201
    else:
        raise ApiError('create API key failed', 500)
Exemple #8
0
def custom(webhook):
    if webhook not in custom_webhooks.webhooks:
        raise ApiError("Custom webhook '%s' not found." % webhook, 404)

    try:
        rv = custom_webhooks.webhooks[webhook].incoming(
            query_string=request.args,
            payload=request.get_json() or request.get_data(as_text=True)
            or request.form)
    except Exception as e:
        raise ApiError(str(e), 400)

    if isinstance(rv, Alert):
        rv = [rv]

    if isinstance(rv, list):
        alerts = []
        for alert in rv:
            alert.customer = assign_customer(wanted=alert.customer)
            add_remote_ip(request, alert)

            try:
                alert = process_alert(alert)
            except RejectException as e:
                raise ApiError(str(e), 403)
            except Exception as e:
                raise ApiError(str(e), 500)

            text = 'alert received via {} webhook'.format(webhook)
            write_audit_trail.send(current_app._get_current_object(),
                                   event='webhook-received',
                                   message=text,
                                   user=g.login,
                                   customers=g.customers,
                                   scopes=g.scopes,
                                   resource_id=alert.id,
                                   type='alert',
                                   request=request)
            alerts.append(alert)

        if len(alerts) == 1:
            return jsonify(status='ok',
                           id=alerts[0].id,
                           alert=alerts[0].serialize), 201
        else:
            return jsonify(status='ok',
                           ids=[alert.id for alert in alerts]), 201

    else:
        text = 'request received via {} webhook'.format(webhook)
        write_audit_trail.send(current_app._get_current_object(),
                               event='webhook-received',
                               message=text,
                               user=g.login,
                               customers=g.customers,
                               scopes=g.scopes,
                               resource_id=None,
                               type='user-defined',
                               request=request)
        return rv
Exemple #9
0
def create_blackout():
    try:
        blackout = Blackout.parse(request.json)
    except Exception as e:
        raise ApiError(str(e), 400)

    if 'admin' in g.scopes or 'admin:blackouts' in g.scopes:
        blackout.user = blackout.user or g.user
    else:
        blackout.user = g.user

    blackout.customer = assign_customer(wanted=blackout.customer,
                                        permission='admin:blackouts')

    try:
        blackout = blackout.create()
    except Exception as e:
        raise ApiError(str(e), 500)

    if blackout:
        return jsonify(status="ok",
                       id=blackout.id,
                       blackout=blackout.serialize), 201, {
                           'Location': absolute_url('/blackout/' + blackout.id)
                       }
    else:
        raise ApiError("insert blackout failed", 500)
Exemple #10
0
def create_blackout():
    try:
        blackout = Blackout.parse(request.json)
    except Exception as e:
        raise ApiError(str(e), 400)

    if Scope.admin in g.scopes or Scope.admin_blackouts in g.scopes:
        blackout.user = blackout.user or g.login
    else:
        blackout.user = g.login

    blackout.customer = assign_customer(wanted=blackout.customer, permission=Scope.admin_blackouts)

    try:
        blackout = blackout.create()
    except Exception as e:
        raise ApiError(str(e), 500)

    write_audit_trail.send(current_app._get_current_object(), event='blackout-created', message='', user=g.login,
                           customers=g.customers, scopes=g.scopes, resource_id=blackout.id, type='blackout', request=request)

    if blackout:
        return jsonify(status='ok', id=blackout.id, blackout=blackout.serialize), 201, {'Location': absolute_url('/blackout/' + blackout.id)}
    else:
        raise ApiError('insert blackout failed', 500)
Exemple #11
0
def update_blackout(blackout_id):
    if not request.json:
        raise ApiError('nothing to change', 400)

    if not current_app.config['AUTH_REQUIRED']:
        blackout = Blackout.find_by_id(blackout_id)
    elif Scope.admin in g.scopes or Scope.admin_blackouts in g.scopes:
        blackout = Blackout.find_by_id(blackout_id)
    else:
        blackout = Blackout.find_by_id(blackout_id, g.customers)

    if not blackout:
        raise ApiError('not found', 404)

    update = request.json
    update['user'] = g.login
    update['customer'] = assign_customer(wanted=update.get('customer'), permission=Scope.admin_blackouts)

    write_audit_trail.send(current_app._get_current_object(), event='blackout-updated', message='', user=g.login,
                           customers=g.customers, scopes=g.scopes, resource_id=blackout.id, type='blackout',
                           request=request)

    updated = blackout.update(**update)
    if updated:
        return jsonify(status='ok', blackout=updated.serialize)
    else:
        raise ApiError('failed to update blackout', 500)
Exemple #12
0
def graylog():

    try:
        incomingAlert = parse_graylog(request.json)
    except ValueError as e:
        raise ApiError(str(e), 400)

    if request.args.get('event', None):
        incomingAlert.event = request.args.get('event')
    if request.args.get('event_type', None):
        incomingAlert.event_type = request.args.get('event_type')
    if request.args.get('environment', None):
        incomingAlert.environment = request.args.get('environment')
    if request.args.get('service', None):
        incomingAlert.service = request.args.get('service').split(",")
    if request.args.get('severity', None):
        incomingAlert.severity = request.args.get('severity')

    incomingAlert.customer = assign_customer(wanted=incomingAlert.customer)
    add_remote_ip(request, incomingAlert)

    try:
        alert = process_alert(incomingAlert)
    except RejectException as e:
        raise ApiError(str(e), 403)
    except Exception as e:
        raise ApiError(str(e), 500)

    if alert:
        return jsonify(status="ok", id=alert.id, alert=alert.serialize), 201
    else:
        raise ApiError("insert or update of graylog check failed", 500)
Exemple #13
0
def receive():
    try:
        incomingAlert = Alert.parse(request.json)
    except ValueError as e:
        raise ApiError(str(e), 400)

    incomingAlert.customer = assign_customer(wanted=incomingAlert.customer)
    add_remote_ip(request, incomingAlert)

    try:
        alert = process_alert(incomingAlert)
    except RejectException as e:
        raise ApiError(str(e), 403)
    except RateLimit as e:
        return jsonify(status="error", message=str(e),
                       id=incomingAlert.id), 429
    except BlackoutPeriod as e:
        return jsonify(status="ok", message=str(e), id=incomingAlert.id), 202
    except Exception as e:
        raise ApiError(str(e), 500)

    if alert:
        return jsonify(status="ok", id=alert.id, alert=alert.serialize), 201
    else:
        raise ApiError("insert or update of received alert failed", 500)
Exemple #14
0
def create_heartbeat():
    try:
        heartbeat = Heartbeat.parse(request.json)
    except ValueError as e:
        raise ApiError(str(e), 400)

    heartbeat.customer = assign_customer(wanted=heartbeat.customer,
                                         permission=Scope.admin_heartbeats)

    try:
        heartbeat = heartbeat.create()
    except Exception as e:
        raise ApiError(str(e), 500)

    write_audit_trail.send(current_app._get_current_object(),
                           event='heartbeat-created',
                           message='',
                           user=g.login,
                           customers=g.customers,
                           scopes=g.scopes,
                           resource_id=heartbeat.id,
                           type='heartbeat',
                           request=request)

    if heartbeat:
        return jsonify(status='ok',
                       id=heartbeat.id,
                       heartbeat=heartbeat.serialize), 201
    else:
        raise ApiError('insert or update of received heartbeat failed', 500)
Exemple #15
0
def custom(webhook):
    if webhook not in custom_webhooks.webhooks:
        raise ApiError("Custom webhook '%s' not found." % webhook, 404)

    try:
        rv = custom_webhooks.webhooks[webhook].incoming(
            query_string=request.args,
            payload=request.get_json() or request.get_data(as_text=True) or request.form
        )
    except Exception as e:
        raise ApiError(str(e), 400)

    if isinstance(rv, Alert):
        rv = [rv]

    if isinstance(rv, list):
        alerts = []
        for alert in rv:
            alert.customer = assign_customer(wanted=alert.customer)

            def audit_trail_alert(event: str):
                write_audit_trail.send(current_app._get_current_object(), event=event, message=alert.text, user=g.login,
                                       customers=g.customers, scopes=g.scopes, resource_id=alert.id, type='alert',
                                       request=request)

            try:
                alert = process_alert(alert)
            except RejectException as e:
                audit_trail_alert(event='alert-rejected')
                raise ApiError(str(e), 403)
            except RateLimit as e:
                audit_trail_alert(event='alert-rate-limited')
                return jsonify(status='error', message=str(e), id=alert.id), 429
            except HeartbeatReceived as e:
                audit_trail_alert(event='alert-heartbeat')
                return jsonify(status='ok', message=str(e), id=alert.id), 202
            except BlackoutPeriod as e:
                audit_trail_alert(event='alert-blackout')
                return jsonify(status='ok', message=str(e), id=alert.id), 202
            except Exception as e:
                raise ApiError(str(e), 500)

            text = 'alert received via {} webhook'.format(webhook)
            write_audit_trail.send(current_app._get_current_object(), event='webhook-received', message=text,
                                   user=g.login, customers=g.customers, scopes=g.scopes, resource_id=alert.id,
                                   type='alert', request=request)
            alerts.append(alert)

        if len(alerts) == 1:
            return jsonify(status='ok', id=alerts[0].id, alert=alerts[0].serialize), 201
        else:
            return jsonify(status='ok', ids=[alert.id for alert in alerts]), 201

    else:
        text = 'request received via {} webhook'.format(webhook)
        write_audit_trail.send(current_app._get_current_object(), event='webhook-received', message=text,
                               user=g.login, customers=g.customers, scopes=g.scopes, resource_id=None,
                               type='user-defined', request=request)
        return rv
Exemple #16
0
def receive():
    try:
        alert = Alert.parse(request.json)
    except ValueError as e:
        raise ApiError(str(e), 400)

    alert.customer = assign_customer(wanted=alert.customer)

    def audit_trail_alert(event: str):
        write_audit_trail.send(current_app._get_current_object(),
                               event=event,
                               message=alert.text,
                               user=g.login,
                               customers=g.customers,
                               scopes=g.scopes,
                               resource_id=alert.id,
                               type='alert',
                               request=request)

    try:
        alert = process_alert(alert)
    except RejectException as e:
        audit_trail_alert(event='alert-rejected')
        raise ApiError(str(e), 403)
    except RateLimit as e:
        audit_trail_alert(event='alert-rate-limited')
        return jsonify(status='error', message=str(e), id=alert.id), 429
    except HeartbeatReceived as heartbeat:
        audit_trail_alert(event='alert-heartbeat')
        return jsonify(status='ok', message=str(heartbeat),
                       id=heartbeat.id), 202
    except BlackoutPeriod as e:
        audit_trail_alert(event='alert-blackout')
        return jsonify(status='ok', message=str(e), id=alert.id), 202
    except ForwardingLoop as e:
        return jsonify(status='ok', message=str(e)), 202
    except AlertaException as e:
        raise ApiError(e.message, code=e.code, errors=e.errors)
    except Exception as e:
        raise ApiError(str(e), 500)

    write_audit_trail.send(current_app._get_current_object(),
                           event='alert-received',
                           message=alert.text,
                           user=g.login,
                           customers=g.customers,
                           scopes=g.scopes,
                           resource_id=alert.id,
                           type='alert',
                           request=request)

    if alert:
        return jsonify(status='ok', id=alert.id, alert=alert.serialize), 201
    else:
        raise ApiError('insert or update of received alert failed', 500)
Exemple #17
0
def grafana():

    alerts = []
    data = request.json
    if data and data['state'] == 'alerting':
        for match in data.get('evalMatches', []):
            try:
                incomingAlert = parse_grafana(data, match, request.args)
            except ValueError as e:
                return jsonify(status='error', message=str(e)), 400

            incomingAlert.customer = assign_customer(wanted=incomingAlert.customer)
            add_remote_ip(request, incomingAlert)

            try:
                alert = process_alert(incomingAlert)
            except RejectException as e:
                return jsonify(status='error', message=str(e)), 403
            except Exception as e:
                return jsonify(status='error', message=str(e)), 500
            alerts.append(alert)

    elif data and data['state'] == 'ok' and data.get('ruleId', None):
        try:
            query = qb.from_dict({'attributes.ruleId': str(data['ruleId'])})
            existingAlerts = Alert.find_all(query)
        except Exception as e:
            raise ApiError(str(e), 500)

        for updateAlert in existingAlerts:
            updateAlert.severity = 'normal'
            updateAlert.status = 'closed'

            try:
                alert = process_alert(updateAlert)
            except RejectException as e:
                raise ApiError(str(e), 403)
            except Exception as e:
                raise ApiError(str(e), 500)
            alerts.append(alert)
    else:
        raise ApiError('no alerts in Grafana notification payload', 400)

    for alert in alerts:
        text = 'grafana alert received via webhook'
        write_audit_trail.send(current_app._get_current_object(), event='webhook-received', message=text, user=g.user,
                               customers=g.customers, scopes=g.scopes, resource_id=alert.id, type='alert', request=request)

    if len(alerts) == 1:
        return jsonify(status='ok', id=alerts[0].id, alert=alerts[0].serialize), 201
    else:
        return jsonify(status='ok', ids=[alert.id for alert in alerts]), 201
Exemple #18
0
def custom(webhook):
    try:
        response = custom_webhooks.webhooks[webhook].incoming(
            query_string=request.args,
            payload=request.get_json() or request.get_data(as_text=True)
            or request.form)
    except KeyError as e:
        raise ApiError(
            "Webhook '%s' not found. Did you mean to use POST instead of GET?"
            % webhook, 404)
    except ValueError as e:
        raise ApiError(str(e), 400)

    if isinstance(response, Alert):
        response.customer = assign_customer(wanted=response.customer)
        add_remote_ip(request, response)

        try:
            alert = process_alert(response)
        except RejectException as e:
            raise ApiError(str(e), 403)
        except Exception as e:
            raise ApiError(str(e), 500)

        text = '{} alert received via custom webhook'.format(webhook)
        write_audit_trail.send(current_app._get_current_object(),
                               event='webhook-received',
                               message=text,
                               user=g.user,
                               customers=g.customers,
                               scopes=g.scopes,
                               resource_id=alert.id,
                               type='alert',
                               request=request)
        if alert:
            return jsonify(status='ok', id=alert.id,
                           alert=alert.serialize), 201
        else:
            raise ApiError('insert or update via %s webhook failed' % webhook,
                           500)
    else:
        text = '{} request received via custom webhook'.format(webhook)
        write_audit_trail.send(current_app._get_current_object(),
                               event='webhook-received',
                               message=text,
                               user=g.user,
                               customers=g.customers,
                               scopes=g.scopes,
                               resource_id=None,
                               type='user-defined',
                               request=request)
        return jsonify(**response)
Exemple #19
0
def grafana():

    alerts = []
    data = request.json
    if data and data['state'] == 'alerting':
        for match in data.get('evalMatches', []):
            try:
                incomingAlert = parse_grafana(data, match, request.args)
            except ValueError as e:
                return jsonify(status="error", message=str(e)), 400

            incomingAlert.customer = assign_customer(
                wanted=incomingAlert.customer)
            add_remote_ip(request, incomingAlert)

            try:
                alert = process_alert(incomingAlert)
            except RejectException as e:
                return jsonify(status="error", message=str(e)), 403
            except Exception as e:
                return jsonify(status="error", message=str(e)), 500
            alerts.append(alert)

    elif data and data['state'] == 'ok' and data.get('ruleId', None):
        try:
            query = qb.from_dict({'attributes.ruleId': str(data['ruleId'])})
            existingAlerts = Alert.find_all(query)
        except Exception as e:
            raise ApiError(str(e), 500)

        for updateAlert in existingAlerts:
            updateAlert.severity = 'normal'
            updateAlert.status = 'closed'

            try:
                alert = process_alert(updateAlert)
            except RejectException as e:
                raise ApiError(str(e), 403)
            except Exception as e:
                raise ApiError(str(e), 500)
            alerts.append(alert)
    else:
        raise ApiError("no alerts in Grafana notification payload", 400)

    if len(alerts) == 1:
        return jsonify(status="ok", id=alerts[0].id,
                       alert=alerts[0].serialize), 201
    else:
        return jsonify(status="ok", ids=[alert.id for alert in alerts]), 201
Exemple #20
0
def create_heartbeat():
    try:
        heartbeat = Heartbeat.parse(request.json)
    except ValueError as e:
        raise ApiError(str(e), 400)

    heartbeat.customer = assign_customer(wanted=heartbeat.customer, permission='admin:heartbeats')

    try:
        heartbeat = heartbeat.create()
    except Exception as e:
        raise ApiError(str(e), 500)

    if heartbeat:
        return jsonify(status="ok", id=heartbeat.id, heartbeat=heartbeat.serialize), 201
    else:
        raise ApiError("insert or update of received heartbeat failed", 500)
Exemple #21
0
def create_key():
    try:
        key = ApiKey.parse(request.json)
    except ValueError as e:
        raise ApiError(str(e), 400)

    if Scope.admin in g.scopes or Scope.admin_keys in g.scopes:
        key.user = key.user or g.login
    else:
        key.user = g.login

    key.customer = assign_customer(wanted=key.customer,
                                   permission=Scope.admin_keys)

    if not key.user:
        raise ApiError(
            "An API key must be associated with a 'user'. Retry with user credentials.",
            400)

    for want_scope in key.scopes:
        if not Permission.is_in_scope(want_scope, have_scopes=g.scopes):
            raise ApiError(
                "Requested scope '{}' not in existing scopes: {}".format(
                    want_scope, ','.join(g.scopes)), 403)

    try:
        key = key.create()
    except Exception as e:
        raise ApiError(str(e), 500)

    write_audit_trail.send(current_app._get_current_object(),
                           event='apikey-created',
                           message='',
                           user=g.login,
                           customers=g.customers,
                           scopes=g.scopes,
                           resource_id=key.id,
                           type='apikey',
                           request=request)

    if key:
        return jsonify(status='ok', key=key.key, data=key.serialize), 201
    else:
        raise ApiError('create API key failed', 500)
Exemple #22
0
def create_twilio_rule():
    try:
        twilio_rule = TwilioRule.parse(request.json)
    except Exception as e:
        raise ApiError(str(e), 400)

    if Scope.admin in g.scopes or Scope.admin_twilio_rules in g.scopes:
        twilio_rule.user = twilio_rule.user or g.login
    else:
        twilio_rule.user = g.login

    twilio_rule.customer = assign_customer(wanted=twilio_rule.customer,
                                           permission=Scope.admin_twilio_rules)

    try:
        twilio_rule = twilio_rule.create()
    except Exception as e:
        raise ApiError(str(e), 500)

    write_audit_trail.send(
        current_app._get_current_object(),
        event='twiliorule-created',
        message='',
        user=g.login,
        customers=g.customers,
        scopes=g.scopes,
        resource_id=twilio_rule.id,
        type='twilio_rule',
        request=request,
    )

    if twilio_rule:
        return (
            jsonify(status='ok',
                    id=twilio_rule.id,
                    twilioRule=twilio_rule.serialize),
            201,
            {
                'Location': absolute_url('/twiliorule/' + twilio_rule.id)
            },
        )
    else:
        raise ApiError('insert twilio rule failed', 500)
Exemple #23
0
def graylog():

    try:
        incomingAlert = parse_graylog(request.json)
    except ValueError as e:
        raise ApiError(str(e), 400)

    if request.args.get('event', None):
        incomingAlert.event = request.args.get('event')
    if request.args.get('event_type', None):
        incomingAlert.event_type = request.args.get('event_type')
    if request.args.get('environment', None):
        incomingAlert.environment = request.args.get('environment')
    if request.args.get('service', None):
        incomingAlert.service = request.args.get('service').split(',')
    if request.args.get('severity', None):
        incomingAlert.severity = request.args.get('severity')

    incomingAlert.customer = assign_customer(wanted=incomingAlert.customer)
    add_remote_ip(request, incomingAlert)

    try:
        alert = process_alert(incomingAlert)
    except RejectException as e:
        raise ApiError(str(e), 403)
    except Exception as e:
        raise ApiError(str(e), 500)

    text = 'graylog alert received via webhook'
    write_audit_trail.send(current_app._get_current_object(),
                           event='webhook-received',
                           message=text,
                           user=g.user,
                           customers=g.customers,
                           scopes=g.scopes,
                           resource_id=alert.id,
                           type='alert',
                           request=request)

    if alert:
        return jsonify(status='ok', id=alert.id, alert=alert.serialize), 201
    else:
        raise ApiError('insert or update of graylog check failed', 500)
Exemple #24
0
def prometheus():

    alerts = []
    if request.json and 'alerts' in request.json:
        external_url = request.json.get('externalURL', None)
        for alert in request.json['alerts']:
            try:
                incomingAlert = parse_prometheus(alert, external_url)
            except ValueError as e:
                raise ApiError(str(e), 400)

            incomingAlert.customer = assign_customer(
                wanted=incomingAlert.customer)
            add_remote_ip(request, incomingAlert)

            try:
                alert = process_alert(incomingAlert)
            except RejectException as e:
                raise ApiError(str(e), 403)
            except Exception as e:
                raise ApiError(str(e), 500)
            alerts.append(alert)
    else:
        raise ApiError('no alerts in Prometheus notification payload', 400)

    for alert in alerts:
        text = 'prometheus alert received via webhook'
        write_audit_trail.send(current_app._get_current_object(),
                               event='webhook-received',
                               message=text,
                               user=g.user,
                               customers=g.customers,
                               scopes=g.scopes,
                               resource_id=alert.id,
                               type='alert',
                               request=request)

    if len(alerts) == 1:
        return jsonify(status='ok', id=alerts[0].id,
                       alert=alerts[0].serialize), 201
    else:
        return jsonify(status='ok', ids=[alert.id for alert in alerts]), 201
Exemple #25
0
def serverdensity():

    try:
        incomingAlert = parse_serverdensity(request.json)
    except ValueError as e:
        raise ApiError(str(e), 400)

    incomingAlert.customer = assign_customer(wanted=incomingAlert.customer)
    add_remote_ip(request, incomingAlert)

    try:
        alert = process_alert(incomingAlert)
    except RejectException as e:
        raise ApiError(str(e), 403)
    except Exception as e:
        raise ApiError(str(e), 500)
    if alert:
        return jsonify(status="ok", id=alert.id, alert=alert.serialize), 201
    else:
        raise ApiError("insert or update of ServerDensity alert failed", 500)
Exemple #26
0
def create_heartbeat():
    try:
        heartbeat = Heartbeat.parse(request.json)
    except ValueError as e:
        raise ApiError(str(e), 400)

    heartbeat.customer = assign_customer(wanted=heartbeat.customer, permission=Scope.admin_heartbeats)

    try:
        heartbeat = heartbeat.create()
    except Exception as e:
        raise ApiError(str(e), 500)

    write_audit_trail.send(current_app._get_current_object(), event='heartbeat-created', message='', user=g.login,
                           customers=g.customers, scopes=g.scopes, resource_id=heartbeat.id, type='heartbeat', request=request)

    if heartbeat:
        return jsonify(status='ok', id=heartbeat.id, heartbeat=heartbeat.serialize), 201
    else:
        raise ApiError('insert or update of received heartbeat failed', 500)
Exemple #27
0
def pingdom():

    try:
        incomingAlert = parse_pingdom(request.json)
    except ValueError as e:
        raise ApiError(str(e), 400)

    incomingAlert.customer = assign_customer(wanted=incomingAlert.customer)
    add_remote_ip(request, incomingAlert)

    try:
        alert = process_alert(incomingAlert)
    except RejectException as e:
        raise ApiError(str(e), 403)
    except Exception as e:
        raise ApiError(str(e), 500)

    if alert:
        return jsonify(status='ok', id=alert.id, alert=alert.serialize), 201
    else:
        raise ApiError('insert or update of pingdom check failed', 500)
Exemple #28
0
def cloudwatch():

    try:
        incomingAlert = parse_notification(request.get_json(force=True))
    except ValueError as e:
        raise ApiError(str(e), 400)

    incomingAlert.customer = assign_customer(wanted=incomingAlert.customer)
    add_remote_ip(request, incomingAlert)

    try:
        alert = process_alert(incomingAlert)
    except RejectException as e:
        raise ApiError(str(e), 403)
    except Exception as e:
        raise ApiError(str(e), 500)

    if alert:
        return jsonify(status='ok', id=alert.id, alert=alert.serialize), 201
    else:
        raise ApiError('insert or update of cloudwatch alarm failed', 500)
Exemple #29
0
def update_key(key):
    if not request.json:
        raise ApiError('nothing to change', 400)

    if not current_app.config['AUTH_REQUIRED']:
        key = ApiKey.find_by_id(key)
    elif Scope.admin in g.scopes or Scope.admin_keys in g.scopes:
        key = ApiKey.find_by_id(key)
    else:
        key = ApiKey.find_by_id(key, user=g.login)

    if not key:
        raise ApiError('not found', 404)

    update = request.json
    update['customer'] = assign_customer(wanted=update.get('customer'),
                                         permission=Scope.admin_keys)

    for want_scope in update.get('scopes', []):
        if not Permission.is_in_scope(want_scope, have_scopes=g.scopes):
            raise ApiError(
                "Requested scope '{}' not in existing scopes: {}".format(
                    want_scope, ','.join(g.scopes)), 403)

    admin_audit_trail.send(current_app._get_current_object(),
                           event='apikey-updated',
                           message='',
                           user=g.login,
                           customers=g.customers,
                           scopes=g.scopes,
                           resource_id=key.id,
                           type='apikey',
                           request=request)

    updated = key.update(**request.json)
    if updated:
        return jsonify(status='ok', key=updated.serialize)
    else:
        raise ApiError('failed to update API key', 500)
Exemple #30
0
def custom(webhook):
    try:
        incomingAlert = custom_webhooks.webhooks[webhook].incoming(
            query_string=request.args,
            payload=request.get_json() or request.get_data(as_text=True))
    except ValueError as e:
        raise ApiError(str(e), 400)

    incomingAlert.customer = assign_customer(wanted=incomingAlert.customer)
    add_remote_ip(request, incomingAlert)

    try:
        alert = process_alert(incomingAlert)
    except RejectException as e:
        raise ApiError(str(e), 403)
    except Exception as e:
        raise ApiError(str(e), 500)

    if alert:
        return jsonify(status="ok", id=alert.id, alert=alert.serialize), 201
    else:
        raise ApiError("insert or update via %s webhook failed" % webhook, 500)
Exemple #31
0
def stackdriver():

    try:
        incomingAlert = parse_stackdriver(request.get_json(force=True))
    except ValueError as e:
        raise ApiError(str(e), 400)

    incomingAlert.customer = assign_customer(wanted=incomingAlert.customer)
    add_remote_ip(request, incomingAlert)

    try:
        alert = process_alert(incomingAlert)
    except RejectException as e:
        raise ApiError(str(e), 403)
    except Exception as e:
        raise ApiError(str(e), 500)

    if alert:
        return jsonify(status="ok", id=alert.id, alert=alert.serialize), 201
    else:
        raise ApiError("insert or update of StackDriver notification failed",
                       500)
Exemple #32
0
def update_twilio_rule(twilio_rule_id):
    if not request.json:
        raise ApiError('nothing to change', 400)

    if not current_app.config['AUTH_REQUIRED']:
        twilio_rule = TwilioRule.find_by_id(twilio_rule_id)
    elif Scope.admin in g.scopes or Scope.admin_twilio_rules in g.scopes:
        twilio_rule = TwilioRule.find_by_id(twilio_rule_id)
    else:
        twilio_rule = TwilioRule.find_by_id(twilio_rule_id, g.customers)

    if not twilio_rule:
        raise ApiError('not found', 404)

    update = request.json
    update['user'] = g.login
    update['customer'] = assign_customer(wanted=update.get('customer'),
                                         permission=Scope.admin_twilio_rules)

    write_audit_trail.send(
        current_app._get_current_object(),
        event='twilio_rule-updated',
        message='',
        user=g.login,
        customers=g.customers,
        scopes=g.scopes,
        resource_id=twilio_rule.id,
        type='twilio_rule',
        request=request,
    )

    updated = twilio_rule.update(**update)
    if updated:
        return jsonify(status='ok', twilioRule=updated.serialize)
    else:
        raise ApiError('failed to update twilio rule', 500)
Exemple #33
0
def custom(webhook, path):
    if webhook not in custom_webhooks.webhooks:
        raise ApiError(f"Custom webhook '{webhook}' not found.", 404)

    try:
        rv = custom_webhooks.webhooks[webhook].incoming(
            path=path or request.path,
            query_string=request.args,
            payload=request.get_json() or request.form
            or request.get_data(as_text=True))
    except TypeError:
        rv = custom_webhooks.webhooks[webhook].incoming(
            query_string=request.args,
            payload=request.get_json() or request.form
            or request.get_data(as_text=True))
    except AlertaException as e:
        raise ApiError(e.message, code=e.code, errors=e.errors)
    except Exception as e:
        raise ApiError(str(e), 400)

    if isinstance(rv, Alert):
        rv = [rv]

    if isinstance(rv, list):
        alerts = []
        for alert in rv:
            alert.customer = assign_customer(wanted=alert.customer)

            def audit_trail_alert(event: str):
                write_audit_trail.send(current_app._get_current_object(),
                                       event=event,
                                       message=alert.text,
                                       user=g.login,
                                       customers=g.customers,
                                       scopes=g.scopes,
                                       resource_id=alert.id,
                                       type='alert',
                                       request=request)

            try:
                alert = process_alert(alert)
            except RejectException as e:
                audit_trail_alert(event='alert-rejected')
                raise ApiError(str(e), 403)
            except RateLimit as e:
                audit_trail_alert(event='alert-rate-limited')
                return jsonify(status='error', message=str(e),
                               id=alert.id), 429
            except HeartbeatReceived as heartbeat:
                audit_trail_alert(event='alert-heartbeat')
                return jsonify(status='ok',
                               message=str(heartbeat),
                               id=heartbeat.id), 202
            except BlackoutPeriod as e:
                audit_trail_alert(event='alert-blackout')
                return jsonify(status='ok', message=str(e), id=alert.id), 202
            except ForwardingLoop as e:
                return jsonify(status='ok', message=str(e)), 202
            except AlertaException as e:
                raise ApiError(e.message, code=e.code, errors=e.errors)
            except Exception as e:
                raise ApiError(str(e), 500)

            text = f'alert received via {webhook} webhook'
            write_audit_trail.send(current_app._get_current_object(),
                                   event='webhook-received',
                                   message=text,
                                   user=g.login,
                                   customers=g.customers,
                                   scopes=g.scopes,
                                   resource_id=alert.id,
                                   type='alert',
                                   request=request)
            alerts.append(alert)

        if len(alerts) == 1:
            return jsonify(status='ok',
                           id=alerts[0].id,
                           alert=alerts[0].serialize), 201
        else:
            return jsonify(status='ok',
                           ids=[alert.id for alert in alerts]), 201

    else:
        text = f'request received via {webhook} webhook'
        write_audit_trail.send(current_app._get_current_object(),
                               event='webhook-received',
                               message=text,
                               user=g.login,
                               customers=g.customers,
                               scopes=g.scopes,
                               resource_id=None,
                               type='user-defined',
                               request=request)
        return rv
Exemple #34
0
    def test_assign_customer(self):

        with self.app.test_request_context('/'):
            self.app.preprocess_request()

            # nothing wanted, assign one
            g.customers = ['Customer1']
            g.scopes = []
            self.assertEqual(assign_customer(wanted=None), 'Customer1')

            # nothing wanted, but too many, throw error
            g.customers = ['Customer1', 'Customer2']
            g.scopes = []
            with self.assertRaises(ApiError) as e:
                assign_customer(wanted=None)
            exc = e.exception
            self.assertEqual(str(exc), 'must define customer as more than one possibility')

            # customer wanted, matches so allow
            g.customers = ['Customer1']
            g.scopes = []
            self.assertEqual(assign_customer(wanted='Customer1'), 'Customer1')

            # customer wanted, in list so allow
            g.customers = ['Customer1', 'Customer2']
            g.scopes = []
            self.assertEqual(assign_customer(wanted='Customer2'), 'Customer2')

            # customer wanted not in list, throw exception
            g.customers = ['Customer1', 'Customer2']
            g.scopes = []
            with self.assertRaises(ApiError) as e:
                assign_customer(wanted='Customer3')
            exc = e.exception
            self.assertEqual(str(exc), "not allowed to set customer to 'Customer3'")

            # no customers, admin scope so allow
            g.customers = []
            g.scopes = ['admin']
            self.assertEqual(assign_customer(wanted=None), None)
            self.assertEqual(assign_customer(wanted='Customer1'), 'Customer1')

            g.customers = ['Customer1', 'Customer2']
            g.scopes = ['admin']
            with self.assertRaises(ApiError) as e:
                assign_customer(wanted=None)
            exc = e.exception
            self.assertEqual(str(exc), 'must define customer as more than one possibility')
            self.assertEqual(assign_customer(wanted='Customer3'), 'Customer3')

            # wrong scope
            g.customers = ['Customer1']
            g.scopes = ['read:keys', 'write:keys']
            with self.assertRaises(ApiError) as e:
                assign_customer(wanted='Customer2', permission=Scope.admin_keys)
            exc = e.exception
            self.assertEqual(str(exc), "not allowed to set customer to 'Customer2'")

            # right scope
            g.customers = ['Customer1']
            g.scopes = ['admin:keys', 'read:keys', 'write:keys']
            self.assertEqual(assign_customer(wanted='Customer2', permission=Scope.admin_keys), 'Customer2')
Exemple #35
0
    def test_assign_customer(self):

        with self.app.test_request_context('/'):
            self.app.preprocess_request()

            # nothing wanted, assign one
            g.customers = ['Customer1']
            g.scopes = []
            self.assertEqual(assign_customer(wanted=None), 'Customer1')

            # nothing wanted, but too many, throw error
            g.customers = ['Customer1', 'Customer2']
            g.scopes = []
            with self.assertRaises(ApiError) as e:
                assign_customer(wanted=None)
            exc = e.exception
            self.assertEqual(
                str(exc), 'must define customer as more than one possibility')

            # customer wanted, matches so allow
            g.customers = ['Customer1']
            g.scopes = []
            self.assertEqual(assign_customer(wanted='Customer1'), 'Customer1')

            # customer wanted, in list so allow
            g.customers = ['Customer1', 'Customer2']
            g.scopes = []
            self.assertEqual(assign_customer(wanted='Customer2'), 'Customer2')

            # customer wanted not in list, throw exception
            g.customers = ['Customer1', 'Customer2']
            g.scopes = []
            with self.assertRaises(ApiError) as e:
                assign_customer(wanted='Customer3')
            exc = e.exception
            self.assertEqual(str(exc),
                             "not allowed to set customer to 'Customer3'")

            # no customers, admin scope so allow
            g.customers = []
            g.scopes = ['admin']
            self.assertEqual(assign_customer(wanted=None), None)
            self.assertEqual(assign_customer(wanted='Customer1'), 'Customer1')

            g.customers = ['Customer1', 'Customer2']
            g.scopes = ['admin']
            with self.assertRaises(ApiError) as e:
                assign_customer(wanted=None)
            exc = e.exception
            self.assertEqual(
                str(exc), 'must define customer as more than one possibility')
            self.assertEqual(assign_customer(wanted='Customer3'), 'Customer3')

            # wrong scope
            g.customers = ['Customer1']
            g.scopes = ['read:keys', 'write:keys']
            with self.assertRaises(ApiError) as e:
                assign_customer(wanted='Customer2',
                                permission=Scope.admin_keys)
            exc = e.exception
            self.assertEqual(str(exc),
                             "not allowed to set customer to 'Customer2'")

            # right scope
            g.customers = ['Customer1']
            g.scopes = ['admin:keys', 'read:keys', 'write:keys']
            self.assertEqual(
                assign_customer(wanted='Customer2',
                                permission=Scope.admin_keys), 'Customer2')