588397f03e6eec252a0e8dd08a03c603f09858eb
[it/otf.git] / a1-policy-manager-vth / app / routes / policy.py
1 \r
2 import datetime\r
3 import json\r
4 import logging\r
5 from logging import FileHandler\r
6 import os\r
7 \r
8 import requests\r
9 from flask import Flask, request, jsonify\r
10 from . import config, ROUTES\r
11 from app.helpers import policy_helper as Policy\r
12 from app.helpers import response_helper as ResponseHelper\r
13 from app.errors.bad_request_exception import BadRequestException\r
14 \r
15 \r
16 \r
17 def sendCallback(url, data):\r
18     try:\r
19         if type(data) is not dict:\r
20             data = {"msg": data}\r
21         app.logger.info("sending callback")\r
22         requests.post(url, json=data)\r
23     except Exception as e:\r
24         app.logger.info(e)\r
25     return\r
26 \r
27 def unix_time_millis(dt):\r
28     epoch = datetime.datetime.utcfromtimestamp(0)\r
29     return (dt - epoch).total_seconds() * 1000.0\r
30 \r
31 \r
32 def route_check2(get_function=None, post_function=None, put_function=None, delete_function=None):\r
33     """\r
34      Info:\r
35         Since all routes do the same pre-check and have a similar skeleton, this function just refactored the pre-check for code reuse\r
36      Arguments (**kwargs): pass in the specified key(s) and  method(s) that handle the type of method, method must be allowed by route decorator\r
37         get_function => type: function\r
38         put_function => type: function\r
39         delete_function => type: function\r
40     Returns:\r
41         returns the return of the function call, typically a jsonified response.\r
42         you can capture response in a var and execute logic or you can just return the function call/response \r
43     E.G.:\r
44         response = route_check(post_function = handle_post)\r
45         return route_check(get_function = handle_get, post_function = handle_post)\r
46     """\r
47     response_dict = ResponseHelper.vth_response_dic()\r
48     start_time = unix_time_millis(datetime.datetime.now())\r
49     status_code = 200\r
50     if request.is_json and ResponseHelper.valid_json(request.data):\r
51         if(request.method == 'GET'):\r
52             response_dict = get_function(request, response_dict, config)\r
53         elif(request.method == 'POST'):\r
54             response_dict = post_function(request, response_dict, config)\r
55         elif(request.method == 'PUT'):\r
56             response_dict = put_function(request, response_dict, config)\r
57         elif(request.method == 'DELETE'):\r
58             response_dict = delete_function(request, response_dict, config)\r
59     else:\r
60         raise BadRequestException(406, "Invalid Json")\r
61     end_time = unix_time_millis(datetime.datetime.now())\r
62     response_dict['vthResponse']['testDurationMS'] = end_time-start_time\r
63     return jsonify(response_dict), status_code\r
64 \r
65 \r
66 @ROUTES.route("/policies", methods=['GET'])\r
67 def policies():\r
68     pass\r
69 \r
70 @ROUTES.route("/policy", methods=['GET', 'PUT', 'DELETE'])\r
71 def handle_policy():\r
72     return ResponseHelper.route_check(config=config, get_function = Policy.get_policy_using_get, put_function = Policy.put_policy_using_put, delete_function=Policy.delete_policy_using_delete)\r
73     \r
74 \r
75 @ROUTES.route("/policy_ids", methods=['GET'])\r
76 def handle_policy_ids():\r
77     return ResponseHelper.route_check(config=config, get_function = Policy.get_policy_ids_using_get)\r
78 \r
79 @ROUTES.route("/policy_schemas", methods=['GET'])\r
80 def handle_policy_schemas():\r
81     return ResponseHelper.route_check(config=config, get_function = Policy.get_policy_schemas_using_get)\r
82 \r
83 @ROUTES.route("/policy_schema", methods=['GET'])\r
84 def handle_policy_schema():\r
85     return ResponseHelper.route_check(config=config, get_function = Policy.get_policy_schema_using_get)\r
86 \r
87 @ROUTES.route("/policy_status", methods=['GET'])\r
88 def handle_policy_status():\r
89     return ResponseHelper.route_check(config=config, get_function = Policy.get_policy_status_using_get)\r
90 \r
91 @ROUTES.route("/policy_types", methods=['GET'])\r
92 def handle_policy_types():\r
93     return ResponseHelper.route_check(config=config, get_function = Policy.get_policy_types_using_get)\r
94 \r
95 \r
96 @ROUTES.route("/", methods=['POST'])\r
97 def executeRicRequest():\r
98     response_data = {\r
99         'vthResponse': {\r
100             'testDuration': '',\r
101             'dateTimeUTC': str(datetime.datetime.now()),\r
102             'abstractMessage': '',\r
103             'resultData': {}\r
104         }\r
105     }\r
106 \r
107     startTime = unix_time_millis(datetime.datetime.now())\r
108     ret_url = request.args.get('retURL')\r
109     try:\r
110         if not request.is_json:\r
111             raise ValueError("request must be json")\r
112 \r
113         requestData = request.get_json()\r
114 \r
115         app.logger.info("A1 requestData:" + str(requestData))\r
116 \r
117         action = requestData['action'].lower()\r
118         _check_incoming_request(requestData)\r
119 \r
120         os.environ['NO_PROXY'] = '127.0.0.1'  # TODO testing purpose w/ mock server. Needs to remove on final version\r
121         with open('config.json') as configFile:\r
122             config = json.load(configFile)\r
123 \r
124         baseAddress = config['base_address']\r
125         if action == 'health_check' or action == 'list_policy':\r
126             res = requests.get(baseAddress + config['actions_path'][action])\r
127             response_data['vthResponse']['resultData']['statusCode'] = res.status_code\r
128             if action == 'health_check':\r
129                 response_data['vthResponse']['resultData']['resultOutput'] = res.text\r
130             else:\r
131                 response_data['vthResponse']['resultData']['resultOutput'] = res.json()\r
132         elif action == 'list_policy_instance':\r
133             res = requests.get(baseAddress + config['actions_path'][action]\r
134                                .format(policy_type_id=requestData['policy_type_id']))\r
135             response_data['vthResponse']['resultData']['statusCode'] = res.status_code\r
136             response_data['vthResponse']['resultData']['resultOutput'] = res.json()\r
137         elif action == 'get_policy_instance_status':\r
138             res = requests.get(baseAddress + config['actions_path'][action]\r
139                                .format(policy_type_id=requestData['policy_type_id'],\r
140                                        policy_instance_id=requestData['policy_instance_id']))\r
141             response_data['vthResponse']['resultData']['statusCode'] = res.status_code\r
142             response_data['vthResponse']['resultData']['resultOutput'] = res.json()\r
143         elif action == 'edit_policy':\r
144             res = _send_edit_request(requestData, config)\r
145             response_data['vthResponse']['resultData']['statusCode'] = res.status_code\r
146             if requestData['request_type'].lower() == 'get' and res.status_code == 200:\r
147                 response_data['vthResponse']['resultData']['resultOutput'] = res.json()\r
148             else:\r
149                 response_data['vthResponse']['resultData']['resultOutput'] = res.text\r
150         elif action == 'edit_policy_instance':\r
151             res = _send_edit_request(requestData, config)\r
152             response_data['vthResponse']['resultData']['statusCode'] = res.status_code\r
153             if requestData['request_type'].lower() == 'get' and res.status_code == 200:\r
154                 response_data['vthResponse']['resultData']['resultOutput'] = res.json()\r
155             else:\r
156                 response_data['vthResponse']['resultData']['resultOutput'] = res.text\r
157 \r
158     except Exception as ex:\r
159         endTime = unix_time_millis(datetime.datetime.now())\r
160         totalTime = endTime - startTime\r
161         response_data['vthResponse']['testDuration'] = totalTime\r
162         response_data['vthResponse']['abstractMessage'] = str(ex)\r
163         return jsonify(response_data)\r
164 \r
165     endTime = unix_time_millis(datetime.datetime.now())\r
166     totalTime = endTime - startTime\r
167 \r
168     response_data['vthResponse']['testDuration'] = totalTime\r
169 \r
170     if ret_url is not None:\r
171         sendCallback(ret_url, response_data)\r
172         return '', 200\r
173 \r
174     return jsonify(response_data), 200\r
175 \r
176 \r
177 def _send_edit_request(request_data, config):\r
178     baseAddress = config['base_address']\r
179     path = ''\r
180     action = request_data['action']\r
181     policy_type_id = request_data['policy_type_id']\r
182     request_type = request_data['request_type']\r
183     if action == "edit_policy":\r
184         path = baseAddress + config['actions_path'][action].format(policy_type_id=policy_type_id)\r
185     if action == 'edit_policy_instance':\r
186         instance_id = request_data['policy_instance_id']\r
187         path = baseAddress + config['actions_path'][action].format(policy_type_id=policy_type_id,\r
188                                                                    policy_instance_id=instance_id)\r
189     if request_type == 'get':\r
190         return requests.get(path)\r
191     if request_type == 'put':\r
192         payload = request_data['payload']\r
193         return requests.put(path, payload)\r
194     if request_type == 'delete':\r
195         return requests.delete(path)\r
196 \r
197 \r
198 def _check_incoming_request(requestData):  # check if the request is valid\r
199     if 'action' not in requestData:\r
200         raise KeyError('no action was specify')\r
201 \r
202     action = requestData['action'].lower()\r
203     edit_actions = ['edit_policy', 'edit_policy_instance']\r
204     requires_policy_id = ['edit_policy', 'list_policy_instance'\r
205         , 'edit_policy_instance', 'get_policy_instance_status']\r
206     requires_policy_instance_id = ['edit_policy_instance', 'get_policy_instance_status']\r
207     possible_actions = ['health_check', 'list_policy', 'edit_policy', 'list_policy_instance'\r
208         , 'edit_policy_instance', 'get_policy_instance_status']\r
209     possible_request_type = ['get', 'put', 'delete']\r
210 \r
211     if action not in possible_actions:\r
212         raise KeyError("invalid action")\r
213     if action in edit_actions:  # request type is required\r
214         if 'request_type' not in requestData:\r
215             raise KeyError('this action: ' + action + ' requires a request type')\r
216         if requestData['request_type'] not in possible_request_type:\r
217             raise KeyError('this request_type: ' + requestData['request_type'] + ' is not valid')\r
218         if requestData['request_type'] == 'put' and 'payload' not in requestData:\r
219             raise KeyError('put request requires a payload')\r
220     if action in requires_policy_id:\r
221         if 'policy_type_id' not in requestData:\r
222             raise KeyError('this action: ' + action + ' requires a policy_type_id')\r
223     if action in requires_policy_instance_id:\r
224         if 'policy_instance_id' not in requestData:\r
225             raise KeyError('this action: ' + action + ' requires a policy_instance_id')\r