aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--moonv4/bin/bootstrap.py1
-rw-r--r--moonv4/moon_authz/Dockerfile5
-rw-r--r--moonv4/moon_authz/moon_authz/api/authorization.py387
-rw-r--r--moonv4/moon_authz/moon_authz/http_server.py140
-rw-r--r--moonv4/moon_authz/moon_authz/messenger.py50
-rw-r--r--moonv4/moon_authz/moon_authz/server.py48
-rw-r--r--moonv4/moon_authz/requirements.txt9
-rw-r--r--moonv4/moon_interface/moon_interface/api/assignments.py264
-rw-r--r--moonv4/moon_interface/moon_interface/api/authz.py244
-rw-r--r--moonv4/moon_interface/moon_interface/api/data.py259
-rw-r--r--moonv4/moon_interface/moon_interface/api/meta_data.py204
-rw-r--r--moonv4/moon_interface/moon_interface/api/meta_rules.py138
-rw-r--r--moonv4/moon_interface/moon_interface/api/models.py101
-rw-r--r--moonv4/moon_interface/moon_interface/api/pdp.py106
-rw-r--r--moonv4/moon_interface/moon_interface/api/perimeter.py312
-rw-r--r--moonv4/moon_interface/moon_interface/api/policies.py106
-rw-r--r--moonv4/moon_interface/moon_interface/api/rules.py114
-rw-r--r--moonv4/moon_interface/moon_interface/api/wrapper.py120
-rw-r--r--moonv4/moon_interface/moon_interface/authz_requests.py159
-rw-r--r--moonv4/moon_interface/moon_interface/containers.py102
-rw-r--r--moonv4/moon_interface/moon_interface/http_server.py59
-rw-r--r--moonv4/moon_interface/moon_interface/server.py3
-rw-r--r--moonv4/moon_manager/moon_manager/api/containers.py179
-rw-r--r--moonv4/moon_manager/moon_manager/http_server.py3
-rw-r--r--moonv4/moon_manager/requirements.txt3
-rw-r--r--moonv4/moon_utilities/Changelog4
-rw-r--r--moonv4/moon_utilities/build.sh21
-rw-r--r--moonv4/moon_utilities/moon_utilities/__init__.py2
-rw-r--r--moonv4/moon_utilities/moon_utilities/cache.py520
-rw-r--r--moonv4/moon_utilities/moon_utilities/configuration.py4
-rw-r--r--moonv4/moon_utilities/moon_utilities/get_os_apis.py16
-rw-r--r--moonv4/moon_utilities/moon_utilities/security_functions.py232
-rw-r--r--moonv4/moon_wrapper/moon_wrapper/api/__init__.py0
-rw-r--r--moonv4/moon_wrapper/moon_wrapper/api/generic.py151
-rw-r--r--moonv4/moon_wrapper/moon_wrapper/api/wrapper.py101
-rw-r--r--moonv4/moon_wrapper/moon_wrapper/http_server.py197
-rw-r--r--moonv4/moon_wrapper/requirements.txt1
-rw-r--r--moonv4/tests/populate_default_values.py18
-rw-r--r--moonv4/tests/send_authz.py8
39 files changed, 2327 insertions, 2064 deletions
diff --git a/moonv4/bin/bootstrap.py b/moonv4/bin/bootstrap.py
index 98b8f9a3..6f2a5e03 100644
--- a/moonv4/bin/bootstrap.py
+++ b/moonv4/bin/bootstrap.py
@@ -213,6 +213,7 @@ def start_moon(data_config):
output = subprocess.run(cmd,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
+ time.sleep(3)
if output.returncode != 0:
log.info(" ".join(cmd))
log.info(output.returncode)
diff --git a/moonv4/moon_authz/Dockerfile b/moonv4/moon_authz/Dockerfile
index 6ecc8f2d..579ddd16 100644
--- a/moonv4/moon_authz/Dockerfile
+++ b/moonv4/moon_authz/Dockerfile
@@ -3,11 +3,12 @@ FROM ubuntu:latest
ENV UUID=null
RUN apt update && apt install python3.5 python3-pip -y
-RUN pip3 install moon_utilities moon_db pip --upgrade
+RUN pip3 install pip --upgrade
ADD . /root
WORKDIR /root/
-RUN pip3 install -r requirements.txt
+RUN pip3 install -r requirements.txt --upgrade
+RUN pip3 install dist/moon_utilities-1.3.0-py3-none-any.whl --upgrade
RUN pip3 install .
CMD ["python3", "-m", "moon_authz"] \ No newline at end of file
diff --git a/moonv4/moon_authz/moon_authz/api/authorization.py b/moonv4/moon_authz/moon_authz/api/authorization.py
index 94f1e13d..caa41082 100644
--- a/moonv4/moon_authz/moon_authz/api/authorization.py
+++ b/moonv4/moon_authz/moon_authz/api/authorization.py
@@ -3,17 +3,15 @@
# license which can be found in the file 'LICENSE' in this package distribution
# or at 'http://www.apache.org/licenses/LICENSE-2.0'.
-import hashlib
+import binascii
import itertools
-from oslo_log import log as logging
-from oslo_config import cfg
-import oslo_messaging
-from moon_utilities.security_functions import call, Context, notify
-from moon_utilities.misc import get_uuid_from_name
+import pickle
+from uuid import uuid4
+import logging
from moon_utilities import exceptions
-from moon_db.core import PDPManager
-from moon_db.core import ModelManager
-from moon_db.core import PolicyManager
+import flask
+from flask import request
+from flask_restful import Resource
# TODO (asteroide):
# - end the dev of the context
@@ -21,43 +19,85 @@ from moon_db.core import PolicyManager
# - call the next security function
# - call the master if an element is absent
-LOG = logging.getLogger(__name__)
-CONF = cfg.CONF
+LOG = logging.getLogger("moon.api." + __name__)
-class Authorization(object):
+class Authz(Resource):
"""
- Retrieve the current status of all components.
+ Endpoint for authz requests
"""
+ __urls__ = (
+ "/authz",
+ "/authz/",
+ "/authz/<string:uuid>/<string:subject_name>/<string:object_name>/<string:action_name>",
+ )
__version__ = "0.1.0"
pdp_id = None
meta_rule_id = None
keystone_project_id = None
payload = None
- def __init__(self, component_desc):
- self.component_id = component_desc
- LOG.info("ext={}".format(component_desc))
- self.filter_rule = oslo_messaging.NotificationFilter(
- event_type='^authz$',
- context={'container_id': "\w+_"+hashlib.sha224(component_desc.encode("utf-8")).hexdigest()}
- )
+ def __init__(self, **kwargs):
+ component_data = kwargs.get("component_data", {})
+ self.component_id = component_data['component_id']
+ self.pdp_id = component_data['pdp_id']
+ self.meta_rule_id = component_data['meta_rule_id']
+ self.keystone_project_id = component_data['keystone_project_id']
+ self.cache = kwargs.get("cache")
+ self.context = None
- for _id_value in component_desc.split("_"):
- _type, _id = _id_value.split(":")
- if _type == "pdp":
- self.pdp_id = _id
- elif _type == "metarule":
- self.meta_rule_id = _id
- elif _type == "project":
- self.keystone_project_id = _id
+ def post(self, uuid=None, subject_name=None, object_name=None, action_name=None):
+ """Get a response on an authorization request
- def __check_rules(self, context):
+ :param uuid: uuid of a tenant or an intra_extension
+ :param subject_name: name of the subject or the request
+ :param object_name: name of the object
+ :param action_name: name of the action
+ :return: {
+ "args": {},
+ "ctx": {
+ "action_name": "4567",
+ "id": "123456",
+ "method": "authz",
+ "object_name": "234567",
+ "subject_name": "123456",
+ "user_id": "admin"
+ },
+ "error": {
+ "code": 500,
+ "description": "",
+ "title": "Moon Error"
+ },
+ "intra_extension_id": "123456",
+ "result": false
+ }
+ :internal_api: authz
+ """
+ self.context = pickle.loads(request.data)
+ self.context.set_cache(self.cache)
+ self.context.increment_index()
+ self.run()
+ self.context.delete_cache()
+ response = flask.make_response(pickle.dumps(self.context))
+ response.headers['content-type'] = 'application/octet-stream'
+ return response
+
+ def run(self):
+ LOG.info("self.context.pdp_set={}".format(self.context.pdp_set))
+ result, message = self.__check_rules()
+ if result:
+ return self.__exec_instructions(result)
+ else:
+ self.context.current_state = "deny"
+ # self.__exec_next_state(result)
+ return
+
+ def __check_rules(self):
scopes_list = list()
- current_header_id = context['headers'][context['index']]
- Context.update_target(context)
- current_pdp = context['pdp_set'][current_header_id]
+ current_header_id = self.context.headers[self.context.index]
+ # Context.update_target(context)
+ current_pdp = self.context.pdp_set[current_header_id]
category_list = list()
category_list.extend(current_pdp["meta_rules"]["subject_categories"])
category_list.extend(current_pdp["meta_rules"]["object_categories"])
@@ -65,13 +105,12 @@ class Authorization(object):
for category in category_list:
scope = list(current_pdp['target'][category])
scopes_list.append(scope)
- policy_id = PolicyManager.get_policy_from_meta_rules("admin", current_header_id)
- rules = PolicyManager.get_rules(user_id="admin",
- policy_id=policy_id,
- meta_rule_id=current_header_id)
+ # policy_id = self.cache.get_policy_from_meta_rules("admin", current_header_id)
+
for item in itertools.product(*scopes_list):
req = list(item)
- for rule in rules['rules']:
+ for rule in self.cache.rules[self.context.current_policy_id]["rules"]:
+ LOG.info("rule={}".format(rule))
if req == rule['rule']:
return rule['instructions'], ""
LOG.warning("No rule match the request...")
@@ -84,13 +123,12 @@ class Authorization(object):
except ValueError:
LOG.error("Cannot understand value in instruction ({})".format(target))
return False
- pdp_set = self.payload["authz_context"]['pdp_set']
- for meta_rule_id in self.payload["authz_context"]['pdp_set']:
- policy_id = PolicyManager.get_policy_from_meta_rules("admin", meta_rule_id)
+ # pdp_set = self.payload["authz_context"]['pdp_set']
+ for meta_rule_id in self.context.pdp_set:
if meta_rule_id == "effect":
continue
- if pdp_set[meta_rule_id]["meta_rules"]["name"] == policy_name:
- for category_id, category_value in ModelManager.get_subject_categories("admin").items():
+ if self.context.pdp_set[meta_rule_id]["meta_rules"]["name"] == policy_name:
+ for category_id, category_value in self.cache.subject_categories.items():
if category_value["name"] == "role":
subject_category_id = category_id
break
@@ -131,95 +169,96 @@ class Authorization(object):
return self.payload["container_chaining"][index]
def __update_headers(self, name):
- context = self.payload["authz_context"]
- for meta_rule_id, meta_rule_value in context["pdp_set"].items():
+ # context = self.payload["authz_context"]
+ for meta_rule_id, meta_rule_value in self.context.pdp_set.items():
if meta_rule_id == "effect":
continue
if meta_rule_value["meta_rules"]["name"] == name:
- self.payload["authz_context"]['headers'].append(meta_rule_id)
+ self.context.headers.append(meta_rule_id)
return True
return False
- def __exec_next_state(self, rule_found):
- index = self.payload["authz_context"]['index']
- current_meta_rule = self.payload["authz_context"]['headers'][index]
- current_container = self.__get_container_from_meta_rule(current_meta_rule)
- current_container_genre = current_container["genre"]
- try:
- next_meta_rule = self.payload["authz_context"]['headers'][index+1]
- except IndexError:
- next_meta_rule = None
- if current_container_genre == "authz":
- if rule_found:
- return self.__return_to_router()
- pass
- if next_meta_rule:
- # next will be session if current is deny and session is unset
- if self.payload["authz_context"]['pdp_set'][next_meta_rule]['effect'] == "unset":
- return notify(
- request_id=self.payload["authz_context"]["request_id"],
- container_id=self.__get_container_from_meta_rule(next_meta_rule)['container_id'],
- payload=self.payload)
- # next will be delegation if current is deny and session is passed or deny and delegation is unset
- else:
- LOG.error("Delegation is not developed!")
+ # def __exec_next_state(self, rule_found):
+ # index = self.context.index
+ # current_meta_rule = self.context.headers[index]
+ # current_container = self.__get_container_from_meta_rule(current_meta_rule)
+ # current_container_genre = current_container["genre"]
+ # try:
+ # next_meta_rule = self.context.headers[index + 1]
+ # except IndexError:
+ # next_meta_rule = None
+ # if current_container_genre == "authz":
+ # if rule_found:
+ # return True
+ # pass
+ # if next_meta_rule:
+ # # next will be session if current is deny and session is unset
+ # if self.payload["authz_context"]['pdp_set'][next_meta_rule]['effect'] == "unset":
+ # return notify(
+ # request_id=self.payload["authz_context"]["request_id"],
+ # container_id=self.__get_container_from_meta_rule(next_meta_rule)['container_id'],
+ # payload=self.payload)
+ # # next will be delegation if current is deny and session is passed or deny and delegation is unset
+ # else:
+ # LOG.error("Delegation is not developed!")
+ #
+ # else:
+ # # else next will be None and the request is sent to router
+ # return self.__return_to_router()
+ # elif current_container_genre == "session":
+ # pass
+ # # next will be next container in headers if current is passed
+ # if self.payload["authz_context"]['pdp_set'][current_meta_rule]['effect'] == "passed":
+ # return notify(
+ # request_id=self.payload["authz_context"]["request_id"],
+ # container_id=self.__get_container_from_meta_rule(next_meta_rule)['container_id'],
+ # payload=self.payload)
+ # # next will be None if current is grant and the request is sent to router
+ # else:
+ # return self.__return_to_router()
+ # elif current_container_genre == "delegation":
+ # LOG.error("Delegation is not developed!")
+ # # next will be authz if current is deny
+ # # next will be None if current is grant and the request is sent to router
- else:
- # else next will be None and the request is sent to router
- return self.__return_to_router()
- elif current_container_genre == "session":
- pass
- # next will be next container in headers if current is passed
- if self.payload["authz_context"]['pdp_set'][current_meta_rule]['effect'] == "passed":
- return notify(
- request_id=self.payload["authz_context"]["request_id"],
- container_id=self.__get_container_from_meta_rule(next_meta_rule)['container_id'],
- payload=self.payload)
- # next will be None if current is grant and the request is sent to router
- else:
- return self.__return_to_router()
- elif current_container_genre == "delegation":
- LOG.error("Delegation is not developed!")
- # next will be authz if current is deny
- # next will be None if current is grant and the request is sent to router
-
- def __return_to_router(self):
- call(endpoint="security_router",
- ctx={"id": self.component_id,
- "call_master": False,
- "method": "return_authz",
- "request_id": self.payload["authz_context"]["request_id"]},
- method="route",
- args=self.payload["authz_context"])
+ # def __return_to_router(self):
+ # call(endpoint="security_router",
+ # ctx={"id": self.component_id,
+ # "call_master": False,
+ # "method": "return_authz",
+ # "request_id": self.payload["authz_context"]["request_id"]},
+ # method="route",
+ # args=self.payload["authz_context"])
def __exec_instructions(self, instructions):
- current_header_id = self.payload["authz_context"]['headers'][self.payload["authz_context"]['index']]
for instruction in instructions:
for key in instruction:
if key == "decision":
if instruction["decision"] == "grant":
- self.payload["authz_context"]['pdp_set'][current_header_id]["effect"] = "grant"
- self.__return_to_router()
+ self.context.current_state = "grant"
+ LOG.info("__exec_instructions True {}".format(
+ self.context.current_state))
+ return True
else:
- self.payload["authz_context"]['pdp_set'][current_header_id]["effect"] = instruction["decision"]
+ self.context.current_state = instruction["decision"].lower()
elif key == "chain":
result = self.__update_headers(**instruction["chain"])
if not result:
- self.payload["authz_context"]['pdp_set'][current_header_id]["effect"] = "deny"
+ self.context.current_state = "deny"
else:
- self.payload["authz_context"]['pdp_set'][current_header_id]["effect"] = "passed"
+ self.context.current_state = "passed"
elif key == "update":
result = self.__update_subject_category_in_policy(**instruction["update"])
if not result:
- self.payload["authz_context"]['pdp_set'][current_header_id]["effect"] = "deny"
+ self.context.current_state = "deny"
else:
- self.payload["authz_context"]['pdp_set'][current_header_id]["effect"] = "passed"
- # LOG.info("__exec_instructions {}".format(self.payload["authz_context"]))
+ self.context.current_state = "passed"
+ LOG.info("__exec_instructions False {}".format(self.context.current_state))
def __update_current_request(self):
index = self.payload["authz_context"]["index"]
current_header_id = self.payload["authz_context"]['headers'][index]
- previous_header_id = self.payload["authz_context"]['headers'][index-1]
+ previous_header_id = self.payload["authz_context"]['headers'][index - 1]
current_policy_id = PolicyManager.get_policy_from_meta_rules("admin", current_header_id)
previous_policy_id = PolicyManager.get_policy_from_meta_rules("admin", previous_header_id)
# FIXME (asteroide): must change those lines to be ubiquitous against any type of policy
@@ -233,11 +272,11 @@ class Authorization(object):
break
for assignment_id, assignment_value in PolicyManager.get_subject_assignments(
"admin", previous_policy_id, subject, subject_category_id).items():
- for data_id in assignment_value["assignments"]:
- data = PolicyManager.get_subject_data("admin", previous_policy_id, data_id, subject_category_id)
- for _data in data:
- for key, value in _data["data"].items():
- role_names.append(value["name"])
+ for data_id in assignment_value["assignments"]:
+ data = PolicyManager.get_subject_data("admin", previous_policy_id, data_id, subject_category_id)
+ for _data in data:
+ for key, value in _data["data"].items():
+ role_names.append(value["name"])
new_role_ids = []
for perimeter_id, perimeter_value in PolicyManager.get_objects("admin", current_policy_id).items():
if perimeter_value["name"] in role_names:
@@ -251,72 +290,65 @@ class Authorization(object):
self.payload["authz_context"]['current_request']['object'] = new_role_ids[0]
self.payload["authz_context"]['current_request']['action'] = perimeter_id
elif self.payload["authz_context"]['pdp_set'][current_header_id]['meta_rules']['name'] == "rbac":
- self.payload["authz_context"]['current_request']['subject'] = self.payload["authz_context"]['initial_request']['subject']
- self.payload["authz_context"]['current_request']['object'] = self.payload["authz_context"]['initial_request']['object']
- self.payload["authz_context"]['current_request']['action'] = self.payload["authz_context"]['initial_request']['action']
+ self.payload["authz_context"]['current_request']['subject'] = \
+ self.payload["authz_context"]['initial_request']['subject']
+ self.payload["authz_context"]['current_request']['object'] = \
+ self.payload["authz_context"]['initial_request']['object']
+ self.payload["authz_context"]['current_request']['action'] = \
+ self.payload["authz_context"]['initial_request']['action']
- def critical(self, ctxt, publisher_id, event_type, payload, metadata):
- """This is the authz endpoint
- but due to the oslo_messaging notification architecture, we must call it "critical"
-
- :param ctxt: context of the request
- :param publisher_id: ID of the publisher
- :param event_type: type of event ("authz" here)
- :param payload: content of the authz request
- :param metadata: metadata of the notification
- :return: result of the authorization for the current component
- """
- LOG.info("calling authz {} {}".format(ctxt, payload))
- self.keystone_project_id = payload["id"]
- self.payload = payload
+ def get_authz(self):
+ # self.keystone_project_id = payload["id"]
+ # LOG.info("get_authz {}".format(payload))
+ # self.payload = payload
try:
- if "authz_context" not in payload:
- try:
- self.payload["authz_context"] = Context(self.keystone_project_id,
- self.payload["subject_name"],
- self.payload["object_name"],
- self.payload["action_name"],
- self.payload["request_id"]).to_dict()
- except exceptions.SubjectUnknown:
- ctx = {
- "subject_name": self.payload["subject_name"],
- "object_name": self.payload["object_name"],
- "action_name": self.payload["action_name"],
- }
- call("moon_manager", method="update_from_master", ctx=ctx, args={})
- self.payload["authz_context"] = Context(self.keystone_project_id,
- self.payload["subject_name"],
- self.payload["object_name"],
- self.payload["action_name"],
- self.payload["request_id"]).to_dict()
- except exceptions.ObjectUnknown:
- ctx = {
- "subject_name": self.payload["subject_name"],
- "object_name": self.payload["object_name"],
- "action_name": self.payload["action_name"],
- }
- call("moon_manager", method="update_from_master", ctx=ctx, args={})
- self.payload["authz_context"] = Context(self.keystone_project_id,
- self.payload["subject_name"],
- self.payload["object_name"],
- self.payload["action_name"],
- self.payload["request_id"]).to_dict()
- except exceptions.ActionUnknown:
- ctx = {
- "subject_name": self.payload["subject_name"],
- "object_name": self.payload["object_name"],
- "action_name": self.payload["action_name"],
- }
- call("moon_manager", method="update_from_master", ctx=ctx, args={})
- self.payload["authz_context"] = Context(self.keystone_project_id,
- self.payload["subject_name"],
- self.payload["object_name"],
- self.payload["action_name"],
- self.payload["request_id"]).to_dict()
- self.__update_container_chaining()
- else:
- self.payload["authz_context"]["index"] += 1
- self.__update_current_request()
+ # if "authz_context" not in payload:
+ # try:
+ # self.payload["authz_context"] = Context(self.keystone_project_id,
+ # self.payload["subject_name"],
+ # self.payload["object_name"],
+ # self.payload["action_name"],
+ # self.payload["request_id"]).to_dict()
+ # except exceptions.SubjectUnknown:
+ # ctx = {
+ # "subject_name": self.payload["subject_name"],
+ # "object_name": self.payload["object_name"],
+ # "action_name": self.payload["action_name"],
+ # }
+ # call("moon_manager", method="update_from_master", ctx=ctx, args={})
+ # self.payload["authz_context"] = Context(self.keystone_project_id,
+ # self.payload["subject_name"],
+ # self.payload["object_name"],
+ # self.payload["action_name"],
+ # self.payload["request_id"]).to_dict()
+ # except exceptions.ObjectUnknown:
+ # ctx = {
+ # "subject_name": self.payload["subject_name"],
+ # "object_name": self.payload["object_name"],
+ # "action_name": self.payload["action_name"],
+ # }
+ # call("moon_manager", method="update_from_master", ctx=ctx, args={})
+ # self.payload["authz_context"] = Context(self.keystone_project_id,
+ # self.payload["subject_name"],
+ # self.payload["object_name"],
+ # self.payload["action_name"],
+ # self.payload["request_id"]).to_dict()
+ # except exceptions.ActionUnknown:
+ # ctx = {
+ # "subject_name": self.payload["subject_name"],
+ # "object_name": self.payload["object_name"],
+ # "action_name": self.payload["action_name"],
+ # }
+ # call("moon_manager", method="update_from_master", ctx=ctx, args={})
+ # self.payload["authz_context"] = Context(self.keystone_project_id,
+ # self.payload["subject_name"],
+ # self.payload["object_name"],
+ # self.payload["action_name"],
+ # self.payload["request_id"]).to_dict()
+ # self.__update_container_chaining()
+ # else:
+ # self.payload["authz_context"]["index"] += 1
+ # self.__update_current_request()
result, message = self.__check_rules(self.payload["authz_context"])
current_header_id = self.payload["authz_context"]['headers'][self.payload["authz_context"]['index']]
if result:
@@ -327,7 +359,7 @@ class Authorization(object):
return {"authz": result,
"error": message,
"pdp_id": self.pdp_id,
- "ctx": ctxt, "args": self.payload}
+ "args": self.payload}
except Exception as e:
try:
LOG.error(self.payload["authz_context"])
@@ -337,5 +369,8 @@ class Authorization(object):
return {"authz": False,
"error": str(e),
"pdp_id": self.pdp_id,
- "ctx": ctxt, "args": self.payload}
+ "args": self.payload}
+ def head(self, uuid=None, subject_name=None, object_name=None, action_name=None):
+ LOG.info("HEAD request")
+ return "", 200 \ No newline at end of file
diff --git a/moonv4/moon_authz/moon_authz/http_server.py b/moonv4/moon_authz/moon_authz/http_server.py
new file mode 100644
index 00000000..b6818a9f
--- /dev/null
+++ b/moonv4/moon_authz/moon_authz/http_server.py
@@ -0,0 +1,140 @@
+# Copyright 2015 Open Platform for NFV Project, Inc. and its contributors
+# This software is distributed under the terms and conditions of the 'Apache-2.0'
+# license which can be found in the file 'LICENSE' in this package distribution
+# or at 'http://www.apache.org/licenses/LICENSE-2.0'.
+
+from flask import Flask, request
+# from flask_cors import CORS, cross_origin
+from flask_restful import Resource, Api, reqparse
+import logging
+from moon_utilities import exceptions
+from moon_authz import __version__
+from moon_authz.api.authorization import Authz
+from moon_utilities.cache import Cache
+
+logger = logging.getLogger("moon." + __name__)
+
+CACHE = Cache()
+CACHE.update()
+
+
+class Server:
+ """Base class for HTTP server"""
+
+ def __init__(self, host="localhost", port=80, api=None, **kwargs):
+ """Run a server
+
+ :param host: hostname of the server
+ :param port: port for the running server
+ :param kwargs: optional parameters
+ :return: a running server
+ """
+ self._host = host
+ self._port = port
+ self._api = api
+ self._extra = kwargs
+
+ @property
+ def host(self):
+ return self._host
+
+ @host.setter
+ def host(self, name):
+ self._host = name
+
+ @host.deleter
+ def host(self):
+ self._host = ""
+
+ @property
+ def port(self):
+ return self._port
+
+ @port.setter
+ def port(self, number):
+ self._port = number
+
+ @port.deleter
+ def port(self):
+ self._port = 80
+
+ def run(self):
+ raise NotImplementedError()
+
+__API__ = (
+ Authz,
+ )
+
+
+class Root(Resource):
+ """
+ The root of the web service
+ """
+ __urls__ = ("/", )
+ __methods = ("get", "post", "put", "delete", "options")
+
+ def get(self):
+ tree = {"/": {"methods": ("get",), "description": "List all methods for that service."}}
+ for item in __API__:
+ tree[item.__name__] = {"urls": item.__urls__}
+ _methods = []
+ for _method in self.__methods:
+ if _method in dir(item):
+ _methods.append(_method)
+ tree[item.__name__]["methods"] = _methods
+ tree[item.__name__]["description"] = item.__doc__.strip()
+ return {
+ "version": __version__,
+ "tree": tree
+ }
+
+ def head(self):
+ return "", 201
+
+
+class HTTPServer(Server):
+
+ def __init__(self, host="0.0.0.0", port=38001, **kwargs):
+ super(HTTPServer, self).__init__(host=host, port=port, **kwargs)
+ self.component_data = kwargs.get("component_data", {})
+ logger.info("HTTPServer port={} {}".format(port, kwargs))
+ self.app = Flask(__name__)
+ self._port = port
+ self._host = host
+ # Todo : specify only few urls instead of *
+ # CORS(self.app)
+ self.component_id = kwargs.get("component_id")
+ self.keystone_project_id = kwargs.get("keystone_project_id")
+ self.container_chaining = kwargs.get("container_chaining")
+ self.api = Api(self.app)
+ self.__set_route()
+ # self.__hook_errors()
+
+ @self.app.errorhandler(exceptions.AuthException)
+ def _auth_exception(error):
+ return {"error": "Unauthorized"}, 401
+
+ def __hook_errors(self):
+ # FIXME (dthom): it doesn't work
+ def get_404_json(e):
+ return {"error": "Error", "code": 404, "description": e}
+ self.app.register_error_handler(404, get_404_json)
+
+ def get_400_json(e):
+ return {"error": "Error", "code": 400, "description": e}
+ self.app.register_error_handler(400, lambda e: get_400_json)
+ self.app.register_error_handler(403, exceptions.AuthException)
+
+ def __set_route(self):
+ self.api.add_resource(Root, '/')
+
+ for api in __API__:
+ self.api.add_resource(api, *api.__urls__,
+ resource_class_kwargs={
+ "component_data": self.component_data,
+ "cache": CACHE
+ }
+ )
+
+ def run(self):
+ self.app.run(host=self._host, port=self._port) # nosec
diff --git a/moonv4/moon_authz/moon_authz/messenger.py b/moonv4/moon_authz/moon_authz/messenger.py
deleted file mode 100644
index 6fa34770..00000000
--- a/moonv4/moon_authz/moon_authz/messenger.py
+++ /dev/null
@@ -1,50 +0,0 @@
-# Copyright 2015 Open Platform for NFV Project, Inc. and its contributors
-# This software is distributed under the terms and conditions of the 'Apache-2.0'
-# license which can be found in the file 'LICENSE' in this package distribution
-# or at 'http://www.apache.org/licenses/LICENSE-2.0'.
-
-from oslo_config import cfg
-import oslo_messaging
-import time
-from oslo_log import log as logging
-from moon_authz.api.generic import Status, Logs
-from moon_authz.api.authorization import Authorization
-from moon_utilities.api import APIList
-
-LOG = logging.getLogger(__name__)
-CONF = cfg.CONF
-
-
-class Server:
-
- def __init__(self, component_id, keystone_project_id):
- self.TOPIC = "authz-workers"
- transport = oslo_messaging.get_notification_transport(cfg.CONF)
- targets = [
- oslo_messaging.Target(topic=self.TOPIC),
- ]
- self.endpoints = [
- APIList((Status, Logs)),
- Status(),
- Logs(),
- Authorization(component_id)
- ]
- pool = "authz-workers"
- self.server = oslo_messaging.get_notification_listener(transport, targets,
- self.endpoints, executor='threading',
- pool=pool)
- LOG.info("Starting MQ notification server with topic: {}".format(self.TOPIC))
-
- def run(self):
- try:
- self.server.start()
- while True:
- time.sleep(0.1)
- except KeyboardInterrupt:
- print("Stopping server by crtl+c")
- except SystemExit:
- print("Stopping server")
-
- self.server.stop()
-
-
diff --git a/moonv4/moon_authz/moon_authz/server.py b/moonv4/moon_authz/moon_authz/server.py
index 0c2a36ff..5ca96e6f 100644
--- a/moonv4/moon_authz/moon_authz/server.py
+++ b/moonv4/moon_authz/moon_authz/server.py
@@ -4,31 +4,43 @@
# or at 'http://www.apache.org/licenses/LICENSE-2.0'.
import os
-from oslo_config import cfg
from oslo_log import log as logging
-# cfg.CONF.register_cli_opt(cfg.StrOpt('function_type', positional=True,
-# help="The type of function managed by this component (example 'authz')."))
-cfg.CONF.register_cli_opt(cfg.StrOpt('uuid', positional=True,
- help="The ID of the component managed here."))
-cfg.CONF.register_cli_opt(cfg.StrOpt('keystone_project_id', positional=True,
- help="The ID of the component managed here."))
-from moon_utilities import options # noqa
-from moon_authz.messenger import Server
-
-LOG = logging.getLogger(__name__)
-CONF = cfg.CONF
+from moon_authz.http_server import HTTPServer as Server
+from moon_utilities import configuration
+
+LOG = logging.getLogger("moon.server")
DOMAIN = "moon_authz"
__CWD__ = os.path.dirname(os.path.abspath(__file__))
def main():
- component_id = CONF.uuid
- keystone_project_id = CONF.keystone_project_id
- # function_type = CONF.intra_extension_id.replace(component_id, "").strip('_')
- LOG.info("Starting server with IP {} on component {}".format(
- CONF.security_router.host, component_id))
- server = Server(component_id=component_id, keystone_project_id=keystone_project_id)
+ component_id = os.getenv("UUID")
+ component_type = os.getenv("TYPE")
+ tcp_port = os.getenv("PORT")
+ pdp_id = os.getenv("PDP_ID")
+ meta_rule_id = os.getenv("META_RULE_ID")
+ keystone_project_id = os.getenv("KEYSTONE_PROJECT_ID")
+ configuration.init_logging()
+ LOG.info("component_type={}".format(component_type))
+ conf = configuration.get_configuration("plugins/{}".format(component_type))
+ conf["plugins/{}".format(component_type)]['id'] = component_id
+ hostname = conf["plugins/{}".format(component_type)].get('hostname', component_id)
+ port = conf["plugins/{}".format(component_type)].get('port', tcp_port)
+ bind = conf["plugins/{}".format(component_type)].get('bind', "0.0.0.0")
+
+ LOG.info("Starting server with IP {} on port {} bind to {}".format(hostname, port, bind))
+ server = Server(
+ host=bind,
+ port=int(port),
+ component_data={
+ 'component_id': component_id,
+ 'component_type': component_type,
+ 'pdp_id': pdp_id,
+ 'meta_rule_id': meta_rule_id,
+ 'keystone_project_id': keystone_project_id,
+ }
+ )
server.run()
diff --git a/moonv4/moon_authz/requirements.txt b/moonv4/moon_authz/requirements.txt
index 8faf9439..344bec52 100644
--- a/moonv4/moon_authz/requirements.txt
+++ b/moonv4/moon_authz/requirements.txt
@@ -1 +1,8 @@
-kombu !=4.0.1,!=4.0.0 \ No newline at end of file
+kombu !=4.0.1,!=4.0.0
+oslo.log
+flask
+oslo.config
+flask_restful
+flask_cors
+moon_db
+moon_utilities
diff --git a/moonv4/moon_interface/moon_interface/api/assignments.py b/moonv4/moon_interface/moon_interface/api/assignments.py
deleted file mode 100644
index 855a9049..00000000
--- a/moonv4/moon_interface/moon_interface/api/assignments.py
+++ /dev/null
@@ -1,264 +0,0 @@
-# Copyright 2015 Open Platform for NFV Project, Inc. and its contributors
-# This software is distributed under the terms and conditions of the 'Apache-2.0'
-# license which can be found in the file 'LICENSE' in this package distribution
-# or at 'http://www.apache.org/licenses/LICENSE-2.0'.
-"""
-Assignments allow to connect data with elements of perimeter
-
-"""
-
-from flask import request
-from flask_restful import Resource
-from oslo_log import log as logging
-from moon_utilities.security_functions import call
-from moon_utilities.security_functions import check_auth
-
-__version__ = "0.2.0"
-
-LOG = logging.getLogger("moon.interface.api." + __name__)
-
-
-class SubjectAssignments(Resource):
- """
- Endpoint for subject assignment requests
- """
-
- __urls__ = (
- "/policies/<string:uuid>/subject_assignments",
- "/policies/<string:uuid>/subject_assignments/",
- "/policies/<string:uuid>/subject_assignments/<string:perimeter_id>",
- "/policies/<string:uuid>/subject_assignments/<string:perimeter_id>/<string:category_id>",
- "/policies/<string:uuid>/subject_assignments/<string:perimeter_id>/<string:category_id>/<string:data_id>",
- )
-
- @check_auth
- def get(self, uuid=None, perimeter_id=None, category_id=None, data_id=None, user_id=None):
- """Retrieve all subject assignments or a specific one for a given policy
-
- :param uuid: uuid of the policy
- :param perimeter_id: uuid of the subject
- :param category_id: uuid of the subject category
- :param data_id: uuid of the subject scope
- :param user_id: user ID who do the request
- :return: {
- "subject_data_id": {
- "policy_id": "ID of the policy",
- "subject_id": "ID of the subject",
- "category_id": "ID of the category",
- "assignments": "Assignments list (list of data_id)",
- }
- }
- :internal_api: get_subject_assignments
- """
- return call(ctx={"id": uuid, "method": "get_subject_assignments", "perimeter_id": perimeter_id, "category_id": category_id, "user_id": user_id},
- args={"data_id": data_id})
-
- @check_auth
- def post(self, uuid=None, perimeter_id=None, category_id=None, data_id=None, user_id=None):
- """Create a subject assignment.
-
- :param uuid: uuid of the policy
- :param perimeter_id: uuid of the subject (not used here)
- :param category_id: uuid of the subject category (not used here)
- :param data_id: uuid of the subject scope (not used here)
- :param user_id: user ID who do the request
- :request body: {
- "id": "UUID of the subject",
- "category_id": "UUID of the category"
- "data_id": "UUID of the scope"
- }
- :return: {
- "subject_data_id": {
- "policy_id": "ID of the policy",
- "subject_id": "ID of the subject",
- "category_id": "ID of the category",
- "assignments": "Assignments list (list of data_id)",
- }
- }
- :internal_api: update_subject_assignment
- """
- return call("security_router",
- ctx={"id": uuid, "method": "update_subject_assignment", "user_id": user_id}, args=request.json)
-
- @check_auth
- def delete(self, uuid=None, perimeter_id=None, category_id=None, data_id=None, user_id=None):
- """Delete a subject assignment for a given policy
-
- :param uuid: uuid of the policy
- :param perimeter_id: uuid of the subject
- :param category_id: uuid of the subject category
- :param data_id: uuid of the subject scope
- :param user_id: user ID who do the request
- :return: {
- "result": "True or False",
- "message": "optional message"
- }
- :internal_api: delete_subject_assignment
- """
- return call("security_router",
- ctx={"id": uuid, "method": "delete_subject_assignment", "perimeter_id": perimeter_id, "category_id": category_id, "user_id": user_id},
- args={"data_id": data_id})
-
-
-class ObjectAssignments(Resource):
- """
- Endpoint for object assignment requests
- """
-
- __urls__ = (
- "/policies/<string:uuid>/object_assignments",
- "/policies/<string:uuid>/object_assignments/",
- "/policies/<string:uuid>/object_assignments/<string:perimeter_id>",
- "/policies/<string:uuid>/object_assignments/<string:perimeter_id>/<string:category_id>",
- "/policies/<string:uuid>/object_assignments/<string:perimeter_id>/<string:category_id>/<string:data_id>",
- )
-
- @check_auth
- def get(self, uuid=None, perimeter_id=None, category_id=None, data_id=None, user_id=None):
- """Retrieve all object assignment or a specific one for a given policy
-
- :param uuid: uuid of the policy
- :param perimeter_id: uuid of the object
- :param category_id: uuid of the object category
- :param data_id: uuid of the object scope
- :param user_id: user ID who do the request
- :return: {
- "object_data_id": {
- "policy_id": "ID of the policy",
- "object_id": "ID of the object",
- "category_id": "ID of the category",
- "assignments": "Assignments list (list of data_id)",
- }
- }
- :internal_api: get_object_assignments
- """
- return call("security_router",
- ctx={"id": uuid, "method": "get_object_assignments", "perimeter_id": perimeter_id, "category_id": category_id, "user_id": user_id},
- args={"data_id": data_id})
-
- @check_auth
- def post(self, uuid=None, perimeter_id=None, category_id=None, data_id=None, user_id=None):
- """Create an object assignment.
-
- :param uuid: uuid of the policy
- :param perimeter_id: uuid of the object (not used here)
- :param category_id: uuid of the object category (not used here)
- :param data_id: uuid of the object scope (not used here)
- :param user_id: user ID who do the request
- :request body: {
- "id": "UUID of the action",
- "category_id": "UUID of the category"
- "data_id": "UUID of the scope"
- }
- :return: {
- "object_data_id": {
- "policy_id": "ID of the policy",
- "object_id": "ID of the object",
- "category_id": "ID of the category",
- "assignments": "Assignments list (list of data_id)",
- }
- }
- :internal_api: update_object_assignment
- """
- return call("security_router",
- ctx={"id": uuid, "method": "update_object_assignment", "user_id": user_id}, args=request.json)
-
- @check_auth
- def delete(self, uuid=None, perimeter_id=None, category_id=None, data_id=None, user_id=None):
- """Delete a object assignment for a given policy
-
- :param uuid: uuid of the policy
- :param perimeter_id: uuid of the object
- :param category_id: uuid of the object category
- :param data_id: uuid of the object scope
- :param user_id: user ID who do the request
- :return: {
- "result": "True or False",
- "message": "optional message"
- }
- :internal_api: delete_object_assignment
- """
- return call("security_router",
- ctx={"id": uuid, "method": "delete_object_assignment", "perimeter_id": perimeter_id, "category_id": category_id, "user_id": user_id},
- args={"data_id": data_id})
-
-
-class ActionAssignments(Resource):
- """
- Endpoint for action assignment requests
- """
-
- __urls__ = (
- "/policies/<string:uuid>/action_assignments",
- "/policies/<string:uuid>/action_assignments/",
- "/policies/<string:uuid>/action_assignments/<string:perimeter_id>",
- "/policies/<string:uuid>/action_assignments/<string:perimeter_id>/<string:category_id>",
- "/policies/<string:uuid>/action_assignments/<string:perimeter_id>/<string:category_id>/<string:data_id>",
- )
-
- @check_auth
- def get(self, uuid=None, perimeter_id=None, category_id=None, data_id=None, user_id=None):
- """Retrieve all action assignment or a specific one for a given policy
-
- :param uuid: uuid of the policy
- :param perimeter_id: uuid of the action
- :param category_id: uuid of the action category
- :param data_id: uuid of the action scope
- :param user_id: user ID who do the request
- :return: {
- "action_data_id": {
- "policy_id": "ID of the policy",
- "object_id": "ID of the action",
- "category_id": "ID of the category",
- "assignments": "Assignments list (list of data_id)",
- }
- }
- :internal_api: get_action_assignments
- """
- return call("security_router", ctx={"id": uuid, "method": "get_action_assignments", "perimeter_id": perimeter_id, "category_id": category_id, "user_id": user_id},
- args={"data_id": data_id})
-
- @check_auth
- def post(self, uuid=None, perimeter_id=None, category_id=None, data_id=None, user_id=None):
- """Create an action assignment.
-
- :param uuid: uuid of the policy
- :param perimeter_id: uuid of the action (not used here)
- :param category_id: uuid of the action category (not used here)
- :param data_id: uuid of the action scope (not used here)
- :param user_id: user ID who do the request
- :request body: {
- "id": "UUID of the action",
- "category_id": "UUID of the category",
- "data_id": "UUID of the scope"
- }
- :return: {
- "action_data_id": {
- "policy_id": "ID of the policy",
- "object_id": "ID of the action",
- "category_id": "ID of the category",
- "assignments": "Assignments list (list of data_id)",
- }
- }
- :internal_api: update_action_assignment
- """
- return call("security_router", ctx={"id": uuid, "method": "update_action_assignment", "user_id": user_id},
- args=request.json)
-
- @check_auth
- def delete(self, uuid=None, perimeter_id=None, category_id=None, data_id=None, user_id=None):
- """Delete a action assignment for a given policy
-
- :param uuid: uuid of the policy
- :param perimeter_id: uuid of the action
- :param category_id: uuid of the action category
- :param data_id: uuid of the action scope
- :param user_id: user ID who do the request
- :return: {
- "result": "True or False",
- "message": "optional message"
- }
- :internal_api: delete_action_assignment
- """
- return call("security_router", ctx={"id": uuid, "method": "delete_action_assignment", "perimeter_id": perimeter_id, "category_id": category_id, "user_id": user_id},
- args={"data_id": data_id})
diff --git a/moonv4/moon_interface/moon_interface/api/authz.py b/moonv4/moon_interface/moon_interface/api/authz.py
index 69de0f80..3847cc73 100644
--- a/moonv4/moon_interface/moon_interface/api/authz.py
+++ b/moonv4/moon_interface/moon_interface/api/authz.py
@@ -6,23 +6,194 @@
Authz is the endpoint to get authorization response
"""
-from uuid import uuid4
-import time
+from flask import request
from flask_restful import Resource
-from oslo_log import log as logging
-from moon_utilities.security_functions import call
+import logging
+import pickle
+import requests
+import time
+from uuid import uuid4
+
+from moon_interface.containers import DockerManager
+from moon_interface.authz_requests import AuthzRequest
+from moon_utilities import configuration
__version__ = "0.1.0"
LOG = logging.getLogger("moon.interface.api." + __name__)
+def pdp_in_cache(cache, uuid):
+ """Check if a PDP exist with this Keystone Project ID in the cache of this component
+
+ :param cache: Cache to use
+ :param uuid: Keystone Project ID
+ :return: True or False
+ """
+ for item_uuid, item_value in cache.pdp.items():
+ if uuid == item_value['keystone_project_id']:
+ return item_uuid, item_value
+ return None, None
+
+
+def pdp_in_manager(cache, uuid):
+ """Check if a PDP exist with this Keystone Project ID in the Manager component
+
+ :param cache: Cache to use
+ :param uuid: Keystone Project ID
+ :return: True or False
+ """
+ cache.update()
+ return pdp_in_cache(cache, uuid)
+
+
+def container_exist(cache, uuid):
+ """Check if a PDP exist with this Keystone Project ID in the Manager component
+
+ :param cache: Cache to use
+ :param uuid: Keystone Project ID
+ :return: True or False
+ """
+ for key, value in cache.containers.items():
+ if "keystone_project_id" not in value:
+ continue
+ if value["keystone_project_id"] == uuid:
+ try:
+ req = requests.head("http://{}:{}/".format(
+ value.get("hostname"),
+ value.get("port")[0].get("PublicPort")))
+ LOG.info("container_exist {}".format(req.status_code))
+ if req.status_code in (200, 201):
+ return value
+ return
+ except requests.exceptions.ConnectionError:
+ pass
+ # maybe hostname is not working so trying with IP address
+ try:
+ req = requests.head("http://{}:{}/".format(
+ value.get("ip"),
+ value.get("port")[0].get("PublicPort")))
+ if req.status_code in (200, 201):
+ return value
+ return
+ except requests.exceptions.ConnectionError:
+ return
+
+
+def build_container(cache, manager_url, uuid, meta_rule_id, plugin_name="authz"):
+ """Create the container and update the cache with the given perimeter elements
+
+ :param cache: Cache to use
+ :param manager_url: URL of the manager
+ :param uuid: Keystone Project ID
+ :param meta_rule_id: UUID of the meta_rule
+ :param plugin_name: name of the plugin to use
+ :return: True or False
+ """
+ LOG.info("Building a new container for {}".format(plugin_name))
+ manager = DockerManager()
+ tcp_port = configuration.increment_port()
+ container_name = configuration.get_plugins()[plugin_name]['container']
+ name = "{}_{}".format(plugin_name, uuid4().hex)
+ policy_id = cache.get_policy_from_meta_rules(meta_rule_id)
+ container_data = {
+ "name": name,
+ "hostname": name,
+ "port": {
+ "PrivatePort": tcp_port,
+ "Type": "tcp",
+ "IP": "0.0.0.0",
+ "PublicPort": tcp_port
+ },
+ "keystone_project_id": uuid,
+ "pdp_id": cache.get_pdp_from_keystone_project(uuid),
+ "meta_rule_id": meta_rule_id,
+ "policy_id": policy_id,
+ "container_name": container_name,
+ "plugin_name": plugin_name
+ }
+ container = manager.create_container(container_data)
+ container_data['container_id'] = container.id
+ container_data['port']["IP"] = container.ip
+ container_data['start_time'] = time.time()
+ req = requests.post("{}/containers".format(manager_url),
+ json=container_data)
+ if req.status_code == 200:
+ cache.add_container(container_data)
+ return True
+
+
+def create_containers(cache, manager_url, uuid, plugin_name="authz"):
+ """Create the container and update the cache with the given perimeter elements
+
+ :param cache: Cache to use
+ :param manager_url: URL of the manager
+ :param uuid: Keystone Project ID
+ :param plugin_name: name of the plugin to use
+ :return: True or False
+ """
+ LOG.info("Need to create some containers for {}".format(uuid))
+ for pdp_id, pdp_value in cache.pdp.items():
+ LOG.info("pdp {}".format(pdp_value))
+ if uuid == pdp_value.get("keystone_project_id", ""):
+ LOG.info("uuid {}".format(uuid))
+ for policy_id in pdp_value.get("security_pipeline", []):
+ LOG.info("policy {}".format(policy_id))
+ model_id = cache.policies[policy_id]["model_id"]
+ model_value = cache.models[model_id]
+ for meta_rule_id in model_value["meta_rules"]:
+ LOG.info("meta_rule {}".format(meta_rule_id))
+ build_container(
+ cache=cache,
+ uuid=uuid,
+ manager_url=manager_url,
+ meta_rule_id=meta_rule_id,
+ plugin_name=plugin_name)
+ return
+
+
+def create_authz_request(cache, interface_name, manager_url, uuid, subject_name, object_name, action_name):
+ """Create the authorization request and make the first call to the Authz function
+
+ :param cache: Cache to use
+ :param interface_name: hostname of the interface
+ :param manager_url: URL of the manager
+ :param uuid: Keystone Project ID
+ :param subject_name: name of the subject
+ :param object_name: name of the object
+ :param action_name: name of the action
+ :return: Authorisation request
+ """
+ req_id = uuid4().hex
+ ctx = {
+ "project_id": uuid,
+ "subject_name": subject_name,
+ "object_name": object_name,
+ "action_name": action_name,
+ "request_id": req_id,
+ "interface_name": interface_name,
+ "manager_url": manager_url,
+ "cookie": uuid4().hex
+ }
+ cache.authz_requests[req_id] = AuthzRequest(ctx)
+ return cache.authz_requests[req_id]
+
+
class Authz(Resource):
"""
Endpoint for authz requests
"""
- __urls__ = ("/authz/<string:uuid>/<string:subject_name>/<string:object_name>/<string:action_name>", )
+ __urls__ = (
+ "/authz/<string:uuid>",
+ "/authz/<string:uuid>/<string:subject_name>/<string:object_name>/<string:action_name>",
+ )
+
+ def __init__(self, **kwargs):
+ self.CACHE = kwargs.get("cache")
+ self.INTERFACE_NAME = kwargs.get("interface_name", "interface")
+ self.MANAGER_URL = kwargs.get("manager_url", "http://manager:8080")
+ self.TIMEOUT = 5
def get(self, uuid=None, subject_name=None, object_name=None, action_name=None):
"""Get a response on an authorization request
@@ -51,17 +222,52 @@ class Authz(Resource):
}
:internal_api: authz
"""
- # Note (asteroide): user_id default to admin to be able to read the database
- # it would be better to have a read-only user.
- start_time = time.time()
- result = call("security_router", ctx={"id": uuid,
- "call_master": False,
- "method": "authz",
- "subject_name": subject_name,
- "object_name": object_name,
- "action_name": action_name,
- "user_id": "admin",
- "request_id": uuid4().hex}, args={})
- end_time = time.time()
- result['time'] = {"start": start_time, "end": end_time}
- return result
+ pdp_id, pdp_value = pdp_in_cache(self.CACHE, uuid)
+ if not pdp_id:
+ pdp_id, pdp_value = pdp_in_manager(self.CACHE, uuid)
+ if not pdp_id:
+ return {
+ "result": False,
+ "message": "Unknown Project ID or "
+ "Project ID is not bind to a PDP."}, 403
+ if not container_exist(self.CACHE, uuid):
+ create_containers(
+ cache=self.CACHE,
+ uuid=uuid,
+ manager_url=self.MANAGER_URL,
+ plugin_name="authz")
+ authz_request = create_authz_request(
+ cache=self.CACHE,
+ uuid=uuid,
+ interface_name=self.INTERFACE_NAME,
+ manager_url=self.MANAGER_URL,
+ subject_name=subject_name,
+ object_name=object_name,
+ action_name=action_name)
+ cpt = 0
+ while True:
+ if cpt > self.TIMEOUT*10:
+ return {"result": False,
+ "message": "Authz request had timed out."}, 500
+ if authz_request.is_authz():
+ if authz_request.final_result == "Grant":
+ return {"result": True, "message": ""}, 200
+ return {"result": False, "message": ""}, 401
+ cpt += 1
+ time.sleep(0.1)
+
+ def patch(self, uuid=None, subject_name=None, object_name=None, action_name=None):
+ """Get a response on an authorization request
+
+ :param uuid: uuid of the authorization request
+ :param subject_name: not used
+ :param object_name: not used
+ :param action_name: not used
+ :request body: a Context object
+ :return: {}
+ :internal_api: authz
+ """
+ if uuid in self.CACHE.authz_requests:
+ self.CACHE.authz_requests[uuid].set_result(pickle.loads(request.data))
+ return "", 201
+ return {"result": False, "message": "The request ID is unknown"}, 500
diff --git a/moonv4/moon_interface/moon_interface/api/data.py b/moonv4/moon_interface/moon_interface/api/data.py
deleted file mode 100644
index 6d959095..00000000
--- a/moonv4/moon_interface/moon_interface/api/data.py
+++ /dev/null
@@ -1,259 +0,0 @@
-# Copyright 2015 Open Platform for NFV Project, Inc. and its contributors
-# This software is distributed under the terms and conditions of the 'Apache-2.0'
-# license which can be found in the file 'LICENSE' in this package distribution
-# or at 'http://www.apache.org/licenses/LICENSE-2.0'.
-"""
-Data are elements used to create rules
-
-"""
-
-from flask import request
-from flask_restful import Resource
-from oslo_log import log as logging
-from moon_utilities.security_functions import call
-from moon_utilities.security_functions import check_auth
-
-__version__ = "0.2.0"
-
-LOG = logging.getLogger("moon.interface.api." + __name__)
-
-
-class SubjectData(Resource):
- """
- Endpoint for subject data requests
- """
-
- __urls__ = (
- "/policies/<string:uuid>/subject_data",
- "/policies/<string:uuid>/subject_data/",
- "/policies/<string:uuid>/subject_data/<string:category_id>",
- "/policies/<string:uuid>/subject_data/<string:category_id>/<string:data_id>",
- )
-
- @check_auth
- def get(self, uuid=None, category_id=None, data_id=None, user_id=None):
- """Retrieve all subject categories or a specific one if sid is given for a given policy
-
- :param uuid: uuid of the policy
- :param category_id: uuid of the subject category
- :param data_id: uuid of the subject data
- :param user_id: user ID who do the request
- :return: [{
- "policy_id": "policy_id1",
- "category_id": "category_id1",
- "data": {
- "subject_data_id": {
- "name": "name of the data",
- "description": "description of the data"
- }
- }
- }]
- :internal_api: get_subject_data
- """
- return call("security_router", ctx={"id": uuid, "method": "get_subject_data", "category_id": category_id, "user_id": user_id},
- args={"data_id": data_id})
-
- @check_auth
- def post(self, uuid=None, category_id=None, data_id=None, user_id=None):
- """Create or update a subject.
-
- :param uuid: uuid of the policy
- :param category_id: uuid of the subject category
- :param data_id: uuid of the subject data
- :param user_id: user ID who do the request
- :request body: {
- "name": "name of the data",
- "description": "description of the data"
- }
- :return: {
- "policy_id": "policy_id1",
- "category_id": "category_id1",
- "data": {
- "subject_data_id": {
- "name": "name of the data",
- "description": "description of the data"
- }
- }
- }
- :internal_api: add_subject_data
- """
- return call("security_router", ctx={"id": uuid, "method": "add_subject_data", "category_id": category_id, "user_id": user_id},
- args=request.json)
-
- @check_auth
- def delete(self, uuid=None, category_id=None, data_id=None, user_id=None):
- """Delete a subject for a given policy
-
- :param uuid: uuid of the policy
- :param category_id: uuid of the subject category
- :param data_id: uuid of the subject data
- :param user_id: user ID who do the request
- :return: [{
- "result": "True or False",
- "message": "optional message"
- }]
- :internal_api: delete_subject_data
- """
- return call("security_router", ctx={"id": uuid, "method": "delete_subject_data", "category_id": category_id, "user_id": user_id},
- args={"data_id": data_id})
-
-
-class ObjectData(Resource):
- """
- Endpoint for object data requests
- """
-
- __urls__ = (
- "/policies/<string:uuid>/object_data",
- "/policies/<string:uuid>/object_data/",
- "/policies/<string:uuid>/object_data/<string:category_id>",
- "/policies/<string:uuid>/object_data/<string:category_id>/<string:data_id>",
- )
-
- @check_auth
- def get(self, uuid=None, category_id=None, data_id=None, user_id=None):
- """Retrieve all object categories or a specific one if sid is given for a given policy
-
- :param uuid: uuid of the policy
- :param category_id: uuid of the object category
- :param data_id: uuid of the object data
- :param user_id: user ID who do the request
- :return: [{
- "policy_id": "policy_id1",
- "category_id": "category_id1",
- "data": {
- "object_data_id": {
- "name": "name of the data",
- "description": "description of the data"
- }
- }
- }]
- :internal_api: get_object_data
- """
- return call("security_router", ctx={"id": uuid, "method": "get_object_data", "category_id": category_id, "user_id": user_id},
- args={"data_id": data_id})
-
- @check_auth
- def post(self, uuid=None, category_id=None, data_id=None, user_id=None):
- """Create or update a object.
-
- :param uuid: uuid of the policy
- :param category_id: uuid of the object category
- :param data_id: uuid of the object data
- :param user_id: user ID who do the request
- :request body: {
- "name": "name of the data",
- "description": "description of the data"
- }
- :return: {
- "policy_id": "policy_id1",
- "category_id": "category_id1",
- "data": {
- "object_data_id": {
- "name": "name of the data",
- "description": "description of the data"
- }
- }
- }
- :internal_api: add_object_data
- """
- return call("security_router", ctx={"id": uuid, "method": "add_object_data", "category_id": category_id, "user_id": user_id}, args=request.json)
-
- @check_auth
- def delete(self, uuid=None, category_id=None, data_id=None, user_id=None):
- """Delete a object for a given policy
-
- :param uuid: uuid of the policy
- :param category_id: uuid of the object category
- :param data_id: uuid of the object data
- :param user_id: user ID who do the request
- :return: {
- "result": "True or False",
- "message": "optional message"
- }
- :internal_api: delete_object_data
- """
- return call("security_router", ctx={"id": uuid, "method": "delete_object_data", "category_id": category_id, "user_id": user_id},
- args={"data_id": data_id})
-
-
-class ActionData(Resource):
- """
- Endpoint for action data requests
- """
-
- __urls__ = (
- "/policies/<string:uuid>/action_data",
- "/policies/<string:uuid>/action_data/",
- "/policies/<string:uuid>/action_data/<string:category_id>",
- "/policies/<string:uuid>/action_data/<string:category_id>/<string:data_id>",
- )
-
- @check_auth
- def get(self, uuid=None, category_id=None, data_id=None, user_id=None):
- """Retrieve all action categories or a specific one if sid is given for a given policy
-
- :param uuid: uuid of the policy
- :param category_id: uuid of the action category
- :param data_id: uuid of the action data
- :param user_id: user ID who do the request
- :return: [{
- "policy_id": "policy_id1",
- "category_id": "category_id1",
- "data": {
- "action_data_id": {
- "name": "name of the data",
- "description": "description of the data"
- }
- }
- }]
- :internal_api: get_action_data
- """
- return call("security_router", ctx={"id": uuid, "method": "get_action_data", "category_id": category_id, "user_id": user_id},
- args={"data_id": data_id})
-
- @check_auth
- def post(self, uuid=None, category_id=None, data_id=None, user_id=None):
- """Create or update a action.
-
- :param uuid: uuid of the policy
- :param category_id: uuid of the action category
- :param data_id: uuid of the action data
- :param user_id: user ID who do the request
- :request body: {
- "name": "name of the data",
- "description": "description of the data"
- }
- :return: {
- "policy_id": "policy_id1",
- "category_id": "category_id1",
- "data": {
- "action_data_id": {
- "name": "name of the data",
- "description": "description of the data"
- }
- }
- }
- :internal_api: add_action_data
- """
- return call("security_router", ctx={"id": uuid, "method": "add_action_data", "category_id": category_id, "user_id": user_id},
- args=request.json)
-
- @check_auth
- def delete(self, uuid=None, category_id=None, data_id=None, user_id=None):
- """Delete a action for a given policy
-
- :param uuid: uuid of the policy
- :param category_id: uuid of the action category
- :param data_id: uuid of the action data
- :param user_id: user ID who do the request
- :return: {
- "result": "True or False",
- "message": "optional message"
- }
- :internal_api: delete_action_data
- """
- return call("security_router", ctx={"id": uuid, "method": "delete_action_data", "category_id": category_id, "user_id": user_id},
- args={"data_id": data_id})
-
-
diff --git a/moonv4/moon_interface/moon_interface/api/meta_data.py b/moonv4/moon_interface/moon_interface/api/meta_data.py
deleted file mode 100644
index 3c933759..00000000
--- a/moonv4/moon_interface/moon_interface/api/meta_data.py
+++ /dev/null
@@ -1,204 +0,0 @@
-# Copyright 2015 Open Platform for NFV Project, Inc. and its contributors
-# This software is distributed under the terms and conditions of the 'Apache-2.0'
-# license which can be found in the file 'LICENSE' in this package distribution
-# or at 'http://www.apache.org/licenses/LICENSE-2.0'.
-"""
-Meta Data are elements used to create Meta data (skeleton of security policies)
-
-"""
-
-from flask import request
-from flask_restful import Resource
-from oslo_log import log as logging
-from moon_utilities.security_functions import call
-from moon_utilities.security_functions import check_auth
-
-__version__ = "0.2.0"
-
-LOG = logging.getLogger("moon.interface.api." + __name__)
-
-
-class SubjectCategories(Resource):
- """
- Endpoint for subject categories requests
- """
-
- __urls__ = (
- "/subject_categories",
- "/subject_categories/",
- "/subject_categories/<string:category_id>",
- )
-
- @check_auth
- def get(self, category_id=None, user_id=None):
- """Retrieve all subject categories or a specific one
-
- :param category_id: uuid of the subject category
- :param user_id: user ID who do the request
- :return: {
- "subject_category_id": {
- "name": "name of the category",
- "description": "description of the category"
- }
- }
- :internal_api: get_subject_categories
- """
- return call("security_router", ctx={"method": "get_subject_categories", "user_id": user_id}, args={"category_id": category_id})
-
- @check_auth
- def post(self, category_id=None, user_id=None):
- """Create or update a subject category.
-
- :param category_id: must not be used here
- :param user_id: user ID who do the request
- :request body: {
- "name": "name of the category",
- "description": "description of the category"
- }
- :return: {
- "subject_category_id": {
- "name": "name of the category",
- "description": "description of the category"
- }
- }
- :internal_api: add_subject_category
- """
- return call("security_router", ctx={"method": "set_subject_category", "user_id": user_id}, args=request.json)
-
- @check_auth
- def delete(self, category_id=None, user_id=None):
- """Delete a subject category
-
- :param category_id: uuid of the subject category to delete
- :param user_id: user ID who do the request
- :return: {
- "result": "True or False",
- "message": "optional message"
- }
- :internal_api: delete_subject_category
- """
- return call("security_router", ctx={"method": "delete_subject_category", "user_id": user_id}, args={"category_id": category_id})
-
-
-class ObjectCategories(Resource):
- """
- Endpoint for object categories requests
- """
-
- __urls__ = (
- "/object_categories",
- "/object_categories/",
- "/object_categories/<string:category_id>",
- )
-
- @check_auth
- def get(self, category_id=None, user_id=None):
- """Retrieve all object categories or a specific one
-
- :param category_id: uuid of the object category
- :param user_id: user ID who do the request
- :return: {
- "object_category_id": {
- "name": "name of the category",
- "description": "description of the category"
- }
- }
- :internal_api: get_object_categories
- """
- return call("security_router", ctx={"method": "get_object_categories", "user_id": user_id}, args={"category_id": category_id})
-
- @check_auth
- def post(self, category_id=None, user_id=None):
- """Create or update a object category.
-
- :param category_id: must not be used here
- :param user_id: user ID who do the request
- :request body: {
- "name": "name of the category",
- "description": "description of the category"
- }
- :return: {
- "object_category_id": {
- "name": "name of the category",
- "description": "description of the category"
- }
- }
- :internal_api: add_object_category
- """
- return call("security_router", ctx={"method": "set_object_category", "user_id": user_id}, args=request.json)
-
- @check_auth
- def delete(self, category_id=None, user_id=None):
- """Delete an object category
-
- :param category_id: uuid of the object category to delete
- :param user_id: user ID who do the request
- :return: {
- "result": "True or False",
- "message": "optional message"
- }
- :internal_api: delete_object_category
- """
- return call("security_router", ctx={"method": "delete_object_category", "user_id": user_id}, args={"category_id": category_id})
-
-
-class ActionCategories(Resource):
- """
- Endpoint for action categories requests
- """
-
- __urls__ = (
- "/action_categories",
- "/action_categories/",
- "/action_categories/<string:category_id>",
- )
-
- @check_auth
- def get(self, category_id=None, user_id=None):
- """Retrieve all action categories or a specific one
-
- :param category_id: uuid of the action category
- :param user_id: user ID who do the request
- :return: {
- "action_category_id": {
- "name": "name of the category",
- "description": "description of the category"
- }
- }
- :internal_api: get_action_categories
- """
- return call("security_router", ctx={"method": "get_action_categories", "user_id": user_id}, args={"category_id": category_id})
-
- @check_auth
- def post(self, category_id=None, user_id=None):
- """Create or update an action category.
-
- :param category_id: must not be used here
- :param user_id: user ID who do the request
- :request body: {
- "name": "name of the category",
- "description": "description of the category"
- }
- :return: {
- "action_category_id": {
- "name": "name of the category",
- "description": "description of the category"
- }
- }
- :internal_api: add_action_category
- """
- return call("security_router", ctx={"method": "set_action_category", "user_id": user_id}, args=request.json)
-
- @check_auth
- def delete(self, category_id=None, user_id=None):
- """Delete an action
-
- :param category_id: uuid of the action category to delete
- :param user_id: user ID who do the request
- :return: {
- "result": "True or False",
- "message": "optional message"
- }
- :internal_api: delete_action_category
- """
- return call("security_router", ctx={"method": "delete_action_category", "user_id": user_id}, args={"category_id": category_id})
diff --git a/moonv4/moon_interface/moon_interface/api/meta_rules.py b/moonv4/moon_interface/moon_interface/api/meta_rules.py
deleted file mode 100644
index 85072243..00000000
--- a/moonv4/moon_interface/moon_interface/api/meta_rules.py
+++ /dev/null
@@ -1,138 +0,0 @@
-# Copyright 2015 Open Platform for NFV Project, Inc. and its contributors
-# This software is distributed under the terms and conditions of the 'Apache-2.0'
-# license which can be found in the file 'LICENSE' in this package distribution
-# or at 'http://www.apache.org/licenses/LICENSE-2.0'.
-"""
-Meta rules are skeleton for security policies
-
-"""
-
-from flask import request
-from flask_restful import Resource
-from oslo_log import log as logging
-from moon_utilities.security_functions import call
-from moon_utilities.security_functions import check_auth
-
-__version__ = "0.1.0"
-
-LOG = logging.getLogger("moon.interface.api." + __name__)
-
-
-class MetaRules(Resource):
- """
- Endpoint for meta rules requests
- """
-
- __urls__ = ("/meta_rules",
- "/meta_rules/",
- "/meta_rules/<string:meta_rule_id>",
- "/meta_rules/<string:meta_rule_id>/")
-
- @check_auth
- def get(self, meta_rule_id=None, user_id=None):
- """Retrieve all sub meta rules
-
- :param meta_rule_id: Meta rule algorithm ID
- :param user_id: user ID who do the request
- :return: {
- "meta_rules": {
- "meta_rule_id1": {
- "name": "name of the meta rule",
- "algorithm": "name of the meta rule algorithm",
- "subject_categories": ["subject_category_id1", "subject_category_id2"],
- "object_categories": ["object_category_id1"],
- "action_categories": ["action_category_id1"]
- },
- }
- }
- :internal_api: get_meta_rules
- """
- return call("security_router", ctx={"method": "get_meta_rules",
- "user_id": user_id,
- "meta_rule_id": meta_rule_id}, args={})
-
- @check_auth
- def post(self, meta_rule_id=None, user_id=None):
- """Add a meta rule
-
- :param meta_rule_id: Meta rule ID
- :param user_id: user ID who do the request
- :request body: post = {
- "name": "name of the meta rule",
- "subject_categories": ["subject_category_id1", "subject_category_id2"],
- "object_categories": ["object_category_id1"],
- "action_categories": ["action_category_id1"]
- }
- :return: {
- "meta_rules": {
- "meta_rule_id1": {
- "name": "name of the meta rule",
- "subject_categories": ["subject_category_id1", "subject_category_id2"],
- "object_categories": ["object_category_id1"],
- "action_categories": ["action_category_id1"]
- },
- }
- }
- :internal_api: add_meta_rules
- """
- return call("security_router", ctx={"method": "add_meta_rules",
- "user_id": user_id,
- "meta_rule_id": meta_rule_id}, args=request.json)
-
- @check_auth
- def patch(self, meta_rule_id=None, user_id=None):
- """Update a meta rule
-
- :param meta_rule_id: Meta rule ID
- :param user_id: user ID who do the request
- :request body: patch = {
- "name": "name of the meta rule",
- "subject_categories": ["subject_category_id1", "subject_category_id2"],
- "object_categories": ["object_category_id1"],
- "action_categories": ["action_category_id1"]
- }
- :return: {
- "meta_rules": {
- "meta_rule_id1": {
- "name": "name of the meta rule",
- "subject_categories": ["subject_category_id1", "subject_category_id2"],
- "object_categories": ["object_category_id1"],
- "action_categories": ["action_category_id1"]
- },
- }
- }
- :internal_api: set_meta_rules
- """
- return call("security_router", ctx={"method": "set_meta_rules",
- "user_id": user_id,
- "meta_rule_id": meta_rule_id}, args=request.json)
-
- @check_auth
- def delete(self, meta_rule_id=None, user_id=None):
- """Delete a meta rule
-
- :param meta_rule_id: Meta rule ID
- :param user_id: user ID who do the request
- :request body: delete = {
- "name": "name of the meta rule",
- "subject_categories": ["subject_category_id1", "subject_category_id2"],
- "object_categories": ["object_category_id1"],
- "action_categories": ["action_category_id1"]
- }
- :return: {
- "meta_rules": {
- "meta_rule_id1": {
- "name": "name of the meta rule",
- "subject_categories": ["subject_category_id1", "subject_category_id2"],
- "object_categories": ["object_category_id1"],
- "action_categories": ["action_category_id1"]
- },
- }
- }
- :internal_api: delete_meta_rules
- """
- return call("security_router", ctx={"method": "delete_meta_rules",
- "user_id": user_id,
- "meta_rule_id": meta_rule_id}, args=request.json)
-
-
diff --git a/moonv4/moon_interface/moon_interface/api/models.py b/moonv4/moon_interface/moon_interface/api/models.py
deleted file mode 100644
index f905db63..00000000
--- a/moonv4/moon_interface/moon_interface/api/models.py
+++ /dev/null
@@ -1,101 +0,0 @@
-# Copyright 2015 Open Platform for NFV Project, Inc. and its contributors
-# This software is distributed under the terms and conditions of the 'Apache-2.0'
-# license which can be found in the file 'LICENSE' in this package distribution
-# or at 'http://www.apache.org/licenses/LICENSE-2.0'.
-"""
-Models aggregate multiple meta rules
-"""
-
-from flask import request
-from flask_restful import Resource
-from oslo_log import log as logging
-from moon_utilities.security_functions import call
-from moon_utilities.security_functions import check_auth
-
-__version__ = "0.1.0"
-
-LOG = logging.getLogger("moon.interface.api." + __name__)
-
-
-class Models(Resource):
- """
- Endpoint for model requests
- """
-
- __urls__ = (
- "/models",
- "/models/",
- "/models/<string:uuid>",
- "/models/<string:uuid>/",
- )
-
- @check_auth
- def get(self, uuid=None, user_id=None):
- """Retrieve all models
-
- :param uuid: uuid of the model
- :param user_id: user ID who do the request
- :return: {
- "model_id1": {
- "name": "...",
- "description": "...",
- "meta_rules": ["meta_rule_id1", ]
- }
- }
- :internal_api: get_models
- """
- return call("security_router", ctx={"id": uuid, "method": "get_models", "user_id": user_id}, args={})
-
- @check_auth
- def post(self, uuid=None, user_id=None):
- """Create model.
-
- :param uuid: uuid of the model (not used here)
- :param user_id: user ID who do the request
- :request body: {
- "name": "...",
- "description": "...",
- "meta_rules": ["meta_rule_id1", ]
- }
- :return: {
- "model_id1": {
- "name": "...",
- "description": "...",
- "meta_rules": ["meta_rule_id1", ]
- }
- }
- :internal_api: add_model
- """
- return call("security_router", ctx={"id": uuid, "method": "add_model", "user_id": user_id}, args=request.json)
-
- @check_auth
- def delete(self, uuid=None, user_id=None):
- """Delete a model
-
- :param uuid: uuid of the model to delete
- :param user_id: user ID who do the request
- :return: {
- "result": "True or False",
- "message": "optional message"
- }
- :internal_api: delete_model
- """
- return call("security_router", ctx={"id": uuid, "method": "delete_model", "user_id": user_id}, args={})
-
- @check_auth
- def patch(self, uuid=None, user_id=None):
- """Update a model
-
- :param uuid: uuid of the model to update
- :param user_id: user ID who do the request
- :return: {
- "model_id1": {
- "name": "...",
- "description": "...",
- "meta_rules": ["meta_rule_id1", ]
- }
- }
- :internal_api: update_model
- """
- return call("security_router", ctx={"id": uuid, "method": "update_model", "user_id": user_id}, args=request.json)
-
diff --git a/moonv4/moon_interface/moon_interface/api/pdp.py b/moonv4/moon_interface/moon_interface/api/pdp.py
deleted file mode 100644
index 5316227b..00000000
--- a/moonv4/moon_interface/moon_interface/api/pdp.py
+++ /dev/null
@@ -1,106 +0,0 @@
-# Copyright 2015 Open Platform for NFV Project, Inc. and its contributors
-# This software is distributed under the terms and conditions of the 'Apache-2.0'
-# license which can be found in the file 'LICENSE' in this package distribution
-# or at 'http://www.apache.org/licenses/LICENSE-2.0'.
-"""
-PDP are Policy Decision Point.
-
-"""
-
-from flask import request
-from flask_restful import Resource
-from oslo_log import log as logging
-from moon_utilities.security_functions import call
-from moon_utilities.security_functions import check_auth
-
-__version__ = "0.1.0"
-
-LOG = logging.getLogger("moon.interface.api." + __name__)
-
-
-class PDP(Resource):
- """
- Endpoint for pdp requests
- """
-
- __urls__ = (
- "/pdp",
- "/pdp/",
- "/pdp/<string:uuid>",
- "/pdp/<string:uuid>/",
- )
-
- @check_auth
- def get(self, uuid=None, user_id=None):
- """Retrieve all pdp
-
- :param uuid: uuid of the pdp
- :param user_id: user ID who do the request
- :return: {
- "pdp_id1": {
- "name": "...",
- "security_pipeline": [...],
- "keystone_project_id": "keystone_project_id1",
- "description": "...",
- }
- }
- :internal_api: get_pdp
- """
- return call("security_router", ctx={"id": uuid, "method": "get_pdp", "user_id": user_id}, args={})
-
- @check_auth
- def post(self, uuid=None, user_id=None):
- """Create pdp.
-
- :param uuid: uuid of the pdp (not used here)
- :param user_id: user ID who do the request
- :request body: {
- "name": "...",
- "security_pipeline": [...],
- "keystone_project_id": "keystone_project_id1",
- "description": "...",
- }
- :return: {
- "pdp_id1": {
- "name": "...",
- "security_pipeline": [...],
- "keystone_project_id": "keystone_project_id1",
- "description": "...",
- }
- }
- :internal_api: add_pdp
- """
- return call("security_router", ctx={"id": uuid, "method": "add_pdp", "user_id": user_id}, args=request.json)
-
- @check_auth
- def delete(self, uuid=None, user_id=None):
- """Delete a pdp
-
- :param uuid: uuid of the pdp to delete
- :param user_id: user ID who do the request
- :return: {
- "result": "True or False",
- "message": "optional message"
- }
- :internal_api: delete_pdp
- """
- return call("security_router", ctx={"id": uuid, "method": "delete_pdp", "user_id": user_id}, args={})
-
- @check_auth
- def patch(self, uuid=None, user_id=None):
- """Update a pdp
-
- :param uuid: uuid of the pdp to update
- :param user_id: user ID who do the request
- :return: {
- "pdp_id1": {
- "name": "...",
- "security_pipeline": [...],
- "keystone_project_id": "keystone_project_id1",
- "description": "...",
- }
- }
- :internal_api: update_pdp
- """
- return call("security_router", ctx={"id": uuid, "method": "update_pdp", "user_id": user_id}, args=request.json)
-
diff --git a/moonv4/moon_interface/moon_interface/api/perimeter.py b/moonv4/moon_interface/moon_interface/api/perimeter.py
deleted file mode 100644
index 177161f6..00000000
--- a/moonv4/moon_interface/moon_interface/api/perimeter.py
+++ /dev/null
@@ -1,312 +0,0 @@
-# Copyright 2015 Open Platform for NFV Project, Inc. and its contributors
-# This software is distributed under the terms and conditions of the 'Apache-2.0'
-# license which can be found in the file 'LICENSE' in this package distribution
-# or at 'http://www.apache.org/licenses/LICENSE-2.0'.
-"""
-* Subjects are the source of an action on an object (examples : users, virtual machines)
-* Objects are the destination of an action (examples virtual machines, virtual Routers)
-* Actions are what subject wants to do on an object
-"""
-
-from flask import request
-from flask_restful import Resource
-from oslo_log import log as logging
-from moon_utilities.security_functions import call
-from moon_utilities.security_functions import check_auth
-
-__version__ = "0.2.0"
-
-LOG = logging.getLogger("moon.interface.api." + __name__)
-
-
-class Subjects(Resource):
- """
- Endpoint for subjects requests
- """
-
- __urls__ = (
- "/subjects",
- "/subjects/",
- "/subjects/<string:perimeter_id>",
- "/policies/<string:uuid>/subjects",
- "/policies/<string:uuid>/subjects/",
- "/policies/<string:uuid>/subjects/<string:perimeter_id>",
- )
-
- @check_auth
- def get(self, uuid=None, perimeter_id=None, user_id=None):
- """Retrieve all subjects or a specific one if perimeter_id is given for a given policy
-
- :param uuid: uuid of the policy
- :param perimeter_id: uuid of the subject
- :param user_id: user ID who do the request
- :return: {
- "subject_id": {
- "name": "name of the subject",
- "keystone_id": "keystone id of the subject",
- "description": "a description"
- }
- }
- :internal_api: get_subjects
- """
- return call("security_router", ctx={"id": uuid, "method": "get_subjects", "user_id": user_id}, args={"perimeter_id": perimeter_id})
-
- @check_auth
- def post(self, uuid=None, perimeter_id=None, user_id=None):
- """Create or update a subject.
-
- :param uuid: uuid of the policy
- :param perimeter_id: must not be used here
- :param user_id: user ID who do the request
- :request body: {
- "name": "name of the subject",
- "description": "description of the subject",
- "password": "password for the subject",
- "email": "email address of the subject"
- }
- :return: {
- "subject_id": {
- "name": "name of the subject",
- "keystone_id": "keystone id of the subject",
- "description": "description of the subject",
- "password": "password for the subject",
- "email": "email address of the subject"
- }
- }
- :internal_api: set_subject
- """
- return call("security_router", ctx={"id": uuid, "method": "set_subject", "user_id": user_id, "perimeter_id": None},
- args=request.json)
-
- @check_auth
- def patch(self, uuid=None, perimeter_id=None, user_id=None):
- """Create or update a subject.
-
- :param uuid: uuid of the policy
- :param perimeter_id: must not be used here
- :param user_id: user ID who do the request
- :request body: {
- "name": "name of the subject",
- "description": "description of the subject",
- "password": "password for the subject",
- "email": "email address of the subject"
- }
- :return: {
- "subject_id": {
- "name": "name of the subject",
- "keystone_id": "keystone id of the subject",
- "description": "description of the subject",
- "password": "password for the subject",
- "email": "email address of the subject"
- }
- }
- :internal_api: set_subject
- """
- return call("security_router", ctx={"id": uuid, "method": "set_subject", "user_id": user_id, "perimeter_id": perimeter_id},
- args=request.json)
-
- @check_auth
- def delete(self, uuid=None, perimeter_id=None, user_id=None):
- """Delete a subject for a given policy
-
- :param uuid: uuid of the policy
- :param perimeter_id: uuid of the subject
- :param user_id: user ID who do the request
- :return: {
- "subject_id": {
- "name": "name of the subject",
- "keystone_id": "keystone id of the subject",
- "description": "description of the subject",
- "password": "password for the subject",
- "email": "email address of the subject"
- }
- }
- :internal_api: delete_subject
- """
- return call("security_router", ctx={"id": uuid, "method": "delete_subject", "user_id": user_id}, args={"perimeter_id": perimeter_id})
-
-
-class Objects(Resource):
- """
- Endpoint for objects requests
- """
-
- __urls__ = (
- "/objects",
- "/objects/",
- "/objects/<string:perimeter_id>",
- "/policies/<string:uuid>/objects",
- "/policies/<string:uuid>/objects/",
- "/policies/<string:uuid>/objects/<string:perimeter_id>",
- )
-
- @check_auth
- def get(self, uuid=None, perimeter_id=None, user_id=None):
- """Retrieve all objects or a specific one if perimeter_id is given for a given policy
-
- :param uuid: uuid of the policy
- :param perimeter_id: uuid of the object
- :param user_id: user ID who do the request
- :return: {
- "object_id": {
- "name": "name of the object",
- "description": "description of the object"
- }
- }
- :internal_api: get_objects
- """
- return call("security_router", ctx={"id": uuid, "method": "get_objects", "user_id": user_id}, args={"perimeter_id": perimeter_id})
-
- @check_auth
- def post(self, uuid=None, perimeter_id=None, user_id=None):
- """Create or update a object.
-
- :param uuid: uuid of the policy
- :param perimeter_id: must not be used here
- :param user_id: user ID who do the request
- :request body: {
- "object_name": "name of the object",
- "object_description": "description of the object"
- }
- :return: {
- "object_id": {
- "name": "name of the object",
- "description": "description of the object"
- }
- }
- :internal_api: set_object
- """
- return call("security_router", ctx={"id": uuid, "method": "set_object", "user_id": user_id, "perimeter_id": None},
- args=request.json)
-
- @check_auth
- def patch(self, uuid=None, perimeter_id=None, user_id=None):
- """Create or update a object.
-
- :param uuid: uuid of the policy
- :param perimeter_id: must not be used here
- :param user_id: user ID who do the request
- :request body: {
- "object_name": "name of the object",
- "object_description": "description of the object"
- }
- :return: {
- "object_id": {
- "name": "name of the object",
- "description": "description of the object"
- }
- }
- :internal_api: set_object
- """
- return call("security_router", ctx={"id": uuid, "method": "set_object", "user_id": user_id, "perimeter_id": perimeter_id},
- args=request.json)
-
- @check_auth
- def delete(self, uuid=None, perimeter_id=None, user_id=None):
- """Delete a object for a given policy
-
- :param uuid: uuid of the policy
- :param perimeter_id: uuid of the object
- :param user_id: user ID who do the request
- :return: {
- "object_id": {
- "name": "name of the object",
- "description": "description of the object"
- }
- }
- :internal_api: delete_object
- """
- return call("security_router", ctx={"id": uuid, "method": "delete_object", "user_id": user_id}, args={"perimeter_id": perimeter_id})
-
-
-class Actions(Resource):
- """
- Endpoint for actions requests
- """
-
- __urls__ = (
- "/actions",
- "/actions/",
- "/actions/<string:perimeter_id>",
- "/policies/<string:uuid>/actions",
- "/policies/<string:uuid>/actions/",
- "/policies/<string:uuid>/actions/<string:perimeter_id>",
- )
-
- @check_auth
- def get(self, uuid=None, perimeter_id=None, user_id=None):
- """Retrieve all actions or a specific one if perimeter_id is given for a given policy
-
- :param uuid: uuid of the policy
- :param perimeter_id: uuid of the action
- :param user_id: user ID who do the request
- :return: {
- "action_id": {
- "name": "name of the action",
- "description": "description of the action"
- }
- }
- :internal_api: get_actions
- """
- return call("security_router", ctx={"id": uuid, "method": "get_actions", "user_id": user_id}, args={"perimeter_id": perimeter_id})
-
- @check_auth
- def post(self, uuid=None, perimeter_id=None, user_id=None):
- """Create or update a action.
-
- :param uuid: uuid of the policy
- :param perimeter_id: must not be used here
- :param user_id: user ID who do the request
- :request body: {
- "name": "name of the action",
- "description": "description of the action"
- }
- :return: {
- "action_id": {
- "name": "name of the action",
- "description": "description of the action"
- }
- }
- :internal_api: set_action
- """
- return call("security_router", ctx={"id": uuid, "method": "set_action", "user_id": user_id, "perimeter_id": None},
- args=request.json)
-
- @check_auth
- def patch(self, uuid=None, perimeter_id=None, user_id=None):
- """Create or update a action.
-
- :param uuid: uuid of the policy
- :param perimeter_id: must not be used here
- :param user_id: user ID who do the request
- :request body: {
- "name": "name of the action",
- "description": "description of the action"
- }
- :return: {
- "action_id": {
- "name": "name of the action",
- "description": "description of the action"
- }
- }
- :internal_api: set_action
- """
- return call("security_router", ctx={"id": uuid, "method": "set_action", "user_id": user_id, "perimeter_id": perimeter_id},
- args=request.json)
-
- @check_auth
- def delete(self, uuid=None, perimeter_id=None, user_id=None):
- """Delete a action for a given policy
-
- :param uuid: uuid of the policy
- :param perimeter_id: uuid of the action
- :param user_id: user ID who do the request
- :return: {
- "action_id": {
- "name": "name of the action",
- "description": "description of the action"
- }
- }
- :internal_api: delete_action
- """
- return call("security_router", ctx={"id": uuid, "method": "delete_action", "user_id": user_id}, args={"perimeter_id": perimeter_id})
diff --git a/moonv4/moon_interface/moon_interface/api/policies.py b/moonv4/moon_interface/moon_interface/api/policies.py
deleted file mode 100644
index 5a84b612..00000000
--- a/moonv4/moon_interface/moon_interface/api/policies.py
+++ /dev/null
@@ -1,106 +0,0 @@
-# Copyright 2015 Open Platform for NFV Project, Inc. and its contributors
-# This software is distributed under the terms and conditions of the 'Apache-2.0'
-# license which can be found in the file 'LICENSE' in this package distribution
-# or at 'http://www.apache.org/licenses/LICENSE-2.0'.
-"""
-Policies are instances of security models and implement security policies
-
-"""
-
-from flask import request
-from flask_restful import Resource
-from oslo_log import log as logging
-from moon_utilities.security_functions import call
-from moon_utilities.security_functions import check_auth
-
-__version__ = "0.1.0"
-
-LOG = logging.getLogger("moon.interface.api." + __name__)
-
-
-class Policies(Resource):
- """
- Endpoint for policy requests
- """
-
- __urls__ = (
- "/policies",
- "/policies/",
- "/policies/<string:uuid>",
- "/policies/<string:uuid>/",
- )
-
- @check_auth
- def get(self, uuid=None, user_id=None):
- """Retrieve all policies
-
- :param uuid: uuid of the policy
- :param user_id: user ID who do the request
- :return: {
- "policy_id1": {
- "name": "...",
- "model_id": "...",
- "genre": "...",
- "description": "...",
- }
- }
- :internal_api: get_policies
- """
- return call("security_router", ctx={"id": uuid, "method": "get_policies", "user_id": user_id}, args={})
-
- @check_auth
- def post(self, uuid=None, user_id=None):
- """Create policy.
-
- :param uuid: uuid of the policy (not used here)
- :param user_id: user ID who do the request
- :request body: {
- "name": "...",
- "model_id": "...",
- "genre": "...",
- "description": "...",
- }
- :return: {
- "policy_id1": {
- "name": "...",
- "model_id": "...",
- "genre": "...",
- "description": "...",
- }
- }
- :internal_api: add_policy
- """
- return call("security_router", ctx={"id": uuid, "method": "add_policy", "user_id": user_id}, args=request.json)
-
- @check_auth
- def delete(self, uuid=None, user_id=None):
- """Delete a policy
-
- :param uuid: uuid of the policy to delete
- :param user_id: user ID who do the request
- :return: {
- "result": "True or False",
- "message": "optional message"
- }
- :internal_api: delete_policy
- """
- return call("security_router", ctx={"id": uuid, "method": "delete_policy", "user_id": user_id}, args={})
-
- @check_auth
- def patch(self, uuid=None, user_id=None):
- """Update a policy
-
- :param uuid: uuid of the policy to update
- :param user_id: user ID who do the request
- :return: {
- "policy_id1": {
- "name": "...",
- "model_id": "...",
- "genre": "...",
- "description": "...",
- }
- }
- :internal_api: update_policy
- """
- return call("security_router", ctx={"id": uuid, "method": "update_policy", "user_id": user_id}, args=request.json)
-
diff --git a/moonv4/moon_interface/moon_interface/api/rules.py b/moonv4/moon_interface/moon_interface/api/rules.py
deleted file mode 100644
index 1111729c..00000000
--- a/moonv4/moon_interface/moon_interface/api/rules.py
+++ /dev/null
@@ -1,114 +0,0 @@
-# Copyright 2015 Open Platform for NFV Project, Inc. and its contributors
-# This software is distributed under the terms and conditions of the 'Apache-2.0'
-# license which can be found in the file 'LICENSE' in this package distribution
-# or at 'http://www.apache.org/licenses/LICENSE-2.0'.
-"""
-Rules (TODO)
-"""
-
-from flask import request
-from flask_restful import Resource
-from oslo_log import log as logging
-from moon_utilities.security_functions import call
-from moon_utilities.security_functions import check_auth
-
-__version__ = "0.1.0"
-
-LOG = logging.getLogger("moon.interface.api." + __name__)
-
-
-class Rules(Resource):
- """
- Endpoint for rules requests
- """
-
- __urls__ = ("/policies/<string:uuid>/rules",
- "/policies/<string:uuid>/rules/",
- "/policies/<string:uuid>/rules/<string:rule_id>",
- "/policies/<string:uuid>/rules/<string:rule_id>/",
- )
-
- @check_auth
- def get(self, uuid=None, rule_id=None, user_id=None):
- """Retrieve all rules or a specific one
-
- :param uuid: policy ID
- :param rule_id: rule ID
- :param user_id: user ID who do the request
- :return: {
- "rules": [
- "policy_id": "policy_id1",
- "meta_rule_id": "meta_rule_id1",
- "rule_id1": ["subject_data_id1", "object_data_id1", "action_data_id1"],
- "rule_id2": ["subject_data_id2", "object_data_id2", "action_data_id2"],
- ]
- }
- :internal_api: get_rules
- """
- return call("security_router", ctx={"id": uuid,
- "method": "get_rules",
- "user_id": user_id,
- "rule_id": rule_id}, args={})
-
- @check_auth
- def post(self, uuid=None, rule_id=None, user_id=None):
- """Add a rule to a meta rule
-
- :param uuid: policy ID
- :param rule_id: rule ID
- :param user_id: user ID who do the request
- :request body: post = {
- "meta_rule_id": "meta_rule_id1",
- "rule": ["subject_data_id2", "object_data_id2", "action_data_id2"],
- "instructions": (
- {"decision": "grant"},
- )
- "enabled": True
- }
- :return: {
- "rules": [
- "meta_rule_id": "meta_rule_id1",
- "rule_id1": {
- "rule": ["subject_data_id1", "object_data_id1", "action_data_id1"],
- "instructions": (
- {"decision": "grant"}, # "grant" to immediately exit,
- # "continue" to wait for the result of next policy
- # "deny" to deny the request
- )
- }
- "rule_id2": {
- "rule": ["subject_data_id2", "object_data_id2", "action_data_id2"],
- "instructions": (
- {
- "update": {
- "operation": "add", # operations may be "add" or "delete"
- "target": "rbac:role:admin" # add the role admin to the current user
- }
- },
- {"chain": {"name": "rbac"}} # chain with the policy named rbac
- )
- }
- ]
- }
- :internal_api: add_rule
- """
- return call("security_router", ctx={"id": uuid,
- "method": "add_rule",
- "user_id": user_id,
- "rule_id": rule_id}, args=request.json)
-
- @check_auth
- def delete(self, uuid=None, rule_id=None, user_id=None):
- """Delete one rule linked to a specific sub meta rule
-
- :param uuid: policy ID
- :param rule_id: rule ID
- :param user_id: user ID who do the request
- :return: { "result": true }
- :internal_api: delete_rule
- """
- return call("security_router", ctx={"id": uuid,
- "method": "delete_rule",
- "user_id": user_id,
- "rule_id": rule_id}, args={})
-
diff --git a/moonv4/moon_interface/moon_interface/api/wrapper.py b/moonv4/moon_interface/moon_interface/api/wrapper.py
new file mode 100644
index 00000000..5ba5779f
--- /dev/null
+++ b/moonv4/moon_interface/moon_interface/api/wrapper.py
@@ -0,0 +1,120 @@
+# Copyright 2015 Open Platform for NFV Project, Inc. and its contributors
+# This software is distributed under the terms and conditions of the 'Apache-2.0'
+# license which can be found in the file 'LICENSE' in this package distribution
+# or at 'http://www.apache.org/licenses/LICENSE-2.0'.
+"""
+Authz is the endpoint to get authorization response
+"""
+
+import flask
+from flask import request
+from flask_restful import Resource
+import logging
+import json
+import requests
+import time
+from uuid import uuid4
+
+from moon_interface.api.authz import pdp_in_cache, pdp_in_manager, container_exist, \
+ create_containers, create_authz_request
+from moon_interface.authz_requests import AuthzRequest
+from moon_utilities import configuration
+
+__version__ = "0.1.0"
+
+LOG = logging.getLogger("moon.interface.api." + __name__)
+
+
+class Wrapper(Resource):
+ """
+ Endpoint for authz requests
+ """
+
+ __urls__ = (
+ "/authz/wrapper",
+ "/authz/wrapper/",
+ )
+
+ def __init__(self, **kwargs):
+ self.port = kwargs.get("port")
+ self.CACHE = kwargs.get("cache", {})
+ self.INTERFACE_NAME = kwargs.get("interface_name", "interface")
+ self.MANAGER_URL = kwargs.get("manager_url", "http://manager:8080")
+ self.TIMEOUT = 5
+
+ def get(self):
+ LOG.info("GET")
+ return self.manage_data()
+
+ def post(self):
+ LOG.info("POST {}".format(request.form))
+ response = flask.make_response("False")
+ if self.manage_data():
+ response = flask.make_response("True")
+ response.headers['content-type'] = 'application/octet-stream'
+ return response
+
+ @staticmethod
+ def __get_subject(target, credentials):
+ _subject = target.get("user_id", "")
+ if not _subject:
+ _subject = credentials.get("user_id", "none")
+ return _subject
+
+ @staticmethod
+ def __get_object(target, credentials):
+ try:
+ # note: case of Glance
+ return target['target']['name']
+ except KeyError:
+ pass
+
+ # note: default case
+ return target.get("project_id", "none")
+
+ @staticmethod
+ def __get_project_id(target, credentials):
+ return target.get("project_id", "none")
+
+ def manage_data(self):
+ target = json.loads(request.form.get('target', {}))
+ credentials = json.loads(request.form.get('credentials', {}))
+ rule = request.form.get('rule', "")
+ _subject = self.__get_subject(target, credentials)
+ _object = self.__get_object(target, credentials)
+ _project_id = self.__get_project_id(target, credentials)
+ LOG.info("GET with args project={} / "
+ "subject={} - object={} - action={}".format(
+ _project_id, _subject, _object, rule))
+ pdp_id, pdp_value = pdp_in_cache(self.CACHE, _project_id)
+ if not pdp_id:
+ pdp_id, pdp_value = pdp_in_manager(self.CACHE, _project_id)
+ if not pdp_id:
+ LOG.error("Unknown Project ID or "
+ "Project ID is not bind to a PDP.")
+ return False
+ if not container_exist(self.CACHE, _project_id):
+ create_containers(self.CACHE, _project_id, self.MANAGER_URL,
+ plugin_name="authz")
+ authz_request = create_authz_request(
+ cache=self.CACHE,
+ uuid=_project_id,
+ interface_name=self.INTERFACE_NAME,
+ manager_url=self.MANAGER_URL,
+ subject_name=_subject,
+ object_name=_object,
+ action_name=rule)
+ cpt = 0
+ while True:
+ LOG.info("Wait")
+ if cpt > self.TIMEOUT*10:
+ LOG.error("Authz request had timed out.")
+ return False
+ if authz_request.is_authz():
+ if authz_request.final_result == "Grant":
+ LOG.info("Grant")
+ return True
+ LOG.info("Deny")
+ return False
+ cpt += 1
+ time.sleep(0.1)
diff --git a/moonv4/moon_interface/moon_interface/authz_requests.py b/moonv4/moon_interface/moon_interface/authz_requests.py
new file mode 100644
index 00000000..2eb5fd19
--- /dev/null
+++ b/moonv4/moon_interface/moon_interface/authz_requests.py
@@ -0,0 +1,159 @@
+# Copyright 2015 Open Platform for NFV Project, Inc. and its contributors
+# This software is distributed under the terms and conditions of the 'Apache-2.0'
+# license which can be found in the file 'LICENSE' in this package distribution
+# or at 'http://www.apache.org/licenses/LICENSE-2.0'.
+
+import logging
+import itertools
+import pickle
+import requests
+from moon_utilities import configuration, exceptions
+from moon_utilities.security_functions import Context
+from moon_utilities.cache import Cache
+
+LOG = logging.getLogger("moon.interface.authz_requests")
+
+
+CACHE = Cache()
+CACHE.update()
+
+
+class AuthzRequest:
+
+ result = None
+ final_result = "Deny"
+ req_max_delay = 2
+
+ def __init__(self, ctx, args=None):
+ self.context = Context(ctx, CACHE)
+ self.args = args
+ self.request_id = ctx["request_id"]
+ if ctx['project_id'] not in CACHE.container_chaining:
+ raise exceptions.KeystoneProjectError("Unknown Project ID {}".format(ctx['project_id']))
+ self.container_chaining = CACHE.container_chaining[ctx['project_id']]
+ if len(self.container_chaining) == 0:
+ raise exceptions.MoonError('Void container chaining')
+ self.pdp_container = self.container_chaining[0]["container_id"]
+ self.run()
+
+ def run(self):
+ self.context.delete_cache()
+ try:
+ req = requests.post("http://{}:{}/authz".format(
+ self.container_chaining[0]["hostname"],
+ self.container_chaining[0]["port"],
+ ), data=pickle.dumps(self.context))
+ if req.status_code != 200:
+ # LOG.error("Cannot connect to {}".format(
+ # "http://{}:{}/authz".format(
+ # self.container_chaining[0]["hostname"],
+ # self.container_chaining[0]["port"]
+ # )))
+ raise exceptions.AuthzException(
+ "Receive bad response from Authz function "
+ "(with hostname - {})".format(
+ req.status_code
+ ))
+ except requests.exceptions.ConnectionError:
+ try:
+ req = requests.post("http://{}:{}/authz".format(
+ self.container_chaining[0]["hostip"],
+ self.container_chaining[0]["port"],
+ ), data=pickle.dumps(self.context))
+ if req.status_code != 200:
+ # LOG.error("req={}".format(req))
+ raise exceptions.AuthzException(
+ "Receive bad response from Authz function "
+ "(with IP address - {})".format(
+ req.status_code
+ ))
+ except requests.exceptions.ConnectionError:
+ LOG.error("Cannot connect to {}".format(
+ "http://{}:{}/authz".format(
+ self.container_chaining[0]["hostip"],
+ self.container_chaining[0]["port"]
+ )))
+ raise exceptions.AuthzException(
+ "Cannot connect to Authz function with IP address")
+ self.context.set_cache(CACHE)
+ if len(self.container_chaining) == 1:
+ # req.raw.decode_content = True
+ self.result = pickle.loads(req.content)
+
+ def __exec_next_state(self, rule_found):
+ index = self.context.index
+ current_meta_rule = self.context.headers[index]
+ current_container = self.__get_container_from_meta_rule(current_meta_rule)
+ current_container_genre = current_container["genre"]
+ try:
+ next_meta_rule = self.context.headers[index + 1]
+ except IndexError:
+ next_meta_rule = None
+ if current_container_genre == "authz":
+ if rule_found:
+ return True
+ pass
+ if next_meta_rule:
+ # next will be session if current is deny and session is unset
+ if self.payload["authz_context"]['pdp_set'][next_meta_rule]['effect'] == "unset":
+ return notify(
+ request_id=self.payload["authz_context"]["request_id"],
+ container_id=self.__get_container_from_meta_rule(next_meta_rule)['container_id'],
+ payload=self.payload)
+ # next will be delegation if current is deny and session is passed or deny and delegation is unset
+ else:
+ LOG.error("Delegation is not developed!")
+
+ else:
+ # else next will be None and the request is sent to router
+ return self.__return_to_router()
+ elif current_container_genre == "session":
+ pass
+ # next will be next container in headers if current is passed
+ if self.payload["authz_context"]['pdp_set'][current_meta_rule]['effect'] == "passed":
+ return notify(
+ request_id=self.payload["authz_context"]["request_id"],
+ container_id=self.__get_container_from_meta_rule(next_meta_rule)['container_id'],
+ payload=self.payload)
+ # next will be None if current is grant and the request is sent to router
+ else:
+ return self.__return_to_router()
+ elif current_container_genre == "delegation":
+ LOG.error("Delegation is not developed!")
+ # next will be authz if current is deny
+ # next will be None if current is grant and the request is sent to router
+
+ def set_result(self, result):
+ self.result = result
+
+ def is_authz(self):
+ if not self.result:
+ return False
+ authz_results = []
+ for key in self.result.pdp_set:
+ if "effect" in self.result.pdp_set[key]:
+ if self.result.pdp_set[key]["effect"] == "grant":
+ # the pdp is a authorization PDP and grant the request
+ authz_results.append(True)
+ elif self.result.pdp_set[key]["effect"] == "passed":
+ # the pdp is not a authorization PDP (session or delegation) and had run normally
+ authz_results.append(True)
+ elif self.result.pdp_set[key]["effect"] == "unset":
+ # the pdp is not a authorization PDP (session or delegation) and had not yep run
+ authz_results.append(True)
+ else:
+ # the pdp is (or not) a authorization PDP and had run badly
+ authz_results.append(False)
+ if list(itertools.accumulate(authz_results, lambda x, y: x & y))[-1]:
+ self.result.pdp_set["effect"] = "grant"
+ if self.result:
+ if self.result.pdp_set["effect"] == "grant":
+ self.final_result = "Grant"
+ return True
+ self.final_result = "Deny"
+ return True
+
+ # def notify(self, request_id, container_id, payload):
+ # LOG.info("notify {} {} {}".format(request_id, container_id, payload))
+ # # TODO: send the notification and wait for the result
+ # # req = requests.get()
diff --git a/moonv4/moon_interface/moon_interface/containers.py b/moonv4/moon_interface/moon_interface/containers.py
new file mode 100644
index 00000000..1ca76a2d
--- /dev/null
+++ b/moonv4/moon_interface/moon_interface/containers.py
@@ -0,0 +1,102 @@
+# Copyright 2017 Open Platform for NFV Project, Inc. and its contributors
+# This software is distributed under the terms and conditions of the 'Apache-2.0'
+# license which can be found in the file 'LICENSE' in this package distribution
+# or at 'http://www.apache.org/licenses/LICENSE-2.0'.
+
+import docker
+import logging
+import re
+import requests
+import time
+from moon_utilities import configuration, exceptions
+
+__version__ = "0.1.0"
+
+LOG = logging.getLogger("moon.interface.container")
+
+
+class DockerManager:
+
+ def __init__(self):
+ docker_conf = configuration.get_configuration("docker")['docker']
+ self.docker = docker.DockerClient(base_url=docker_conf['url'])
+
+ def create_container(self, data):
+ """Create the container through the docker client
+
+ :param data: {
+ "name": "authz",
+ "hostname": "authz123456789",
+ "port": {
+ "PrivatePort": 8090,
+ "Type": "tcp",
+ "IP": "0.0.0.0",
+ "PublicPort": 8090
+ },
+ "keystone_project_id": "keystone_project_id1",
+ "pdp_id": "123456789",
+ "container_name": "wukongsun/moon_authz:v4.1"
+ }
+ :return: container output
+ """
+ output = self.docker.containers.run(
+ image=data.get("container_name"),
+ hostname=data.get("hostname", data.get("name"))[:63],
+ name=data.get("name"),
+ network='moon',
+ ports={'{}/{}'.format(
+ data.get("port").get("PrivatePort"),
+ data.get("port").get("Type")
+ ): int(data.get("port").get("PrivatePort"))},
+ environment={
+ "UUID": data.get("hostname"),
+ "BIND": data.get("port").get("IP"),
+ "TYPE": data.get("plugin_name"),
+ "PORT": data.get("port").get("PrivatePort"),
+ "PDP_ID": data.get("pdp_id"),
+ "META_RULE_ID": data.get("meta_rule_id"),
+ "KEYSTONE_PROJECT_ID": data.get("keystone_project_id"),
+ },
+ detach=True
+ )
+ try:
+ req = requests.head("http://{}:{}/".format(data.get("hostname"), data.get("port").get("PublicPort")))
+ except requests.exceptions.ConnectionError:
+ pass
+ else:
+ if req.status_code != 200:
+ raise exceptions.DockerError("Container {} is not running!".format(data.get("hostname")))
+ output.ip = "0.0.0.0"
+ return output
+
+ # Note: host is not reachable through hostname so trying to find th IP address
+ res = output.exec_run("ip addr")
+ find = re.findall("inet (\d+\.\d+\.\d+\.\d+)", res.decode("utf-8"))
+ ip = "127.0.0.1"
+ for ip in find:
+ if ip.startswith("127"):
+ continue
+ break
+ cpt = 0
+ while True:
+ try:
+ req = requests.head("http://{}:{}/".format(ip, data.get("port").get("PublicPort")))
+ except requests.exceptions.ConnectionError:
+ pass
+ else:
+ if req.status_code not in (200, 201):
+ LOG.error("url={}".format("http://{}:{}/".format(ip, data.get("port").get("PublicPort"))))
+ LOG.error("req={}".format(req))
+ raise exceptions.DockerError("Container {} is not running!".format(data.get("hostname")))
+ output.ip = ip
+ return output
+ finally:
+ cpt += 1
+ time.sleep(0.1)
+ if cpt > 20:
+ break
+ output.ip = ip
+ return output
+
+ def delete_container(self, uuid):
+ raise NotImplementedError
diff --git a/moonv4/moon_interface/moon_interface/http_server.py b/moonv4/moon_interface/moon_interface/http_server.py
index 046337a2..d7f8469c 100644
--- a/moonv4/moon_interface/moon_interface/http_server.py
+++ b/moonv4/moon_interface/moon_interface/http_server.py
@@ -3,23 +3,16 @@
# license which can be found in the file 'LICENSE' in this package distribution
# or at 'http://www.apache.org/licenses/LICENSE-2.0'.
-from flask import Flask
+from flask import Flask, jsonify
from flask_cors import CORS, cross_origin
from flask_restful import Resource, Api
import logging
from moon_interface import __version__
from moon_interface.api.generic import Status, Logs, API
-from moon_interface.api.models import Models
-from moon_interface.api.policies import Policies
-from moon_interface.api.pdp import PDP
-from moon_interface.api.meta_rules import MetaRules
-from moon_interface.api.meta_data import SubjectCategories, ObjectCategories, ActionCategories
-from moon_interface.api.perimeter import Subjects, Objects, Actions
-from moon_interface.api.data import SubjectData, ObjectData, ActionData
-from moon_interface.api.assignments import SubjectAssignments, ObjectAssignments, ActionAssignments
-from moon_interface.api.rules import Rules
from moon_interface.api.authz import Authz
-from moon_utilities import exceptions
+from moon_interface.api.wrapper import Wrapper
+from moon_interface.authz_requests import CACHE
+from moon_utilities import configuration, exceptions
logger = logging.getLogger("moon.interface.http")
@@ -68,13 +61,7 @@ class Server:
raise NotImplementedError()
__API__ = (
- Status, Logs, API,
- MetaRules, SubjectCategories, ObjectCategories, ActionCategories,
- Subjects, Objects, Actions,
- SubjectAssignments, ObjectAssignments, ActionAssignments,
- SubjectData, ObjectData, ActionData,
- Rules, Authz,
- Models, Policies, PDP
+ Status, Logs, API
)
@@ -106,24 +93,28 @@ class HTTPServer(Server):
def __init__(self, host="localhost", port=80, **kwargs):
super(HTTPServer, self).__init__(host=host, port=port, **kwargs)
self.app = Flask(__name__)
+ self.port = port
+ conf = configuration.get_configuration("components/manager")
+ self.manager_hostname = conf["components/manager"].get("hostname", "manager")
+ self.manager_port = conf["components/manager"].get("port", 80)
#Todo : specify only few urls instead of *
CORS(self.app)
self.api = Api(self.app)
self.__set_route()
- # self.__hook_errors()
+ self.__hook_errors()
- @self.app.errorhandler(exceptions.AuthException)
- def _auth_exception(error):
- return {"error": "Unauthorized"}, 401
+ # @self.app.errorhandler(exceptions.AuthException)
+ # def _auth_exception(error):
+ # return {"error": "Unauthorized"}, 401
def __hook_errors(self):
- # FIXME (dthom): it doesn't work
+
def get_404_json(e):
- return {"error": "Error", "code": 404, "description": e}
+ return jsonify({"result": False, "code": 404, "description": str(e)}), 404
self.app.register_error_handler(404, get_404_json)
def get_400_json(e):
- return {"error": "Error", "code": 400, "description": e}
+ return jsonify({"result": False, "code": 400, "description": str(e)}), 400
self.app.register_error_handler(400, lambda e: get_400_json)
self.app.register_error_handler(403, exceptions.AuthException)
@@ -132,7 +123,23 @@ class HTTPServer(Server):
for api in __API__:
self.api.add_resource(api, *api.__urls__)
+ self.api.add_resource(Wrapper, *Wrapper.__urls__,
+ resource_class_kwargs={
+ "port": self.port,
+ "cache": CACHE,
+ "interface_name": self.host,
+ "manager_url": "http://{}:{}".format(self.manager_hostname, self.manager_port),
+ }
+ )
+ self.api.add_resource(Authz, *Authz.__urls__,
+ resource_class_kwargs={
+ "cache": CACHE,
+ "interface_name": self.host,
+ "manager_url": "http://{}:{}".format(self.manager_hostname, self.manager_port),
+ }
+ )
def run(self):
- self.app.run(debug=True, host=self._host, port=self._port) # nosec
+ self.app.run(host=self._host, port=self._port) # nosec
+ # self.app.run(debug=True, host=self._host, port=self._port) # nosec
diff --git a/moonv4/moon_interface/moon_interface/server.py b/moonv4/moon_interface/moon_interface/server.py
index 711aa00a..86274ec5 100644
--- a/moonv4/moon_interface/moon_interface/server.py
+++ b/moonv4/moon_interface/moon_interface/server.py
@@ -14,7 +14,6 @@ def main():
configuration.init_logging()
try:
conf = configuration.get_configuration("components/interface")
- LOG.debug("interface.conf={}".format(conf))
hostname = conf["components/interface"].get("hostname", "interface")
port = conf["components/interface"].get("port", 80)
bind = conf["components/interface"].get("bind", "127.0.0.1")
@@ -25,6 +24,8 @@ def main():
configuration.add_component(uuid="interface", name=hostname, port=port, bind=bind)
LOG.info("Starting server with IP {} on port {} bind to {}".format(hostname, port, bind))
server = HTTPServer(host=bind, port=port)
+ # LOG.info("Starting server")
+ # server = HTTPServer(host="0.0.0.0", port=8081)
server.run()
diff --git a/moonv4/moon_manager/moon_manager/api/containers.py b/moonv4/moon_manager/moon_manager/api/containers.py
new file mode 100644
index 00000000..44e7baac
--- /dev/null
+++ b/moonv4/moon_manager/moon_manager/api/containers.py
@@ -0,0 +1,179 @@
+# Copyright 2015 Open Platform for NFV Project, Inc. and its contributors
+# This software is distributed under the terms and conditions of the 'Apache-2.0'
+# license which can be found in the file 'LICENSE' in this package distribution
+# or at 'http://www.apache.org/licenses/LICENSE-2.0'.
+"""
+PDP are Policy Decision Point.
+
+"""
+
+import copy
+from docker import Client
+from flask import request
+from flask_restful import Resource
+from oslo_log import log as logging
+from moon_utilities.security_functions import check_auth
+from moon_db.core import PDPManager
+from moon_utilities import configuration, exceptions
+
+docker_conf = configuration.get_configuration("docker")['docker']
+docker = Client(base_url=docker_conf['url'])
+
+__version__ = "0.1.0"
+
+LOG = logging.getLogger("moon.manager.api." + __name__)
+
+
+class Container(Resource):
+ """
+ Endpoint for container requests
+ """
+
+ __urls__ = (
+ "/containers",
+ "/containers/",
+ "/containers/<string:uuid>",
+ "/containers/<string:uuid>/",
+ )
+
+ def __init__(self):
+ self.containers = {}
+ self.update()
+
+ def update(self):
+ for _container in docker.containers():
+ if _container['Id'] not in self.containers:
+ self.containers[_container['Id']] = {
+ "name": _container["Names"],
+ "port": _container["Ports"],
+ }
+
+ @check_auth
+ def get(self, uuid=None, user_id=None):
+ """Retrieve all containers
+
+ :param uuid: uuid of the container
+ :param user_id: user ID who do the request
+ :return: {
+ "containers": {
+ "da0fd80fc1dc146e1b...a2e07d240cde09f0a": {
+ "name": [
+ "/wrapper"
+ ],
+ "port": [
+ {
+ "PrivatePort": 8080,
+ "Type": "tcp",
+ "IP": "0.0.0.0",
+ "PublicPort": 8080
+ }
+ ]
+ },
+ }
+ }
+ :internal_api: get_containers
+ """
+ # try:
+ # data = [{"name": item["Names"], "port": item["Ports"], } for item in docker.containers()]
+ # except Exception as e:
+ # LOG.error(e, exc_info=True)
+ # return {"result": False,
+ # "error": str(e)}
+ return {"containers": self.containers}
+
+ @check_auth
+ def post(self, uuid=None, user_id=None):
+ """Add a new container.
+
+ :param uuid: uuid of the pdp (not used here)
+ :param user_id: user ID who do the request
+ :request body: {
+ "id": "id of the new container",
+ "name": "name of the new container",
+ "hostname": "hostname of the new container",
+ "port": {
+ "PrivatePort": 8080,
+ "Type": "tcp",
+ "IP": "0.0.0.0",
+ "PublicPort": 8080
+ },
+ "keystone_project_id": "keystone_project_id1",
+ "pdp_id": "PDP UUID",
+ "container_name": "wukongsun/moon_authz:v4.1"
+ }
+ :return: {
+ "containers": {
+ "da0fd80fc1dc146e1b...a2e07d240cde09f0a": {
+ "name": [
+ "/wrapper"
+ ],
+ "port": [
+ {
+ "PrivatePort": 8080,
+ "Type": "tcp",
+ "IP": "0.0.0.0",
+ "PublicPort": 8080
+ }
+ ]
+ },
+ }
+ }
+ :internal_api: add_container
+ """
+ try:
+ self.update()
+ self.containers[request.json.get('id')] = copy.deepcopy(request.json)
+ LOG.info("Added a new container {}".format(request.json.get('name')))
+ except Exception as e:
+ LOG.error(e, exc_info=True)
+ return {"result": False,
+ "error": str(e)}, 500
+ return {"containers": self.containers}
+
+ @check_auth
+ def delete(self, uuid=None, user_id=None):
+ """Delete a pdp
+
+ :param uuid: uuid of the pdp to delete
+ :param user_id: user ID who do the request
+ :return: {
+ "result": "True or False",
+ "message": "optional message"
+ }
+ :internal_api: delete_pdp
+ """
+ # try:
+ # data = PDPManager.delete_pdp(user_id=user_id, pdp_id=uuid)
+ # except Exception as e:
+ # LOG.error(e, exc_info=True)
+ # return {"result": False,
+ # "error": str(e)}
+ # return {"result": True}
+ raise NotImplementedError
+
+ @check_auth
+ def patch(self, uuid=None, user_id=None):
+ """Update a pdp
+
+ :param uuid: uuid of the pdp to update
+ :param user_id: user ID who do the request
+ :return: {
+ "pdp_id1": {
+ "name": "...",
+ "security_pipeline": [...],
+ "keystone_project_id": "keystone_project_id1",
+ "description": "...",
+ }
+ }
+ :internal_api: update_pdp
+ """
+ # try:
+ # data = PDPManager.update_pdp(user_id=user_id, pdp_id=uuid, value=request.json)
+ # add_container(uuid=uuid, pipeline=data[uuid]['security_pipeline'])
+ # except Exception as e:
+ # LOG.error(e, exc_info=True)
+ # return {"result": False,
+ # "error": str(e)}
+ # return {"pdps": data}
+ raise NotImplementedError
+
diff --git a/moonv4/moon_manager/moon_manager/http_server.py b/moonv4/moon_manager/moon_manager/http_server.py
index bdd429e4..a59921f0 100644
--- a/moonv4/moon_manager/moon_manager/http_server.py
+++ b/moonv4/moon_manager/moon_manager/http_server.py
@@ -18,6 +18,7 @@ from moon_manager.api.perimeter import Subjects, Objects, Actions
from moon_manager.api.data import SubjectData, ObjectData, ActionData
from moon_manager.api.assignments import SubjectAssignments, ObjectAssignments, ActionAssignments
from moon_manager.api.rules import Rules
+from moon_manager.api.containers import Container
from moon_utilities import configuration, exceptions
logger = logging.getLogger("moon.manager.http")
@@ -72,7 +73,7 @@ __API__ = (
Subjects, Objects, Actions,
SubjectAssignments, ObjectAssignments, ActionAssignments,
SubjectData, ObjectData, ActionData,
- Rules,
+ Rules, Container,
Models, Policies, PDP
)
diff --git a/moonv4/moon_manager/requirements.txt b/moonv4/moon_manager/requirements.txt
index e7be3d0e..6b2af70b 100644
--- a/moonv4/moon_manager/requirements.txt
+++ b/moonv4/moon_manager/requirements.txt
@@ -2,4 +2,5 @@ flask
flask_restful
flask_cors
moon_utilities
-moon_db \ No newline at end of file
+moon_db
+docker-py
diff --git a/moonv4/moon_utilities/Changelog b/moonv4/moon_utilities/Changelog
index e39a8b53..51a007c2 100644
--- a/moonv4/moon_utilities/Changelog
+++ b/moonv4/moon_utilities/Changelog
@@ -35,3 +35,7 @@ CHANGES
-----
- Add authentication features for interface
+1.3.0
+-----
+- Add cache functionality
+
diff --git a/moonv4/moon_utilities/build.sh b/moonv4/moon_utilities/build.sh
new file mode 100644
index 00000000..4c7db18d
--- /dev/null
+++ b/moonv4/moon_utilities/build.sh
@@ -0,0 +1,21 @@
+
+
+VERSION=moon_utilities-1.2.0
+
+python3 setup.py sdist bdist_wheel
+
+rm dist/*.asc
+
+gpg --detach-sign -u "A0A96E75" -a dist/${VERSION}-py3-none-any.whl
+gpg --detach-sign -u "A0A96E75" -a dist/${VERSION}.linux-x86_64.tar.gz
+
+if [ "$1" = "upload" ]; then
+ twine upload dist/${VERSION}-py3-none-any.whl dist/${VERSION}-py3-none-any.whl.asc
+ twine upload dist/${VERSION}.linux-x86_64.tar.gz dist/${VERSION}.linux-x86_64.tar.gz.asc
+fi
+
+cp dist/${VERSION}-py3-none-any.whl ../moon_orchestrator/dist/
+cp dist/${VERSION}-py3-none-any.whl ../moon_router/dist/
+cp dist/${VERSION}-py3-none-any.whl ../moon_interface/dist/
+cp dist/${VERSION}-py3-none-any.whl ../moon_manager/dist/
+cp dist/${VERSION}-py3-none-any.whl ../moon_authz/dist/
diff --git a/moonv4/moon_utilities/moon_utilities/__init__.py b/moonv4/moon_utilities/moon_utilities/__init__.py
index 2c7f8f5c..6e5782ce 100644
--- a/moonv4/moon_utilities/moon_utilities/__init__.py
+++ b/moonv4/moon_utilities/moon_utilities/__init__.py
@@ -3,4 +3,4 @@
# license which can be found in the file 'LICENSE' in this package distribution
# or at 'http://www.apache.org/licenses/LICENSE-2.0'.
-__version__ = "1.2.0"
+__version__ = "1.3.0"
diff --git a/moonv4/moon_utilities/moon_utilities/cache.py b/moonv4/moon_utilities/moon_utilities/cache.py
new file mode 100644
index 00000000..7c938b39
--- /dev/null
+++ b/moonv4/moon_utilities/moon_utilities/cache.py
@@ -0,0 +1,520 @@
+import logging
+import time
+import requests
+from uuid import uuid4
+from moon_utilities import configuration, exceptions
+
+LOG = logging.getLogger("moon.utilities.cache")
+
+
+class Cache(object):
+ # TODO (asteroide): set cache integer in CONF file
+ __UPDATE_INTERVAL = 10
+
+ __CONTAINERS = {}
+ __CONTAINERS_UPDATE = 0
+
+ __CONTAINER_CHAINING_UPDATE = 0
+ __CONTAINER_CHAINING = {}
+
+ __PDP = {}
+ __PDP_UPDATE = 0
+
+ __POLICIES = {}
+ __POLICIES_UPDATE = 0
+
+ __MODELS = {}
+ __MODELS_UPDATE = 0
+
+ __SUBJECTS = {}
+ __OBJECTS = {}
+ __ACTIONS = {}
+
+ __SUBJECT_ASSIGNMENTS = {}
+ __OBJECT_ASSIGNMENTS = {}
+ __ACTION_ASSIGNMENTS = {}
+
+ __SUBJECT_CATEGORIES = {}
+ __SUBJECT_CATEGORIES_UPDATE = 0
+ __OBJECT_CATEGORIES = {}
+ __OBJECT_CATEGORIES_UPDATE = 0
+ __ACTION_CATEGORIES = {}
+ __ACTION_CATEGORIES_UPDATE = 0
+
+ __META_RULES = {}
+ __META_RULES_UPDATE = 0
+
+ __RULES = {}
+ __RULES_UPDATE = 0
+
+ __AUTHZ_REQUESTS = {}
+
+
+ def __init__(self):
+ self.manager_url = "{}://{}:{}".format(
+ configuration.get_components()['manager'].get('protocol', 'http'),
+ configuration.get_components()['manager']['hostname'],
+ configuration.get_components()['manager']['port']
+ )
+ self.orchestrator_url = "{}://{}:{}".format(
+ configuration.get_components()['orchestrator'].get('protocol', 'http'),
+ configuration.get_components()['orchestrator']['hostname'],
+ configuration.get_components()['orchestrator']['port']
+ )
+
+ def update(self):
+ self.__update_container()
+ self.__update_pdp()
+ self.__update_policies()
+ self.__update_models()
+ for key, value in self.__PDP.items():
+ # LOG.info("Updating container_chaining with {}".format(value["keystone_project_id"]))
+ self.__update_container_chaining(value["keystone_project_id"])
+
+ @property
+ def authz_requests(self):
+ return self.__AUTHZ_REQUESTS
+
+ # perimeter functions
+
+ @property
+ def subjects(self):
+ return self.__SUBJECTS
+
+ def update_subjects(self, policy_id=None):
+ req = requests.get("{}/policies/{}/subjects".format(self.manager_url, policy_id))
+ self.__SUBJECTS[policy_id] = req.json()['subjects']
+
+ def get_subject(self, policy_id, name):
+ try:
+ for _subject_id, _subject_dict in self.__SUBJECTS[policy_id].items():
+ if _subject_dict["name"] == name:
+ return _subject_id
+ except KeyError:
+ pass
+ self.update_subjects(policy_id)
+ for _subject_id, _subject_dict in self.__SUBJECTS[policy_id].items():
+ if _subject_dict["name"] == name:
+ return _subject_id
+ raise exceptions.SubjectUnknown("Cannot find subject {}".format(name))
+
+ @property
+ def objects(self):
+ return self.__OBJECTS
+
+ def update_objects(self, policy_id=None):
+ req = requests.get("{}/policies/{}/objects".format(self.manager_url, policy_id))
+ self.__OBJECTS[policy_id] = req.json()['objects']
+
+ def get_object(self, policy_id, name):
+ try:
+ for _object_id, _object_dict in self.__OBJECTS[policy_id].items():
+ if _object_dict["name"] == name:
+ return _object_id
+ except KeyError:
+ pass
+ self.update_objects(policy_id)
+ for _object_id, _object_dict in self.__OBJECTS[policy_id].items():
+ if _object_dict["name"] == name:
+ return _object_id
+ raise exceptions.SubjectUnknown("Cannot find object {}".format(name))
+
+ @property
+ def actions(self):
+ return self.__ACTIONS
+
+ def update_actions(self, policy_id=None):
+ req = requests.get("{}/policies/{}/actions".format(self.manager_url, policy_id))
+ self.__ACTIONS[policy_id] = req.json()['actions']
+
+ def get_action(self, policy_id, name):
+ try:
+ for _action_id, _action_dict in self.__ACTIONS[policy_id].items():
+ if _action_dict["name"] == name:
+ return _action_id
+ except KeyError:
+ pass
+ self.update_actions(policy_id)
+ for _action_id, _action_dict in self.__ACTIONS[policy_id].items():
+ if _action_dict["name"] == name:
+ return _action_id
+ raise exceptions.SubjectUnknown("Cannot find action {}".format(name))
+
+ # meta_rule functions
+
+ @property
+ def meta_rules(self):
+ current_time = time.time()
+ if self.__META_RULES_UPDATE + self.__UPDATE_INTERVAL < current_time:
+ self.__update_meta_rules()
+ self.__META_RULES_UPDATE = current_time
+ return self.__META_RULES
+
+ def __update_meta_rules(self):
+ req = requests.get("{}/meta_rules".format(self.manager_url))
+ self.__META_RULES = req.json()['meta_rules']
+
+ # rule functions
+
+ @property
+ def rules(self):
+ current_time = time.time()
+ if self.__RULES_UPDATE + self.__UPDATE_INTERVAL < current_time:
+ self.__update_rules()
+ self.__RULES_UPDATE = current_time
+ return self.__RULES
+
+ def __update_rules(self):
+ for policy_id in self.__POLICIES:
+ LOG.info("Get {}".format("{}/policies/{}/rules".format(
+ self.manager_url, policy_id)))
+ req = requests.get("{}/policies/{}/rules".format(
+ self.manager_url, policy_id))
+ self.__RULES[policy_id] = req.json()['rules']
+ LOG.info("UPDATE RULES {}".format(self.__RULES))
+
+ # assignment functions
+
+ @property
+ def subject_assignments(self):
+ return self.__SUBJECT_ASSIGNMENTS
+
+ def update_subject_assignments(self, policy_id=None, perimeter_id=None):
+ if perimeter_id:
+ req = requests.get("{}/policies/{}/subject_assignments/{}".format(
+ self.manager_url, policy_id, perimeter_id))
+ else:
+ req = requests.get("{}/policies/{}/subject_assignments".format(self.manager_url, policy_id))
+ if policy_id not in self.__SUBJECT_ASSIGNMENTS:
+ self.__SUBJECT_ASSIGNMENTS[policy_id] = {}
+ self.__SUBJECT_ASSIGNMENTS[policy_id].update(req.json()['subject_assignments'])
+
+ def get_subject_assignments(self, policy_id, perimeter_id, category_id):
+ if policy_id not in self.subject_assignments:
+ self.update_subject_assignments(policy_id, perimeter_id)
+ if policy_id not in self.subject_assignments:
+ raise Exception("Cannot found the policy {}".format(policy_id))
+ for key, value in self.subject_assignments[policy_id].items():
+ if perimeter_id == value['subject_id'] and category_id == value['category_id']:
+ return value['assignments']
+ return []
+
+ @property
+ def object_assignments(self):
+ return self.__OBJECT_ASSIGNMENTS
+
+ def update_object_assignments(self, policy_id=None, perimeter_id=None):
+ if perimeter_id:
+ req = requests.get("{}/policies/{}/object_assignments/{}".format(
+ self.manager_url, policy_id, perimeter_id))
+ else:
+ req = requests.get("{}/policies/{}/object_assignments".format(self.manager_url, policy_id))
+ if policy_id not in self.__OBJECT_ASSIGNMENTS:
+ self.__OBJECT_ASSIGNMENTS[policy_id] = {}
+ self.__OBJECT_ASSIGNMENTS[policy_id].update(req.json()['object_assignments'])
+
+ def get_object_assignments(self, policy_id, perimeter_id, category_id):
+ if policy_id not in self.object_assignments:
+ self.update_object_assignments(policy_id, perimeter_id)
+ if policy_id not in self.object_assignments:
+ raise Exception("Cannot found the policy {}".format(policy_id))
+ for key, value in self.object_assignments[policy_id].items():
+ if perimeter_id == value['object_id'] and category_id == value['category_id']:
+ return value['assignments']
+ return []
+
+ @property
+ def action_assignments(self):
+ return self.__ACTION_ASSIGNMENTS
+
+ def update_action_assignments(self, policy_id=None, perimeter_id=None):
+ if perimeter_id:
+ req = requests.get("{}/policies/{}/action_assignments/{}".format(
+ self.manager_url, policy_id, perimeter_id))
+ else:
+ req = requests.get("{}/policies/{}/action_assignments".format(self.manager_url, policy_id))
+ if policy_id not in self.__ACTION_ASSIGNMENTS:
+ self.__ACTION_ASSIGNMENTS[policy_id] = {}
+ self.__ACTION_ASSIGNMENTS[policy_id].update(req.json()['action_assignments'])
+
+ def get_action_assignments(self, policy_id, perimeter_id, category_id):
+ if policy_id not in self.action_assignments:
+ self.update_action_assignments(policy_id, perimeter_id)
+ if policy_id not in self.action_assignments:
+ raise Exception("Cannot found the policy {}".format(policy_id))
+ for key, value in self.action_assignments[policy_id].items():
+ if perimeter_id == value['action_id'] and category_id == value['category_id']:
+ return value['assignments']
+ return []
+
+ # category functions
+
+ @property
+ def subject_categories(self):
+ current_time = time.time()
+ if self.__SUBJECT_CATEGORIES_UPDATE + self.__UPDATE_INTERVAL < current_time:
+ self.__update_subject_categories()
+ self.__SUBJECT_CATEGORIES_UPDATE = current_time
+ return self.__SUBJECT_CATEGORIES
+
+ def __update_subject_categories(self):
+ req = requests.get("{}/policies/subject_categories".format(
+ self.manager_url))
+ self.__SUBJECT_CATEGORIES.update(req.json()['subject_categories'])
+
+ @property
+ def object_categories(self):
+ current_time = time.time()
+ if self.__OBJECT_CATEGORIES_UPDATE + self.__UPDATE_INTERVAL < current_time:
+ self.__update_object_categories()
+ self.__OBJECT_CATEGORIES_UPDATE = current_time
+ return self.__OBJECT_CATEGORIES
+
+ def __update_object_categories(self):
+ req = requests.get("{}/policies/object_categories".format(
+ self.manager_url))
+ self.__OBJECT_CATEGORIES.update(req.json()['object_categories'])
+
+ @property
+ def action_categories(self):
+ current_time = time.time()
+ if self.__ACTION_CATEGORIES_UPDATE + self.__UPDATE_INTERVAL < current_time:
+ self.__update_action_categories()
+ self.__ACTION_CATEGORIES_UPDATE = current_time
+ return self.__ACTION_CATEGORIES
+
+ def __update_action_categories(self):
+ req = requests.get("{}/policies/action_categories".format(
+ self.manager_url))
+ self.__ACTION_CATEGORIES.update(req.json()['action_categories'])
+
+ # PDP functions
+
+ def __update_pdp(self):
+ req = requests.get("{}/pdp".format(self.manager_url))
+ pdp = req.json()
+ for _pdp in pdp["pdps"].values():
+ if _pdp['keystone_project_id'] not in self.__CONTAINER_CHAINING:
+ self.__CONTAINER_CHAINING[_pdp['keystone_project_id']] = {}
+ # Note (asteroide): force update of chaining
+ self.__update_container_chaining(_pdp['keystone_project_id'])
+ for key, value in pdp["pdps"].items():
+ self.__PDP[key] = value
+
+ @property
+ def pdp(self):
+ """Policy Decision Point
+ Example of content:
+ {
+ "pdp_id": {
+ "keystone_project_id": "keystone_project_id",
+ "name": "pdp1",
+ "description": "test",
+ "security_pipeline": [
+ "policy_id"
+ ]
+ }
+ }
+
+ :return:
+ """
+ current_time = time.time()
+ if self.__PDP_UPDATE + self.__UPDATE_INTERVAL < current_time:
+ self.__update_pdp()
+ self.__PDP_UPDATE = current_time
+ return self.__PDP
+
+ # policy functions
+ def __update_policies(self):
+ req = requests.get("{}/policies".format(self.manager_url))
+ policies = req.json()
+ for key, value in policies["policies"].items():
+ self.__POLICIES[key] = value
+
+ @property
+ def policies(self):
+ current_time = time.time()
+ if self.__POLICIES_UPDATE + self.__UPDATE_INTERVAL < current_time:
+ self.__update_policies()
+ self.__POLICIES_UPDATE = current_time
+ return self.__POLICIES
+
+ # model functions
+
+ def __update_models(self):
+ req = requests.get("{}/models".format(self.manager_url))
+ models = req.json()
+ for key, value in models["models"].items():
+ self.__MODELS[key] = value
+
+ @property
+ def models(self):
+ current_time = time.time()
+ if self.__MODELS_UPDATE + self.__UPDATE_INTERVAL < current_time:
+ self.__update_models()
+ self.__MODELS_UPDATE = current_time
+ return self.__MODELS
+
+ # helper functions
+
+ def get_policy_from_meta_rules(self, meta_rule_id):
+ for pdp_key, pdp_value in self.pdp.items():
+ for policy_id in pdp_value["security_pipeline"]:
+ model_id = self.policies[policy_id]["model_id"]
+ if meta_rule_id in self.models[model_id]["meta_rules"]:
+ return policy_id
+
+ def get_pdp_from_keystone_project(self, keystone_project_id):
+ for pdp_key, pdp_value in self.pdp.items():
+ if keystone_project_id == pdp_value["keystone_project_id"]:
+ return pdp_key
+
+ def get_keystone_project_id_from_policy_id(self, policy_id):
+ for pdp_key, pdp_value in self.pdp.items():
+ if policy_id in pdp_value["security_pipeline"]:
+ return pdp_value["keystone_project_id"]
+ # for policy_id in pdp_value["security_pipeline"]:
+ # model_id = self.policies[policy_id]["model_id"]
+ # if meta_rule_id in self.models[model_id]["meta_rules"]:
+ # return pdp_value["keystone_project_id"]
+
+ def get_containers_from_keystone_project_id(self, keystone_project_id, meta_rule_id=None):
+ for container_id, container_value in self.containers.items():
+ if 'keystone_project_id' not in container_value:
+ continue
+ if container_value['keystone_project_id'] == keystone_project_id:
+ if not meta_rule_id:
+ yield container_id, container_value
+ elif container_value['meta_rule_id'] == meta_rule_id:
+ yield container_id, container_value
+ break
+
+ # containers functions
+
+ def __update_container(self):
+ req = requests.get("{}/containers".format(self.manager_url))
+ containers = req.json()
+ for key, value in containers["containers"].items():
+ if key not in self.__CONTAINERS:
+ self.__CONTAINERS[key] = value
+ else:
+ self.__CONTAINERS[key].update(value)
+
+ def add_container(self, container_data):
+ """Add a new container in the cache
+
+ :param container_data: dictionary with information for the container
+ Example:
+ {
+ "name": name,
+ "hostname": name,
+ "port": {
+ "PrivatePort": tcp_port,
+ "Type": "tcp",
+ "IP": "0.0.0.0",
+ "PublicPort": tcp_port
+ },
+ "keystone_project_id": uuid,
+ "pdp_id": self.CACHE.get_pdp_from_keystone_project(uuid),
+ "meta_rule_id": meta_rule_id,
+ "container_name": container_name,
+ "plugin_name": plugin_name
+ "container_id": "container_id"
+ }
+
+ :return:
+ """
+ self.__CONTAINERS[uuid4().hex] = {
+ "keystone_project_id": container_data['keystone_project_id'],
+ "name": container_data['name'],
+ "container_id": container_data['container_id'],
+ "hostname": container_data['name'],
+ "policy_id": container_data['policy_id'],
+ "meta_rule_id": container_data['meta_rule_id'],
+ "port": [
+ {
+ "PublicPort": container_data['port']["PublicPort"],
+ "Type": container_data['port']["Type"],
+ "IP": container_data['port']["IP"],
+ "PrivatePort": container_data['port']["PrivatePort"]
+ }
+ ],
+ "genre": container_data['plugin_name']
+ }
+ self.__update_container_chaining(self.get_keystone_project_id_from_policy_id(container_data['policy_id']))
+
+ @property
+ def containers(self):
+ """Containers cache
+ example of content :
+ {
+ "policy_uuid1": "component_hostname1",
+ "policy_uuid2": "component_hostname2",
+ }
+ :return:
+ """
+ current_time = time.time()
+ if self.__CONTAINERS_UPDATE + self.__UPDATE_INTERVAL < current_time:
+ self.__update_container()
+ self.__CONTAINERS_UPDATE = current_time
+ return self.__CONTAINERS
+
+ @property
+ def container_chaining(self):
+ """Cache for mapping Keystone Project ID with meta_rule ID and container ID
+ Example of content:
+ {
+ "keystone_project_id": [
+ {
+ "container_id": "container_id",
+ "genre": "genre",
+ "policy_id": "policy_id",
+ "meta_rule_id": "meta_rule_id",
+ }
+ ]
+ }
+
+ :return:
+ """
+ current_time = time.time()
+ if self.__CONTAINER_CHAINING_UPDATE + self.__UPDATE_INTERVAL < current_time:
+ for key, value in self.pdp.items():
+ self.__update_container_chaining(value["keystone_project_id"])
+ self.__CONTAINER_CHAINING_UPDATE = current_time
+ LOG.info(self.__CONTAINER_CHAINING_UPDATE)
+ return self.__CONTAINER_CHAINING
+
+ def __update_container_chaining(self, keystone_project_id):
+ container_ids = []
+ for pdp_id, pdp_value, in self.__PDP.items():
+ # LOG.info("pdp_id, pdp_value = {}, {}".format(pdp_id, pdp_value))
+ # LOG.info("__POLICIES = {}".format(self.__POLICIES))
+ if pdp_value:
+ if pdp_value["keystone_project_id"] == keystone_project_id:
+ for policy_id in pdp_value["security_pipeline"]:
+ model_id = self.__POLICIES[policy_id]['model_id']
+ # LOG.info("model_id = {}".format(model_id))
+ # LOG.info("CACHE = {}".format(self.__MODELS[model_id]))
+ # LOG.info("CACHE.containers = {}".format(self.__CONTAINERS))
+ # LOG.info("CACHE.models = {}".format(self.__MODELS))
+ for meta_rule_id in self.__MODELS[model_id]["meta_rules"]:
+ # LOG.info("meta_rule = {}".format(self.__MODELS[model_id]["meta_rules"]))
+ for container_id, container_value in self.get_containers_from_keystone_project_id(
+ keystone_project_id,
+ meta_rule_id
+ ):
+ # LOG.info("CONTAINER: {} {}".format(container_id, container_value))
+ container_ids.append(
+ {
+ "container_id": self.__CONTAINERS[container_id]["container_id"],
+ "genre": self.__CONTAINERS[container_id]["genre"],
+ "policy_id": policy_id,
+ "meta_rule_id": meta_rule_id,
+ "hostname": self.__CONTAINERS[container_id]["hostname"],
+ "hostip": self.__CONTAINERS[container_id]["port"][0]["IP"],
+ "port": self.__CONTAINERS[container_id]["port"][0]["PublicPort"],
+ }
+ )
+ # LOG.info("__update_container_chaining={}".format(container_ids))
+ self.__CONTAINER_CHAINING[keystone_project_id] = container_ids
+
diff --git a/moonv4/moon_utilities/moon_utilities/configuration.py b/moonv4/moon_utilities/moon_utilities/configuration.py
index 32eeff13..d1c5545f 100644
--- a/moonv4/moon_utilities/moon_utilities/configuration.py
+++ b/moonv4/moon_utilities/moon_utilities/configuration.py
@@ -53,8 +53,8 @@ def get_configuration(key):
url = "http://{}:{}/v1/kv/{}".format(CONSUL_HOST, CONSUL_PORT, key)
req = requests.get(url)
if req.status_code != 200:
- LOG.info("url={}".format(url))
- raise exceptions.ConsulComponentNotFound
+ LOG.error("url={}".format(url))
+ raise exceptions.ConsulComponentNotFound("error={}: {}".format(req.status_code, req.text))
data = req.json()
if len(data) == 1:
data = data[0]
diff --git a/moonv4/moon_utilities/moon_utilities/get_os_apis.py b/moonv4/moon_utilities/moon_utilities/get_os_apis.py
index dea2a878..d019c1cd 100644
--- a/moonv4/moon_utilities/moon_utilities/get_os_apis.py
+++ b/moonv4/moon_utilities/moon_utilities/get_os_apis.py
@@ -1,4 +1,5 @@
import json
+import yaml
import logging
import requests
import argparse
@@ -26,6 +27,7 @@ def init():
parser.add_argument("--debug", "-d", action='store_true', help="debug mode")
parser.add_argument("--format", "-f", help="Output format (txt, json)", default="json")
parser.add_argument("--output", "-o", help="Output filename")
+ parser.add_argument("--from-policies", "-p", help="Get API from policy.{json,yaml}", target="policies")
parser.add_argument("--credentials", "-c", help="Github credential filename (inside format user:pass)")
args = parser.parse_args()
@@ -98,6 +100,13 @@ def to_str(results):
return output
+def get_data_from_policies(policies):
+ for filename in policies.split(","):
+ try:
+ obj = json.loads(open(filename.strip()).read())
+
+
+
def save(results, args):
if args.output:
if args.format == 'json':
@@ -114,8 +123,11 @@ def save(results, args):
def main():
args = init()
results = {}
- for key in URLS:
- results[key] = get_content(key, args)
+ if not args.policies:
+ for key in URLS:
+ results[key] = get_content(key, args)
+ else:
+ get_data_from_policies(args.policies)
save(results, args)
if __name__ == "__main__":
diff --git a/moonv4/moon_utilities/moon_utilities/security_functions.py b/moonv4/moon_utilities/moon_utilities/security_functions.py
index ad1a44fa..98935996 100644
--- a/moonv4/moon_utilities/moon_utilities/security_functions.py
+++ b/moonv4/moon_utilities/moon_utilities/security_functions.py
@@ -209,59 +209,90 @@ def call(endpoint="security_router", ctx=None, method="route", **kwargs):
class Context:
- def __init__(self, _keystone_project_id, _subject, _object, _action, _request_id):
- from moon_db.core import PDPManager, ModelManager, PolicyManager
- self.PolicyManager = PolicyManager
- self.ModelManager = ModelManager
- self.PDPManager = PDPManager
- self.__keystone_project_id = _keystone_project_id
+ def __init__(self, init_context, cache):
+ self.cache = cache
+ self.__keystone_project_id = init_context.get("project_id")
self.__pdp_id = None
self.__pdp_value = None
- for _pdp_key, _pdp_value in PDPManager.get_pdp("admin").items():
- if _pdp_value["keystone_project_id"] == _keystone_project_id:
+ for _pdp_key, _pdp_value in self.cache.pdp.items():
+ if _pdp_value["keystone_project_id"] == self.__keystone_project_id:
self.__pdp_id = _pdp_key
self.__pdp_value = copy.deepcopy(_pdp_value)
break
- self.__subject = _subject
- self.__object = _object
- self.__action = _action
+ if not self.__pdp_value:
+ raise exceptions.AuthzException(
+ "Cannot create context for authz "
+ "with Keystone project ID {}".format(
+ self.__keystone_project_id
+ ))
+ self.__subject = init_context.get("subject_name")
+ self.__object = init_context.get("object_name")
+ self.__action = init_context.get("action_name")
self.__current_request = None
- self.__request_id = _request_id
- self.__index = 0
- self.__init_initial_request()
+ self.__request_id = init_context.get("req_id")
+ self.__cookie = init_context.get("cookie")
+ self.__manager_url = init_context.get("manager_url")
+ self.__interface_name = init_context.get("interface_name")
+ self.__index = -1
+ # self.__init_initial_request()
self.__headers = []
- policies = PolicyManager.get_policies("admin")
- models = ModelManager.get_models("admin")
+ policies = self.cache.policies
+ models = self.cache.models
for policy_id in self.__pdp_value["security_pipeline"]:
model_id = policies[policy_id]["model_id"]
for meta_rule in models[model_id]["meta_rules"]:
self.__headers.append(meta_rule)
- self.__meta_rules = ModelManager.get_meta_rules("admin")
+ self.__meta_rules = self.cache.meta_rules
self.__pdp_set = {}
+ # self.__init_pdp_set()
+
+ def delete_cache(self):
+ self.cache = {}
+
+ def set_cache(self, cache):
+ self.cache = cache
+
+ def increment_index(self):
+ self.__index += 1
+ self.__init_current_request()
self.__init_pdp_set()
- def __init_initial_request(self):
- subjects = self.PolicyManager.get_subjects("admin", policy_id=None)
- for _subject_id, _subject_dict in subjects.items():
- if _subject_dict["name"] == self.__subject:
- self.__subject = _subject_id
- break
- else:
- raise exceptions.SubjectUnknown("Cannot find subject {}".format(self.__subject))
- objects = self.PolicyManager.get_objects("admin", policy_id=None)
- for _object_id, _object_dict in objects.items():
- if _object_dict["name"] == self.__object:
- self.__object = _object_id
- break
- else:
- raise exceptions.ObjectUnknown("Cannot find object {}".format(self.__object))
- actions = self.PolicyManager.get_actions("admin", policy_id=None)
- for _action_id, _action_dict in actions.items():
- if _action_dict["name"] == self.__action:
- self.__action = _action_id
- break
- else:
- raise exceptions.ActionUnknown("Cannot find action {}".format(self.__action))
+ @property
+ def current_state(self):
+ return self.__pdp_set[self.__headers[self.__index]]['effect']
+
+ @current_state.setter
+ def current_state(self, state):
+ if state not in ("grant", "deny", "passed"):
+ state = "passed"
+ self.__pdp_set[self.__headers[self.__index]]['effect'] = state
+
+ @current_state.deleter
+ def current_state(self):
+ self.__pdp_set[self.__headers[self.__index]]['effect'] = "unset"
+
+ @property
+ def current_policy_id(self):
+ return self.__pdp_value["security_pipeline"][self.__index]
+
+ @current_policy_id.setter
+ def current_policy_id(self, value):
+ pass
+
+ @current_policy_id.deleter
+ def current_policy_id(self):
+ pass
+
+ def __init_current_request(self):
+ self.__subject = self.cache.get_subject(
+ self.__pdp_value["security_pipeline"][self.__index],
+ self.__subject)
+ self.__object = self.cache.get_object(
+ self.__pdp_value["security_pipeline"][self.__index],
+ self.__object)
+ self.__action = self.cache.get_action(
+ self.__pdp_value["security_pipeline"][self.__index],
+ self.__action)
self.__current_request = dict(self.initial_request)
def __init_pdp_set(self):
@@ -269,67 +300,64 @@ class Context:
self.__pdp_set[header] = dict()
self.__pdp_set[header]["meta_rules"] = self.__meta_rules[header]
self.__pdp_set[header]["target"] = self.__add_target(header)
- # TODO (asteroide): the following information must be retrieve somewhere
self.__pdp_set[header]["effect"] = "unset"
self.__pdp_set["effect"] = "deny"
- @staticmethod
- def update_target(context):
- from moon_db.core import PDPManager, ModelManager, PolicyManager
- # result = dict()
- current_request = context['current_request']
- _subject = current_request.get("subject")
- _object = current_request.get("object")
- _action = current_request.get("action")
- meta_rule_id = context['headers'][context['index']]
- policy_id = PolicyManager.get_policy_from_meta_rules("admin", meta_rule_id)
- meta_rules = ModelManager.get_meta_rules("admin")
- # for meta_rule_id in meta_rules:
- for sub_cat in meta_rules[meta_rule_id]['subject_categories']:
- if sub_cat not in context["pdp_set"][meta_rule_id]["target"]:
- context["pdp_set"][meta_rule_id]["target"][sub_cat] = []
- for assign in PolicyManager.get_subject_assignments("admin", policy_id, _subject, sub_cat).values():
- for assign in assign["assignments"]:
- if assign not in context["pdp_set"][meta_rule_id]["target"][sub_cat]:
- context["pdp_set"][meta_rule_id]["target"][sub_cat].append(assign)
- for obj_cat in meta_rules[meta_rule_id]['object_categories']:
- if obj_cat not in context["pdp_set"][meta_rule_id]["target"]:
- context["pdp_set"][meta_rule_id]["target"][obj_cat] = []
- for assign in PolicyManager.get_object_assignments("admin", policy_id, _object, obj_cat).values():
- for assign in assign["assignments"]:
- if assign not in context["pdp_set"][meta_rule_id]["target"][obj_cat]:
- context["pdp_set"][meta_rule_id]["target"][obj_cat].append(assign)
- for act_cat in meta_rules[meta_rule_id]['action_categories']:
- if act_cat not in context["pdp_set"][meta_rule_id]["target"]:
- context["pdp_set"][meta_rule_id]["target"][act_cat] = []
- for assign in PolicyManager.get_action_assignments("admin", policy_id, _action, act_cat).values():
- for assign in assign["assignments"]:
- if assign not in context["pdp_set"][meta_rule_id]["target"][act_cat]:
- context["pdp_set"][meta_rule_id]["target"][act_cat].append(assign)
- # context["pdp_set"][meta_rule_id]["target"].update(result)
+ # def update_target(self, context):
+ # # result = dict()
+ # current_request = context['current_request']
+ # _subject = current_request.get("subject")
+ # _object = current_request.get("object")
+ # _action = current_request.get("action")
+ # meta_rule_id = context['headers'][context['index']]
+ # policy_id = self.cache.get_policy_from_meta_rules(meta_rule_id)
+ # meta_rules = self.cache.meta_rules()
+ # # for meta_rule_id in meta_rules:
+ # for sub_cat in meta_rules[meta_rule_id]['subject_categories']:
+ # if sub_cat not in context["pdp_set"][meta_rule_id]["target"]:
+ # context["pdp_set"][meta_rule_id]["target"][sub_cat] = []
+ # for assign in self.cache.get_subject_assignments(policy_id, _subject, sub_cat).values():
+ # for assign in assign["assignments"]:
+ # if assign not in context["pdp_set"][meta_rule_id]["target"][sub_cat]:
+ # context["pdp_set"][meta_rule_id]["target"][sub_cat].append(assign)
+ # for obj_cat in meta_rules[meta_rule_id]['object_categories']:
+ # if obj_cat not in context["pdp_set"][meta_rule_id]["target"]:
+ # context["pdp_set"][meta_rule_id]["target"][obj_cat] = []
+ # for assign in self.cache.get_object_assignments(policy_id, _object, obj_cat).values():
+ # for assign in assign["assignments"]:
+ # if assign not in context["pdp_set"][meta_rule_id]["target"][obj_cat]:
+ # context["pdp_set"][meta_rule_id]["target"][obj_cat].append(assign)
+ # for act_cat in meta_rules[meta_rule_id]['action_categories']:
+ # if act_cat not in context["pdp_set"][meta_rule_id]["target"]:
+ # context["pdp_set"][meta_rule_id]["target"][act_cat] = []
+ # for assign in self.cache.get_action_assignments(policy_id, _action, act_cat).values():
+ # for assign in assign["assignments"]:
+ # if assign not in context["pdp_set"][meta_rule_id]["target"][act_cat]:
+ # context["pdp_set"][meta_rule_id]["target"][act_cat].append(assign)
+ # # context["pdp_set"][meta_rule_id]["target"].update(result)
def __add_target(self, meta_rule_id):
result = dict()
_subject = self.__current_request["subject"]
_object = self.__current_request["object"]
_action = self.__current_request["action"]
- meta_rules = self.ModelManager.get_meta_rules("admin")
- policy_id = self.PolicyManager.get_policy_from_meta_rules("admin", meta_rule_id)
+ meta_rules = self.cache.meta_rules
+ policy_id = self.cache.get_policy_from_meta_rules(meta_rule_id)
for sub_cat in meta_rules[meta_rule_id]['subject_categories']:
if sub_cat not in result:
result[sub_cat] = []
- for assign in self.PolicyManager.get_subject_assignments("admin", policy_id, _subject, sub_cat).values():
- result[sub_cat].extend(assign["assignments"])
+ result[sub_cat].extend(
+ self.cache.get_subject_assignments(policy_id, _subject, sub_cat))
for obj_cat in meta_rules[meta_rule_id]['object_categories']:
if obj_cat not in result:
result[obj_cat] = []
- for assign in self.PolicyManager.get_object_assignments("admin", policy_id, _object, obj_cat).values():
- result[obj_cat].extend(assign["assignments"])
+ result[obj_cat].extend(
+ self.cache.get_object_assignments(policy_id, _object, obj_cat))
for act_cat in meta_rules[meta_rule_id]['action_categories']:
if act_cat not in result:
result[act_cat] = []
- for assign in self.PolicyManager.get_action_assignments("admin", policy_id, _action, act_cat).values():
- result[act_cat].extend(assign["assignments"])
+ result[act_cat].extend(
+ self.cache.get_action_assignments(policy_id, _action, act_cat))
return result
def __repr__(self):
@@ -356,6 +384,8 @@ pdp_set: {pdp_set}
"index": copy.deepcopy(self.__index),
"pdp_set": copy.deepcopy(self.__pdp_set),
"request_id": copy.deepcopy(self.__request_id),
+ "manager_url": copy.deepcopy(self.__manager_url),
+ "interface_name": copy.deepcopy(self.__interface_name),
}
@property
@@ -371,6 +401,42 @@ pdp_set: {pdp_set}
raise Exception("You cannot update the request_id")
@property
+ def manager_url(self):
+ return self.__manager_url
+
+ @manager_url.setter
+ def manager_url(self, value):
+ raise Exception("You cannot update the manager_url")
+
+ @manager_url.deleter
+ def manager_url(self):
+ raise Exception("You cannot update the manager_url")
+
+ @property
+ def interface_name(self):
+ return self.__interface_name
+
+ @interface_name.setter
+ def interface_name(self, value):
+ raise Exception("You cannot update the interface_name")
+
+ @interface_name.deleter
+ def interface_name(self):
+ raise Exception("You cannot update the interface_name")
+
+ @property
+ def cookie(self):
+ return self.__cookie
+
+ @cookie.setter
+ def cookie(self, value):
+ raise Exception("You cannot update the cookie")
+
+ @cookie.deleter
+ def cookie(self):
+ raise Exception("You cannot delete the cookie")
+
+ @property
def initial_request(self):
return {
"subject": self.__subject,
@@ -425,7 +491,7 @@ pdp_set: {pdp_set}
@index.deleter
def index(self):
- self.__index = 0
+ self.__index = -1
@property
def pdp_set(self):
diff --git a/moonv4/moon_wrapper/moon_wrapper/api/__init__.py b/moonv4/moon_wrapper/moon_wrapper/api/__init__.py
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/moonv4/moon_wrapper/moon_wrapper/api/__init__.py
diff --git a/moonv4/moon_wrapper/moon_wrapper/api/generic.py b/moonv4/moon_wrapper/moon_wrapper/api/generic.py
new file mode 100644
index 00000000..80e8abff
--- /dev/null
+++ b/moonv4/moon_wrapper/moon_wrapper/api/generic.py
@@ -0,0 +1,151 @@
+# Copyright 2015 Open Platform for NFV Project, Inc. and its contributors
+# This software is distributed under the terms and conditions of the 'Apache-2.0'
+# license which can be found in the file 'LICENSE' in this package distribution
+# or at 'http://www.apache.org/licenses/LICENSE-2.0'.
+"""
+Those API are helping API used to manage the Moon platform.
+"""
+
+from flask_restful import Resource, request
+from oslo_log import log as logging
+from moon_utilities.security_functions import call
+import moon_interface.api
+from moon_utilities.security_functions import check_auth
+
+__version__ = "0.1.0"
+
+LOG = logging.getLogger("moon.interface.api." + __name__)
+
+
+class Status(Resource):
+ """
+ Endpoint for status requests
+ """
+
+ __urls__ = ("/status", "/status/", "/status/<string:component_id>")
+
+ def get(self, component_id=None):
+ """Retrieve status of all components
+
+ :return: {
+ "orchestrator": {
+ "status": "Running"
+ },
+ "security_router": {
+ "status": "Running"
+ }
+ }
+ """
+ return call("security_router", method="get_status", ctx={"component_id": component_id})
+
+
+class Logs(Resource):
+ """
+ Endpoint for logs requests
+ """
+
+ __urls__ = ("/logs", "/logs/", "/logs/<string:component_id>")
+
+ def get(self, component_id=None):
+ """Get logs from the Moon platform
+
+ :param component_id: the ID of the component your are looking for (optional)
+ :return: [
+ "2015-04-15-13:45:20
+ "2015-04-15-13:45:21
+ "2015-04-15-13:45:22
+ "2015-04-15-13:45:23
+ ]
+ """
+ filter_str = request.args.get('filter', '')
+ from_str = request.args.get('from', '')
+ to_str = request.args.get('to', '')
+ event_number = request.args.get('event_number', '')
+ try:
+ event_number = int(event_number)
+ except ValueError:
+ event_number = None
+ args = dict()
+ args["filter"] = filter_str
+ args["from"] = from_str
+ args["to"] = to_str
+ args["event_number"] = event_number
+
+ return call("security_router", method="get_logs", ctx={"component_id": component_id}, args=args)
+
+
+class API(Resource):
+ """
+ Endpoint for API requests
+ """
+
+ __urls__ = (
+ "/api",
+ "/api/",
+ "/api/<string:group_id>",
+ "/api/<string:group_id>/",
+ "/api/<string:group_id>/<string:endpoint_id>")
+
+ @check_auth
+ def get(self, group_id="", endpoint_id="", user_id=""):
+ """Retrieve all API endpoints or a specific endpoint if endpoint_id is given
+
+ :param group_id: the name of one existing group (ie generic, ...)
+ :param endpoint_id: the name of one existing component (ie Logs, Status, ...)
+ :return: {
+ "group_name": {
+ "endpoint_name": {
+ "description": "a description",
+ "methods": {
+ "get": "description of the HTTP method"
+ },
+ "urls": ('/api', '/api/', '/api/<string:endpoint_id>')
+ }
+ }
+ """
+ __methods = ("get", "post", "put", "delete", "options", "patch")
+ api_list = filter(lambda x: "__" not in x, dir(moon_interface.api))
+ api_desc = dict()
+ for api_name in api_list:
+ api_desc[api_name] = {}
+ group_api_obj = eval("moon_interface.api.{}".format(api_name))
+ api_desc[api_name]["description"] = group_api_obj.__doc__
+ if "__version__" in dir(group_api_obj):
+ api_desc[api_name]["version"] = group_api_obj.__version__
+ object_list = list(filter(lambda x: "__" not in x, dir(group_api_obj)))
+ for obj in map(lambda x: eval("moon_interface.api.{}.{}".format(api_name, x)), object_list):
+ if "__urls__" in dir(obj):
+ api_desc[api_name][obj.__name__] = dict()
+ api_desc[api_name][obj.__name__]["urls"] = obj.__urls__
+ api_desc[api_name][obj.__name__]["methods"] = dict()
+ for _method in filter(lambda x: x in __methods, dir(obj)):
+ docstring = eval("moon_interface.api.{}.{}.{}.__doc__".format(api_name, obj.__name__, _method))
+ api_desc[api_name][obj.__name__]["methods"][_method] = docstring
+ api_desc[api_name][obj.__name__]["description"] = str(obj.__doc__)
+ if group_id in api_desc:
+ if endpoint_id in api_desc[group_id]:
+ return {group_id: {endpoint_id: api_desc[group_id][endpoint_id]}}
+ elif len(endpoint_id) > 0:
+ LOG.error("Unknown endpoint_id {}".format(endpoint_id))
+ return {"error": "Unknown endpoint_id {}".format(endpoint_id)}
+ return {group_id: api_desc[group_id]}
+ return api_desc
+
+
+class InternalAPI(Resource):
+ """
+ Endpoint for status requests
+ """
+
+ __urls__ = ("/internal_api", "/internal_api/", "/internal_api/<string:component_id>")
+
+ def get(self, component_id=None, user_id=""):
+ api_list = ("orchestrator", "security_router")
+ if not component_id:
+ return {"api": api_list}
+ if component_id in api_list:
+ api_desc = dict()
+ api_desc["name"] = component_id
+ api_desc["endpoints"] = call("security_router", component_id, {}, "list_api")
+ return api_desc
+
diff --git a/moonv4/moon_wrapper/moon_wrapper/api/wrapper.py b/moonv4/moon_wrapper/moon_wrapper/api/wrapper.py
new file mode 100644
index 00000000..832909c5
--- /dev/null
+++ b/moonv4/moon_wrapper/moon_wrapper/api/wrapper.py
@@ -0,0 +1,101 @@
+# Copyright 2015 Open Platform for NFV Project, Inc. and its contributors
+# This software is distributed under the terms and conditions of the 'Apache-2.0'
+# license which can be found in the file 'LICENSE' in this package distribution
+# or at 'http://www.apache.org/licenses/LICENSE-2.0'.
+"""
+Authz is the endpoint to get authorization response
+"""
+
+import flask
+from flask import request
+from flask_restful import Resource
+import logging
+import json
+import requests
+import time
+from uuid import uuid4
+
+from moon_interface.api.authz import pdp_in_cache, pdp_in_manager, container_exist, \
+ create_containers, create_authz_request
+from moon_interface.authz_requests import AuthzRequest
+from moon_utilities import configuration
+
+__version__ = "0.1.0"
+
+LOG = logging.getLogger("moon.wrapper.api." + __name__)
+
+
+class Wrapper(Resource):
+ """
+ Endpoint for authz requests
+ """
+
+ __urls__ = (
+ "/",
+ )
+
+ def __init__(self, **kwargs):
+ self.port = kwargs.get("port")
+ self.CACHE = kwargs.get("cache", {})
+ self.TIMEOUT = 5
+
+ # def get(self):
+ # LOG.info("GET")
+ # return self.manage_data()
+
+ def post(self):
+ LOG.info("POST {}".format(request.form))
+ response = flask.make_response("False")
+ if self.manage_data():
+ response = flask.make_response("True")
+ response.headers['content-type'] = 'application/octet-stream'
+ return response
+
+ @staticmethod
+ def __get_subject(target, credentials):
+ _subject = target.get("user_id", "")
+ if not _subject:
+ _subject = credentials.get("user_id", "none")
+ return _subject
+
+ @staticmethod
+ def __get_object(target, credentials):
+ try:
+ # note: case of Glance
+ return target['target']['name']
+ except KeyError:
+ pass
+
+ # note: default case
+ return target.get("project_id", "none")
+
+ @staticmethod
+ def __get_project_id(target, credentials):
+ return target.get("project_id", "none")
+
+ def get_interface_url(self, project_id):
+ for container in self.CACHE.containers.values():
+ if container.get("keystone_project_id") == project_id:
+ return "http://{}:{}".format(container['hostname'],
+ container['port'][0]["PublicPort"])
+
+ def manage_data(self):
+ target = json.loads(request.form.get('target', {}))
+ credentials = json.loads(request.form.get('credentials', {}))
+ rule = request.form.get('rule', "")
+ _subject = self.__get_subject(target, credentials)
+ _object = self.__get_object(target, credentials)
+ _project_id = self.__get_project_id(target, credentials)
+ LOG.info("POST with args project={} / "
+ "subject={} - object={} - action={}".format(
+ _project_id, _subject, _object, rule))
+ interface_url = self.get_interface_url(_project_id)
+ req = requests.get("{}/{}/{}/{}".format(
+ interface_url,
+ _subject,
+ _object,
+ rule
+ ))
+ if req.status_code == 200:
+ if req.json().get("result", False):
+ return True
diff --git a/moonv4/moon_wrapper/moon_wrapper/http_server.py b/moonv4/moon_wrapper/moon_wrapper/http_server.py
index f50213c7..d93d6966 100644
--- a/moonv4/moon_wrapper/moon_wrapper/http_server.py
+++ b/moonv4/moon_wrapper/moon_wrapper/http_server.py
@@ -3,74 +3,139 @@
# license which can be found in the file 'LICENSE' in this package distribution
# or at 'http://www.apache.org/licenses/LICENSE-2.0'.
-import requests
-import json
-from flask import Flask, request
+from flask import Flask, jsonify
+from flask_cors import CORS, cross_origin
+from flask_restful import Resource, Api
import logging
-from moon_utilities import configuration
+from moon_wrapper import __version__
+from moon_wrapper.api.generic import Status, Logs, API
+from moon_wrapper.api.wrapper import Wrapper
+from moon_utilities.cache import Cache
+from moon_utilities import configuration, exceptions
logger = logging.getLogger("moon.wrapper.http")
-def __get_subject(target, credentials):
- _subject = target.get("user_id", "")
- if not _subject:
- _subject = credentials.get("user_id", "")
- return _subject
-
-
-def __get_object(target, credentials):
- try:
- # note: case of Glance
- return target['target']['name']
- except KeyError:
- pass
-
- # note: default case
- return target.get("project_id", "")
-
-
-def __get_project_id(target, credentials):
- return target.get("project_id", "")
-
-
-def HTTPServer(host, port):
- app = Flask(__name__)
- conf = configuration.get_configuration("components/wrapper")
- timeout = conf["components/wrapper"].get("timeout", 5)
- conf = configuration.get_configuration("components/interface")
- interface_hostname = conf["components/interface"].get("hostname", "interface")
- interface_port = conf["components/interface"].get("port", 80)
- conf = configuration.get_configuration("logging")
- try:
- debug = conf["logging"]["loggers"]['moon']['level'] == "DEBUG"
- except KeyError:
- debug = False
-
- @app.route("/", methods=['POST', 'GET'])
- def wrapper():
- try:
- target = json.loads(request.form.get('target', {}))
- credentials = json.loads(request.form.get('credentials', {}))
- rule = request.form.get('rule', "")
- _subject = __get_subject(target, credentials)
- _object = __get_object(target, credentials)
- _project_id = __get_project_id(target, credentials)
- logger.info("GET with args {} / {} - {} - {}".format(_project_id, _subject, _object, rule))
- _url = "http://{}:{}/authz/{}/{}/{}/{}".format(
- interface_hostname,
- interface_port,
- _project_id,
- _subject,
- _object,
- rule
- )
- req = requests.get(url=_url, timeout=timeout)
- logger.info("req txt={}".format(req.text))
- if req.json()["result"] == True:
- return "True"
- except Exception as e:
- logger.exception("An exception occurred: {}".format(e))
- return "False"
-
- app.run(debug=debug, host=host, port=port)
+CACHE = Cache()
+
+
+class Server:
+ """Base class for HTTP server"""
+
+ def __init__(self, host="localhost", port=80, api=None, **kwargs):
+ """Run a server
+
+ :param host: hostname of the server
+ :param port: port for the running server
+ :param kwargs: optional parameters
+ :return: a running server
+ """
+ self._host = host
+ self._port = port
+ self._api = api
+ self._extra = kwargs
+
+ @property
+ def host(self):
+ return self._host
+
+ @host.setter
+ def host(self, name):
+ self._host = name
+
+ @host.deleter
+ def host(self):
+ self._host = ""
+
+ @property
+ def port(self):
+ return self._port
+
+ @port.setter
+ def port(self, number):
+ self._port = number
+
+ @port.deleter
+ def port(self):
+ self._port = 80
+
+ def run(self):
+ raise NotImplementedError()
+
+__API__ = (
+ Status, Logs, API
+ )
+
+
+class Root(Resource):
+ """
+ The root of the web service
+ """
+ __urls__ = ("/", )
+ __methods = ("get", "post", "put", "delete", "options")
+
+ def get(self):
+ tree = {"/": {"methods": ("get",),
+ "description": "List all methods for that service."}}
+ for item in __API__:
+ tree[item.__name__] = {"urls": item.__urls__}
+ _methods = []
+ for _method in self.__methods:
+ if _method in dir(item):
+ _methods.append(_method)
+ tree[item.__name__]["methods"] = _methods
+ tree[item.__name__]["description"] = item.__doc__.strip()
+ return {
+ "version": __version__,
+ "tree": tree
+ }
+
+
+class HTTPServer(Server):
+
+ def __init__(self, host="localhost", port=80, **kwargs):
+ super(HTTPServer, self).__init__(host=host, port=port, **kwargs)
+ self.app = Flask(__name__)
+ self.port = port
+ conf = configuration.get_configuration("components/orchestrator")
+ _hostname = conf["components/orchestrator"].get("hostname",
+ "orchestrator")
+ _port = conf["components/manager"].get("port", 80)
+ _protocol = conf["components/manager"].get("protocol", "http")
+ self.orchestrator_url = "{}://{}:{}".format(
+ _protocol, _hostname, _port)
+ # Todo : specify only few urls instead of *
+ # CORS(self.app)
+ self.api = Api(self.app)
+ self.__set_route()
+ self.__hook_errors()
+
+ def __hook_errors(self):
+
+ def get_404_json(e):
+ return jsonify({"result": False, "code": 404,
+ "description": str(e)}), 404
+ self.app.register_error_handler(404, get_404_json)
+
+ def get_400_json(e):
+ return jsonify({"result": False, "code": 400,
+ "description": str(e)}), 400
+ self.app.register_error_handler(400, lambda e: get_400_json)
+ self.app.register_error_handler(403, exceptions.AuthException)
+
+ def __set_route(self):
+ self.api.add_resource(Root, '/')
+
+ for api in __API__:
+ self.api.add_resource(api, *api.__urls__)
+ self.api.add_resource(Wrapper, *Wrapper.__urls__,
+ resource_class_kwargs={
+ "orchestrator_url": self.orchestrator_url,
+ "cache": CACHE,
+ }
+ )
+
+ def run(self):
+ self.app.run(host=self._host, port=self._port) # nosec
+ # self.app.run(debug=True, host=self._host, port=self._port) # nosec
+
diff --git a/moonv4/moon_wrapper/requirements.txt b/moonv4/moon_wrapper/requirements.txt
index 51b57277..399ee15b 100644
--- a/moonv4/moon_wrapper/requirements.txt
+++ b/moonv4/moon_wrapper/requirements.txt
@@ -1,4 +1,3 @@
flask
flask_restful
-babel
moon_utilities \ No newline at end of file
diff --git a/moonv4/tests/populate_default_values.py b/moonv4/tests/populate_default_values.py
index 740ad8ed..cd06ab1a 100644
--- a/moonv4/tests/populate_default_values.py
+++ b/moonv4/tests/populate_default_values.py
@@ -7,8 +7,11 @@ from utils.policies import *
parser = argparse.ArgumentParser()
parser.add_argument('filename', help='scenario filename', nargs=1)
-parser.add_argument("--verbose", "-v", action='store_true', help="verbose mode")
+parser.add_argument("--verbose", "-v", action='store_true',
+ help="verbose mode")
parser.add_argument("--debug", "-d", action='store_true', help="debug mode")
+parser.add_argument("--keystone-pid", "-k", dest="keystone_pid", default="",
+ help="Force a particular Keystone Project ID")
args = parser.parse_args()
FORMAT = '%(asctime)-15s %(levelname)s %(message)s'
@@ -202,11 +205,12 @@ def create_policy(model_id, meta_rule_list):
def create_pdp(policy_id=None):
logger.info("Creating PDP {}".format(scenario.pdp_name))
projects = get_keystone_projects()
- admin_project_id = None
- for _project in projects['projects']:
- if _project['name'] == "admin":
- admin_project_id = _project['id']
- assert admin_project_id
+ project_id = args.keystone_pid
+ if not project_id:
+ for _project in projects['projects']:
+ if _project['name'] == "admin":
+ project_id = _project['id']
+ assert project_id
pdps = check_pdp()["pdps"]
for pdp_id, pdp_value in pdps.items():
if scenario.pdp_name == pdp_value["name"]:
@@ -214,7 +218,7 @@ def create_pdp(policy_id=None):
logger.debug("Found existing PDP named {} (will add policy {})".format(scenario.pdp_name, policy_id))
return pdp_id
_pdp_id = add_pdp(name=scenario.pdp_name, policy_id=policy_id)
- map_to_keystone(pdp_id=_pdp_id, keystone_project_id=admin_project_id)
+ map_to_keystone(pdp_id=_pdp_id, keystone_project_id=project_id)
return _pdp_id
if __name__ == "__main__":
diff --git a/moonv4/tests/send_authz.py b/moonv4/tests/send_authz.py
index a6ad7339..c21c8bca 100644
--- a/moonv4/tests/send_authz.py
+++ b/moonv4/tests/send_authz.py
@@ -136,7 +136,9 @@ def _send(url, stress_test=False):
return {}
if not stress_test:
if res.status_code == 200:
- logger.info("\033[1m{}\033[m {}".format(url, res.status_code))
+ logger.warning("\033[1m{}\033[m \033[32mGrant\033[m".format(url))
+ elif res.status_code == 401:
+ logger.warning("\033[1m{}\033[m \033[31mDeny\033[m".format(url))
else:
logger.error("\033[1m{}\033[m {} {}".format(url, res.status_code, res.text))
try:
@@ -146,11 +148,11 @@ def _send(url, stress_test=False):
logger.error(res.text)
else:
if j.get("result"):
- logger.warning("{} \033[32m{}\033[m".format(url, j.get("result")))
+ # logger.warning("{} \033[32m{}\033[m".format(url, j.get("result")))
logger.debug("{}".format(j.get("error", "")))
current_request['result'] = "Grant"
else:
- logger.warning("{} \033[31m{}\033[m".format(url, "Deny"))
+ # logger.warning("{} \033[31m{}\033[m".format(url, "Deny"))
logger.debug("{}".format(j))
current_request['result'] = "Deny"
return current_request