-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathapp.py
97 lines (77 loc) · 3.44 KB
/
app.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
# Copyright 2016 IBM Corporation
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
from flask import Flask, json, jsonify, make_response, request, url_for, abort
from applicationgraph import ApplicationGraph
from failuregenerator import A8FailureGenerator
from assertionchecker import A8AssertionChecker
import logging
import os, sys, requests
debug = os.getenv('A8_DEBUG')=='1'
a8_controller_url = os.getenv('A8_CONTROLLER_URL', 'http://controller:8080')
a8_controller_token = os.getenv('A8_CONTROLLER_TOKEN', '')
a8_log_server = os.getenv('A8_LOG_SERVER', 'http://es:9200')
app = Flask(__name__, static_url_path='')
app.debug = True
@app.route('/api/v1/recipes', methods=["POST"])
def post_recipe():
payload = request.get_json()
topology = payload.get("topology")
scenarios = payload.get("scenarios")
headers = payload.get("headers")
#pattern = payload.get("header_pattern")
if not topology:
abort(400, "Topology required")
if not scenarios:
abort(400, "Failure scenarios required")
if headers and type(headers)!=dict:
abort(400, "Headers must be a dictionary")
# if not pattern:
# abort(400, "Header_pattern required")
appgraph = ApplicationGraph(topology)
fg = A8FailureGenerator(appgraph, a8_controller_url='{0}/v1/rules'.format(a8_controller_url), a8_controller_token=a8_controller_token, headers=headers, debug=debug)
fg.setup_failures(scenarios)
return make_response(jsonify(recipe_id=fg.get_id()), 201, {'location': url_for('get_recipe_results', recipe_id=fg.get_id())})
@app.route('/api/v1/recipes/<recipe_id>', methods=["POST"])
def get_recipe_results(recipe_id):
payload = request.get_json()
#print json.dumps(payload, indent=2)
checklist = payload.get("checklist")
if not checklist:
abort(400, "Checklist required")
ac = A8AssertionChecker(es_host=a8_log_server, trace_log_value=recipe_id, index=["_all"])
results = ac.check_assertions(checklist, continue_on_error=True)
#print json.dumps(results, indent=2)
return make_response(jsonify(results=results), 200)
@app.route('/api/v1/recipes/<recipe_id>', methods=["DELETE"])
def delete_recipe(recipe_id):
# clear fault injection rules
url = '{0}/v1/rules?tag={1}'.format(a8_controller_url, recipe_id)
headers = {}
if a8_controller_token != "" :
headers['Authorization'] = "Bearer " + token
try:
r = requests.delete(url, headers=headers)
except Exception, e:
sys.stderr.write("Could not DELETE {0}".format(url))
sys.stderr.write("\n")
sys.stderr.write(str(e))
sys.stderr.write("\n")
abort(500, "Could not DELETE {0}".format(url))
if r.status_code != 200 and r.status_code != 204:
abort(r.status_code)
return ""
if __name__ == '__main__':
app.logger.addHandler(logging.StreamHandler(sys.stderr))
app.logger.setLevel(logging.DEBUG)
app.run(host='0.0.0.0', port=5000, debug = True)