1 # ============LICENSE_START===============================================
2 # Copyright (C) 2020 Nordix Foundation. All rights reserved.
3 # ========================================================================
4 # Licensed under the Apache License, Version 2.0 (the "License");
5 # you may not use this file except in compliance with the License.
6 # You may obtain a copy of the License at
8 # http://www.apache.org/licenses/LICENSE-2.0
10 # Unless required by applicable law or agreed to in writing, software
11 # distributed under the License is distributed on an "AS IS" BASIS,
12 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 # See the License for the specific language governing permissions and
14 # limitations under the License.
15 # ============LICENSE_END=================================================
23 from connexion import NoContent
24 from flask import Flask, escape, request, make_response
25 from jsonschema import validate
26 from random import random, choice
27 from var_declaration import policy_instances, policy_types, policy_status, policy_type_per_instance
29 def get_all_policy_identities():
30 if len(request.args) == 0:
31 return(list(policy_instances.keys()), 200)
32 elif 'policyTypeId' in request.args:
33 policyTypeId = request.args.get('policyTypeId')
34 if policyTypeId not in list(policy_types.keys()):
35 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))
37 return(list({key for key in policy_instances.keys() if policy_type_per_instance[key]==policyTypeId}), 200)
39 return(send_error_code(request.args))
41 def put_policy(policyId):
42 data = request.data.decode("utf-8")
43 data = data.replace("'", "\"")
44 data = json.loads(data)
46 if 'policyTypeId' in request.args:
47 policyTypeId = request.args.get('policyTypeId')
49 if policyTypeId not in list(policy_types.keys()):
50 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))
52 policy_schema = policy_types[policyTypeId]["policySchema"]
54 validate(instance=data, schema=policy_schema)
56 return(set_error(None, "The json does not validate against the schema.", 400, None, None, None, None, None))
58 for i in list(policy_instances.keys()):
59 if policyId != i and \
60 data == policy_instances[i] and \
61 policyTypeId == policy_type_per_instance[i]:
62 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))
64 if policyId in list(policy_instances.keys()):
65 if data["scope"] != policy_instances[policyId]["scope"]:
66 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))
68 if 'code' in request.args:
69 return(send_error_code(request.args))
71 if policyId in policy_instances.keys():
76 policy_instances[policyId] = data
77 policy_status[policyId] = set_status("UNDEFINED")
78 if 'policyTypeId' in request.args:
79 status_schema = policy_types[policyTypeId]["statusSchema"]
81 validate(instance=policy_status[policyId], schema=status_schema)
83 return(set_error(None, "The json does not validate against the status schema.", 400, None, None, None, None, None))
84 policy_type_per_instance[policyId] = policyTypeId
86 policy_type_per_instance[policyId] = "UNDEFINED"
88 response = make_response(policy_instances[policyId], code)
90 response.headers['Location'] = "http://localhost:8085/A1-P/v1/policies/" + policyId
93 def set_status(*args):
95 ps["enforceStatus"] = args[0]
97 ps["enforceReason"] = args[1]
99 return(set_error(None, "Too many arguments", 400, "There should be no more than two status arguments: enforceStatus and enforceReason", None, None, None, None))
102 def get_policy(policyId):
103 if len(request.args) == 0:
104 if policyId in policy_instances.keys():
105 res = policy_instances[policyId]
106 res["enforceStatus"] = policy_status[policyId]["enforceStatus"]
109 return(set_error(None, "The requested policy does not exist.", 404, None, None, None, "policyId", None))
111 return(send_error_code(request.args))
113 def delete_policy(policyId):
114 if len(request.args) == 0:
115 if policyId in policy_instances.keys():
116 policy_instances.pop(policyId)
117 policy_status.pop(policyId)
118 policy_type_per_instance.pop(policyId)
121 return(set_error(None, "The policy identity does not exist.", 404, "No policy instance has been deleted.", None, None, "policyId", None))
123 return(send_error_code(request.args))
125 def get_policy_status(policyId):
126 if len(request.args) == 0:
127 if policyId in policy_instances.keys():
128 return(policy_status[policyId], 200)
130 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))
132 return(send_error_code(request.args))
134 def get_all_policytypes_identities():
135 if len(request.args) == 0:
136 return(list(policy_types.keys()), 200)
138 return(send_error_code(request.args))
140 def get_policytypes(policyTypeId):
141 if len(request.args) == 0:
142 if policyTypeId in policy_types.keys():
143 return(policy_types[policyTypeId], 200)
145 return(set_error(None, "The requested policy type does not exist.", 404, None, None, None, "policyTypeId", None))
147 return(send_error_code(request.args))
149 def set_error(type_of, title, status, detail, instance, cause, param, reason):
152 if type_of is not None:
153 error["type"] = type_of
154 if title is not None:
155 error["title"] = title
156 if status is not None:
157 error["status"] = status
158 if detail is not None:
159 error["detail"] = detail
160 if instance is not None:
161 error["instance"] = instance
162 if cause is not None:
163 error["cause"] = cause
164 if param is not None:
165 params["param"] = param
166 if reason is not None:
167 params["reason"] = reason
169 error["invalidParams"] = params
170 return(error, error["status"])
172 def send_error_code(args):
173 if 'code' in args.keys():
176 return(set_error(None, "Method not allowed", 405, "Method not allowed for the URI", None, None, None, None))
178 return(set_error(None, "Too many requests", 429, "Too many requests have been sent in a given amount of time", None, None, None, None))
180 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))
182 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))
184 return(set_error(None, "Not found", 400, "Object in payload not properly formulated or not related to the method", None, None, None, None))
186 return(set_error(None, "Not found", 404, "No resource found at the URI", None, None, None, None))