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, hosts_set
28 from maincommon import *
30 def get_all_policy_identities():
31 extract_host_name(hosts_set, request)
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 extract_host_name(hosts_set, request)
45 data = request.data.decode("utf-8")
46 data = data.replace("'", "\"")
47 data = json.loads(data)
49 if 'policyTypeId' in request.args:
50 policyTypeId = request.args.get('policyTypeId')
52 if policyTypeId not in list(policy_types.keys()):
53 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))
55 policy_schema = policy_types[policyTypeId]["policySchema"]
57 validate(instance=data, schema=policy_schema)
59 return(set_error(None, "The json does not validate against the schema.", 400, None, None, None, None, None))
61 for i in list(policy_instances.keys()):
62 if policyId != i and \
63 data == policy_instances[i] and \
64 policyTypeId == policy_type_per_instance[i]:
65 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))
67 if policyId in list(policy_instances.keys()):
68 if data["scope"] != policy_instances[policyId]["scope"]:
69 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))
71 if 'code' in request.args:
72 return(send_error_code(request.args))
74 if policyId in policy_instances.keys():
79 policy_instances[policyId] = data
80 policy_status[policyId] = set_status("UNDEFINED")
81 if 'policyTypeId' in request.args:
82 status_schema = policy_types[policyTypeId]["statusSchema"]
84 validate(instance=policy_status[policyId], schema=status_schema)
86 return(set_error(None, "The json does not validate against the status schema.", 400, None, None, None, None, None))
87 policy_type_per_instance[policyId] = policyTypeId
89 policy_type_per_instance[policyId] = "UNDEFINED"
91 response = make_response(policy_instances[policyId], code)
93 response.headers['Location'] = "http://localhost:8085/A1-P/v1/policies/" + policyId
96 def set_status(*args):
98 ps["enforceStatus"] = args[0]
100 ps["enforceReason"] = args[1]
102 return(set_error(None, "Too many arguments", 400, "There should be no more than two status arguments: enforceStatus and enforceReason", None, None, None, None))
105 def get_policy(policyId):
106 extract_host_name(hosts_set, request)
107 if len(request.args) == 0:
108 if policyId in policy_instances.keys():
109 res = policy_instances[policyId]
110 res["enforceStatus"] = policy_status[policyId]["enforceStatus"]
113 return(set_error(None, "The requested policy does not exist.", 404, None, None, None, "policyId", None))
115 return(send_error_code(request.args))
117 def delete_policy(policyId):
118 extract_host_name(hosts_set, request)
119 if len(request.args) == 0:
120 if policyId in policy_instances.keys():
121 policy_instances.pop(policyId)
122 policy_status.pop(policyId)
123 policy_type_per_instance.pop(policyId)
126 return(set_error(None, "The policy identity does not exist.", 404, "No policy instance has been deleted.", None, None, "policyId", None))
128 return(send_error_code(request.args))
130 def get_policy_status(policyId):
131 extract_host_name(hosts_set, request)
132 if len(request.args) == 0:
133 if policyId in policy_instances.keys():
134 return(policy_status[policyId], 200)
136 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))
138 return(send_error_code(request.args))
140 def get_all_policytypes_identities():
141 extract_host_name(hosts_set, request)
142 if len(request.args) == 0:
143 return(list(policy_types.keys()), 200)
145 return(send_error_code(request.args))
147 def get_policytypes(policyTypeId):
148 extract_host_name(hosts_set, request)
149 if len(request.args) == 0:
150 if policyTypeId in policy_types.keys():
151 return(policy_types[policyTypeId], 200)
153 return(set_error(None, "The requested policy type does not exist.", 404, None, None, None, "policyTypeId", None))
155 return(send_error_code(request.args))
157 def set_error(type_of, title, status, detail, instance, cause, param, reason):
160 if type_of is not None:
161 error["type"] = type_of
162 if title is not None:
163 error["title"] = title
164 if status is not None:
165 error["status"] = status
166 if detail is not None:
167 error["detail"] = detail
168 if instance is not None:
169 error["instance"] = instance
170 if cause is not None:
171 error["cause"] = cause
172 if param is not None:
173 params["param"] = param
174 if reason is not None:
175 params["reason"] = reason
177 error["invalidParams"] = params
178 return(error, error["status"])
180 def send_error_code(args):
181 if 'code' in args.keys():
184 return(set_error(None, "Method not allowed", 405, "Method not allowed for the URI", None, None, None, None))
186 return(set_error(None, "Too many requests", 429, "Too many requests have been sent in a given amount of time", None, None, None, None))
188 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))
190 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))
192 return(set_error(None, "Not found", 400, "Object in payload not properly formulated or not related to the method", None, None, None, None))
194 return(set_error(None, "Not found", 404, "No resource found at the URI", None, None, None, None))