2 # ============LICENSE_START===============================================
3 # Copyright (C) 2020 Nordix Foundation. All rights reserved.
4 # ========================================================================
5 # Licensed under the Apache License, Version 2.0 (the "License");
6 # you may not use this file except in compliance with the License.
7 # You may obtain a copy of the License at
9 # http://www.apache.org/licenses/LICENSE-2.0
11 # Unless required by applicable law or agreed to in writing, software
12 # distributed under the License is distributed on an "AS IS" BASIS,
13 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 # See the License for the specific language governing permissions and
15 # limitations under the License.
16 # ============LICENSE_END=================================================
25 from connexion import NoContent
26 from flask import Flask, escape, request, make_response
27 from jsonschema import validate
28 from random import random, choice
29 from var_declaration import policy_instances, policy_types, policy_status, policy_type_per_instance
31 def get_all_policy_identities():
32 if len(request.args) == 0:
33 return(list(policy_instances.keys()), 200)
34 elif 'policyTypeId' in request.args:
35 policyTypeId = request.args.get('policyTypeId')
36 if policyTypeId not in list(policy_types.keys()):
37 return(set_error(None, "The policy type provided does not exist.", 400, "The policy type " + data["policyTypeId"] + " is not defined as a policy type.", None, None, "policyTypeId", None))
39 return(list({key for key in policy_instances.keys() if policy_type_per_instance[key]==policyTypeId}), 200)
41 return(send_error_code(request.args))
43 def put_policy(policyId):
44 data = request.data.decode("utf-8")
45 data = data.replace("'", "\"")
46 data = json.loads(data)
48 if 'policyTypeId' in request.args:
49 policyTypeId = request.args.get('policyTypeId')
51 if policyTypeId not in list(policy_types.keys()):
52 return(set_error(None, "The policy type provided does not exist.", 400, "The policy type " + policyTypeId + " is not defined as a policy type.", None, None, "policyTypeId", None))
54 policy_schema = policy_types[policyTypeId]["policySchema"]
56 validate(instance=data, schema=policy_schema)
58 return(set_error(None, "The json does not validate against the schema.", 400, None, None, None, None, None))
60 for i in list(policy_instances.keys()):
61 if policyId != i and \
62 data == policy_instances[i] and \
63 policyTypeId == policy_type_per_instance[i]:
64 return(set_error(None, "The policy already exists with a different id.", 400, "No action has been taken. The id of the existing policy instance is: " + i + ".", None, None, None, None))
66 if policyId in list(policy_instances.keys()):
67 if data["scope"] != policy_instances[policyId]["scope"]:
68 return(set_error(None, "The policy already exists with a different scope.", 400, "The policy put involves a modification of the existing scope, which is not allowed.", None, None, "scope", None))
70 if 'code' in request.args:
71 return(send_error_code(request.args))
73 if policyId in policy_instances.keys():
78 policy_instances[policyId] = data
79 policy_status[policyId] = set_status("UNDEFINED")
80 if 'policyTypeId' in request.args:
81 status_schema = policy_types[policyTypeId]["statusSchema"]
83 validate(instance=policy_status[policyId], schema=status_schema)
85 return(set_error(None, "The json does not validate against the status schema.", 400, None, None, None, None, None))
86 policy_type_per_instance[policyId] = policyTypeId
88 policy_type_per_instance[policyId] = "UNDEFINED"
90 response = make_response(policy_instances[policyId], code)
92 response.headers['Location'] = "http://localhost:8085/A1-P/v1/policies/" + policyId
95 def set_status(*args):
97 ps["enforceStatus"] = args[0]
99 ps["enforceReason"] = args[1]
101 return(set_error(None, "Too many arguments", 400, "There should be no more than two status arguments: enforceStatus and enforceReason", None, None, None, None))
104 def get_policy(policyId):
105 if len(request.args) == 0:
106 if policyId in policy_instances.keys():
107 res = policy_instances[policyId]
108 res["enforceStatus"] = policy_status[policyId]["enforceStatus"]
111 return(set_error(None, "The requested policy does not exist.", 404, None, None, None, "policyId", None))
113 return(send_error_code(request.args))
115 def delete_policy(policyId):
116 if len(request.args) == 0:
117 if policyId in policy_instances.keys():
118 policy_instances.pop(policyId)
119 policy_status.pop(policyId)
120 policy_type_per_instance.pop(policyId)
123 return(set_error(None, "The policy identity does not exist.", 404, "No policy instance has been deleted.", None, None, "policyId", None))
125 return(send_error_code(request.args))
127 def get_policy_status(policyId):
128 if len(request.args) == 0:
129 if policyId in policy_instances.keys():
130 return(policy_status[policyId], 200)
132 return(set_error(None, "The policy identity does not exist.", 404, "There is no existing policy instance with the identity: " + policyId, None, None, "policyId", None))
134 return(send_error_code(request.args))
136 def get_all_policytypes_identities():
137 if len(request.args) == 0:
138 return(list(policy_types.keys()), 200)
140 return(send_error_code(request.args))
142 def get_policytypes(policyTypeId):
143 if len(request.args) == 0:
144 if policyTypeId in policy_types.keys():
145 return(policy_types[policyTypeId], 200)
147 return(set_error(None, "The requested policy type does not exist.", 404, None, None, None, "policyTypeId", None))
149 return(send_error_code(request.args))
151 def set_error(type_of, title, status, detail, instance, cause, param, reason):
154 if type_of is not None:
155 error["type"] = type_of
156 if title is not None:
157 error["title"] = title
158 if status is not None:
159 error["status"] = status
160 if detail is not None:
161 error["detail"] = detail
162 if instance is not None:
163 error["instance"] = instance
164 if cause is not None:
165 error["cause"] = cause
166 if param is not None:
167 params["param"] = param
168 if reason is not None:
169 params["reason"] = reason
171 error["invalidParams"] = params
172 return(error, error["status"])
174 def send_error_code(args):
175 if 'code' in args.keys():
178 return(set_error(None, "Method not allowed", 405, "Method not allowed for the URI", None, None, None, None))
180 return(set_error(None, "Too many requests", 429, "Too many requests have been sent in a given amount of time", None, None, None, None))
182 return(set_error(None, "Insufficient storage", 507, "The method could not be performed on the resource because the provider is unable to store the representation needed to successfully complete the request", None, None, None, None))
184 return(set_error(None, "Service unavailable", 503, "The provider is currently unable to handle the request due to a temporary overload", None, None, None, None))
186 return(set_error(None, "Not found", 400, "No resource found at the URI", None, None, None, None))
188 return(set_error(None, "Not found", 400, "No resource found at the URI", None, None, None, None))