Adding policy manager and a1 sdnc vth
[it/otf.git] / a1-sdnc-vth / app / routes / policy.py
diff --git a/a1-sdnc-vth/app/routes/policy.py b/a1-sdnc-vth/app/routes/policy.py
new file mode 100644 (file)
index 0000000..588397f
--- /dev/null
@@ -0,0 +1,225 @@
+\r
+import datetime\r
+import json\r
+import logging\r
+from logging import FileHandler\r
+import os\r
+\r
+import requests\r
+from flask import Flask, request, jsonify\r
+from . import config, ROUTES\r
+from app.helpers import policy_helper as Policy\r
+from app.helpers import response_helper as ResponseHelper\r
+from app.errors.bad_request_exception import BadRequestException\r
+\r
+\r
+\r
+def sendCallback(url, data):\r
+    try:\r
+        if type(data) is not dict:\r
+            data = {"msg": data}\r
+        app.logger.info("sending callback")\r
+        requests.post(url, json=data)\r
+    except Exception as e:\r
+        app.logger.info(e)\r
+    return\r
+\r
+def unix_time_millis(dt):\r
+    epoch = datetime.datetime.utcfromtimestamp(0)\r
+    return (dt - epoch).total_seconds() * 1000.0\r
+\r
+\r
+def route_check2(get_function=None, post_function=None, put_function=None, delete_function=None):\r
+    """\r
+     Info:\r
+        Since all routes do the same pre-check and have a similar skeleton, this function just refactored the pre-check for code reuse\r
+     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
+        get_function => type: function\r
+        put_function => type: function\r
+        delete_function => type: function\r
+    Returns:\r
+        returns the return of the function call, typically a jsonified response.\r
+        you can capture response in a var and execute logic or you can just return the function call/response \r
+    E.G.:\r
+        response = route_check(post_function = handle_post)\r
+        return route_check(get_function = handle_get, post_function = handle_post)\r
+    """\r
+    response_dict = ResponseHelper.vth_response_dic()\r
+    start_time = unix_time_millis(datetime.datetime.now())\r
+    status_code = 200\r
+    if request.is_json and ResponseHelper.valid_json(request.data):\r
+        if(request.method == 'GET'):\r
+            response_dict = get_function(request, response_dict, config)\r
+        elif(request.method == 'POST'):\r
+            response_dict = post_function(request, response_dict, config)\r
+        elif(request.method == 'PUT'):\r
+            response_dict = put_function(request, response_dict, config)\r
+        elif(request.method == 'DELETE'):\r
+            response_dict = delete_function(request, response_dict, config)\r
+    else:\r
+        raise BadRequestException(406, "Invalid Json")\r
+    end_time = unix_time_millis(datetime.datetime.now())\r
+    response_dict['vthResponse']['testDurationMS'] = end_time-start_time\r
+    return jsonify(response_dict), status_code\r
+\r
+\r
+@ROUTES.route("/policies", methods=['GET'])\r
+def policies():\r
+    pass\r
+\r
+@ROUTES.route("/policy", methods=['GET', 'PUT', 'DELETE'])\r
+def handle_policy():\r
+    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
+    \r
+\r
+@ROUTES.route("/policy_ids", methods=['GET'])\r
+def handle_policy_ids():\r
+    return ResponseHelper.route_check(config=config, get_function = Policy.get_policy_ids_using_get)\r
+\r
+@ROUTES.route("/policy_schemas", methods=['GET'])\r
+def handle_policy_schemas():\r
+    return ResponseHelper.route_check(config=config, get_function = Policy.get_policy_schemas_using_get)\r
+\r
+@ROUTES.route("/policy_schema", methods=['GET'])\r
+def handle_policy_schema():\r
+    return ResponseHelper.route_check(config=config, get_function = Policy.get_policy_schema_using_get)\r
+\r
+@ROUTES.route("/policy_status", methods=['GET'])\r
+def handle_policy_status():\r
+    return ResponseHelper.route_check(config=config, get_function = Policy.get_policy_status_using_get)\r
+\r
+@ROUTES.route("/policy_types", methods=['GET'])\r
+def handle_policy_types():\r
+    return ResponseHelper.route_check(config=config, get_function = Policy.get_policy_types_using_get)\r
+\r
+\r
+@ROUTES.route("/", methods=['POST'])\r
+def executeRicRequest():\r
+    response_data = {\r
+        'vthResponse': {\r
+            'testDuration': '',\r
+            'dateTimeUTC': str(datetime.datetime.now()),\r
+            'abstractMessage': '',\r
+            'resultData': {}\r
+        }\r
+    }\r
+\r
+    startTime = unix_time_millis(datetime.datetime.now())\r
+    ret_url = request.args.get('retURL')\r
+    try:\r
+        if not request.is_json:\r
+            raise ValueError("request must be json")\r
+\r
+        requestData = request.get_json()\r
+\r
+        app.logger.info("A1 requestData:" + str(requestData))\r
+\r
+        action = requestData['action'].lower()\r
+        _check_incoming_request(requestData)\r
+\r
+        os.environ['NO_PROXY'] = '127.0.0.1'  # TODO testing purpose w/ mock server. Needs to remove on final version\r
+        with open('config.json') as configFile:\r
+            config = json.load(configFile)\r
+\r
+        baseAddress = config['base_address']\r
+        if action == 'health_check' or action == 'list_policy':\r
+            res = requests.get(baseAddress + config['actions_path'][action])\r
+            response_data['vthResponse']['resultData']['statusCode'] = res.status_code\r
+            if action == 'health_check':\r
+                response_data['vthResponse']['resultData']['resultOutput'] = res.text\r
+            else:\r
+                response_data['vthResponse']['resultData']['resultOutput'] = res.json()\r
+        elif action == 'list_policy_instance':\r
+            res = requests.get(baseAddress + config['actions_path'][action]\r
+                               .format(policy_type_id=requestData['policy_type_id']))\r
+            response_data['vthResponse']['resultData']['statusCode'] = res.status_code\r
+            response_data['vthResponse']['resultData']['resultOutput'] = res.json()\r
+        elif action == 'get_policy_instance_status':\r
+            res = requests.get(baseAddress + config['actions_path'][action]\r
+                               .format(policy_type_id=requestData['policy_type_id'],\r
+                                       policy_instance_id=requestData['policy_instance_id']))\r
+            response_data['vthResponse']['resultData']['statusCode'] = res.status_code\r
+            response_data['vthResponse']['resultData']['resultOutput'] = res.json()\r
+        elif action == 'edit_policy':\r
+            res = _send_edit_request(requestData, config)\r
+            response_data['vthResponse']['resultData']['statusCode'] = res.status_code\r
+            if requestData['request_type'].lower() == 'get' and res.status_code == 200:\r
+                response_data['vthResponse']['resultData']['resultOutput'] = res.json()\r
+            else:\r
+                response_data['vthResponse']['resultData']['resultOutput'] = res.text\r
+        elif action == 'edit_policy_instance':\r
+            res = _send_edit_request(requestData, config)\r
+            response_data['vthResponse']['resultData']['statusCode'] = res.status_code\r
+            if requestData['request_type'].lower() == 'get' and res.status_code == 200:\r
+                response_data['vthResponse']['resultData']['resultOutput'] = res.json()\r
+            else:\r
+                response_data['vthResponse']['resultData']['resultOutput'] = res.text\r
+\r
+    except Exception as ex:\r
+        endTime = unix_time_millis(datetime.datetime.now())\r
+        totalTime = endTime - startTime\r
+        response_data['vthResponse']['testDuration'] = totalTime\r
+        response_data['vthResponse']['abstractMessage'] = str(ex)\r
+        return jsonify(response_data)\r
+\r
+    endTime = unix_time_millis(datetime.datetime.now())\r
+    totalTime = endTime - startTime\r
+\r
+    response_data['vthResponse']['testDuration'] = totalTime\r
+\r
+    if ret_url is not None:\r
+        sendCallback(ret_url, response_data)\r
+        return '', 200\r
+\r
+    return jsonify(response_data), 200\r
+\r
+\r
+def _send_edit_request(request_data, config):\r
+    baseAddress = config['base_address']\r
+    path = ''\r
+    action = request_data['action']\r
+    policy_type_id = request_data['policy_type_id']\r
+    request_type = request_data['request_type']\r
+    if action == "edit_policy":\r
+        path = baseAddress + config['actions_path'][action].format(policy_type_id=policy_type_id)\r
+    if action == 'edit_policy_instance':\r
+        instance_id = request_data['policy_instance_id']\r
+        path = baseAddress + config['actions_path'][action].format(policy_type_id=policy_type_id,\r
+                                                                   policy_instance_id=instance_id)\r
+    if request_type == 'get':\r
+        return requests.get(path)\r
+    if request_type == 'put':\r
+        payload = request_data['payload']\r
+        return requests.put(path, payload)\r
+    if request_type == 'delete':\r
+        return requests.delete(path)\r
+\r
+\r
+def _check_incoming_request(requestData):  # check if the request is valid\r
+    if 'action' not in requestData:\r
+        raise KeyError('no action was specify')\r
+\r
+    action = requestData['action'].lower()\r
+    edit_actions = ['edit_policy', 'edit_policy_instance']\r
+    requires_policy_id = ['edit_policy', 'list_policy_instance'\r
+        , 'edit_policy_instance', 'get_policy_instance_status']\r
+    requires_policy_instance_id = ['edit_policy_instance', 'get_policy_instance_status']\r
+    possible_actions = ['health_check', 'list_policy', 'edit_policy', 'list_policy_instance'\r
+        , 'edit_policy_instance', 'get_policy_instance_status']\r
+    possible_request_type = ['get', 'put', 'delete']\r
+\r
+    if action not in possible_actions:\r
+        raise KeyError("invalid action")\r
+    if action in edit_actions:  # request type is required\r
+        if 'request_type' not in requestData:\r
+            raise KeyError('this action: ' + action + ' requires a request type')\r
+        if requestData['request_type'] not in possible_request_type:\r
+            raise KeyError('this request_type: ' + requestData['request_type'] + ' is not valid')\r
+        if requestData['request_type'] == 'put' and 'payload' not in requestData:\r
+            raise KeyError('put request requires a payload')\r
+    if action in requires_policy_id:\r
+        if 'policy_type_id' not in requestData:\r
+            raise KeyError('this action: ' + action + ' requires a policy_type_id')\r
+    if action in requires_policy_instance_id:\r
+        if 'policy_instance_id' not in requestData:\r
+            raise KeyError('this action: ' + action + ' requires a policy_instance_id')\r