blob: 92144b88ba130364a19f666e4d0d6f51d3353866 [file] [log] [blame]
Michal Kobusaa3accf2019-06-05 12:25:09 +02001# Copyright 2018: Mirantis Inc.
2# All Rights Reserved.
3#
4# Licensed under the Apache License, Version 2.0 (the "License"); you may
5# not use this file except in compliance with the License. You may obtain
6# a copy of the License at
7#
8# http://www.apache.org/licenses/LICENSE-2.0
9#
10# Unless required by applicable law or agreed to in writing, software
11# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13# License for the specific language governing permissions and limitations
14# under the License.
15
Mateusz Matuszkowiak2820c662018-11-21 12:07:25 +010016import json
17from logging.config import dictConfig
18
19from flask import Flask, Response, jsonify, request
Michal Kobus4104c102019-02-22 17:05:11 +010020
Michal Kobusaa3accf2019-06-05 12:25:09 +020021from prometheus_client import make_wsgi_app
22
23from requests.exceptions import ConnectionError as RequestsConnectionError
Michal Kobusfc1e7732019-05-16 18:30:48 +020024
Michal Kobus211ee922019-04-15 17:44:06 +020025from sf_notifier.helpers import alert_fields_and_action, create_file
26from sf_notifier.salesforce.client import SESSION_FILE, SalesforceClient
Michal Kobusaa3accf2019-06-05 12:25:09 +020027
28from simple_salesforce.exceptions import SalesforceError
29
30from simple_settings import settings
31
32from werkzeug.wsgi import DispatcherMiddleware
Michal Kobusafbf4d02018-11-28 14:18:05 +010033
Mateusz Matuszkowiak2820c662018-11-21 12:07:25 +010034
35dictConfig(settings.LOGGING)
36
Michal Kobusafbf4d02018-11-28 14:18:05 +010037app = Flask(__name__)
38app_dispatch = DispatcherMiddleware(app, {
39 '/metrics': make_wsgi_app()
40})
41
Michal Kobus211ee922019-04-15 17:44:06 +020042
43create_file(SESSION_FILE)
Mateusz Matuszkowiak2820c662018-11-21 12:07:25 +010044sf_cli = SalesforceClient(settings.SF_CONFIG)
45
46
Michal Kobus819cf022018-11-29 16:39:22 +010047@app.route('/info', methods=['GET'])
48def info():
Michal Kobus73d33522018-12-10 11:41:13 +010049 return jsonify({
50 'version': settings.VERSION,
51 'hashing': sf_cli.hash_func.__name__
52 })
Michal Kobus819cf022018-11-29 16:39:22 +010053
54
Mateusz Matuszkowiak2820c662018-11-21 12:07:25 +010055@app.route('/hook', methods=['POST'])
56def webhook_receiver():
57
58 try:
59 data = json.loads(request.data)
60 except ValueError:
Michal Kobus17726ae2018-11-27 12:59:55 +010061 msg = 'Invalid request data: {}.'.format(request.data)
62 app.logger.error(msg)
63 return Response(json.dumps({'error': msg}),
Mateusz Matuszkowiak2820c662018-11-21 12:07:25 +010064 status=400,
65 mimetype='application/json')
66
67 app.logger.info('Received requests: {}'.format(data))
68
Michal Kobusaa3accf2019-06-05 12:25:09 +020069 cases = []
Mateusz Matuszkowiak2820c662018-11-21 12:07:25 +010070 for alert in data['alerts']:
Michal Kobusaa3accf2019-06-05 12:25:09 +020071 try:
72 alert['labels']['env_id'] = sf_cli.environment
Michal Kobuse7589f72020-09-11 14:29:37 +020073 fields, action = alert_fields_and_action(
74 alert, add_links=settings.ADD_LINKS)
Michal Kobusaa3accf2019-06-05 12:25:09 +020075 except KeyError as key:
76 msg = 'Alert misses {} key.'.format(key)
77 app.logger.error(msg)
78 return Response(json.dumps({'error': msg}),
79 status=400,
80 mimetype='application/json')
Mateusz Matuszkowiak2820c662018-11-21 12:07:25 +010081
Michal Kobusaa3accf2019-06-05 12:25:09 +020082 if fields:
83 try:
84 cases.append(getattr(sf_cli, action)(*fields))
85 except (SalesforceError, RequestsConnectionError) as err:
86 msg = 'Salesforce request failure: {}.'.format(err)
87 sf_cli.metrics['sf_error_count'].inc()
88 app.logger.error(msg)
89 return Response(json.dumps({'error': msg}),
90 status=500,
91 mimetype='application/json')
Mateusz Matuszkowiak2820c662018-11-21 12:07:25 +010092
Michal Kobusaa3accf2019-06-05 12:25:09 +020093 if len(cases) == 1:
94 return jsonify(cases[0])
Mateusz Matuszkowiak2820c662018-11-21 12:07:25 +010095 return jsonify(cases)
96
97
98if __name__ == '__main__':
99 app.run()