diff options
137 files changed, 1795 insertions, 3063 deletions
@@ -52,38 +52,8 @@ curl http://$MOON_HOST:30001 curl http://$MOON_HOST:30001/pdp curl http://$MOON_HOST:30001/policies ``` - -If you configured the authentication in the Moon platform: -```bash -curl -i \ - -H "Content-Type: application/json" \ - -d ' -{ "auth": { - "identity": { - "methods": ["password"], - "password": { - "user": { - "name": "admin", - "domain": { "id": "default" }, - "password": "<set_your_password_here>" - } - } - }, - "scope": { - "project": { - "name": "admin", - "domain": { "id": "default" } - } - } - } -}' \ - "http://moon_hostname:30006/v3/auth/tokens" ; echo - -curl --header "X-Auth-Token: <token_retrieve_from_keystone>" http://moon_hostname:30001 -curl --header "X-Auth-Token: <token_retrieve_from_keystone>" http://moon_hostname:30001/pdp -curl --header "X-Auth-Token: <token_retrieve_from_keystone>" http://moon_hostname:30001/policies -``` - + +### Consul Check Check the Consul service for - *Components/Manager*, e.g. ```json @@ -114,10 +84,53 @@ Check the Consul service for } ``` +### Tests Launch functional [test scenario](tests/functional/scenario_enabled) : ```bash -cd $MOON_HOME/tests/functional/scenario_enabled -docker run -ti -v $(pwd):/data wukongsun/moon_forming:latest /bin/bash -moon_populate_values --consul-host=$MOON_HOST --consul-port=30005 -v /data/rbac_large.py -moon_send_authz --consul-host=$MOON_HOST --consul-port=30005 --authz-host=$MOON_HOST --authz-port=31002 -v /data/rbac_large.py +sudo pip install python_moonclient --upgrade +cd $MOON_HOME/tests/functional/scenario_tests +moon_create_pdp --consul-host=$MOON_HOST --consul-port=30005 -v rbac_large.py +moon_get_keystone_project --consul-host=$MOON_HOST --consul-port=30005 +moon_get_pdp --consul-host=$MOON_HOST --consul-port=30005 +moon_map_pdp_to_project "<pdp_id>" "<keystone_project_id>" +moon_send_authz_to_wrapper --consul-host=$MOON_HOST --consul-port=30005 --authz-host=$WRAPPER_HOST --authz-port=$WRAPPER_PORT -v rbac_large.py ``` + +To retrieve the wrapper information, use the following command: +```bash +kubectl get -n moon services | grep wrapper +``` + + +## Annexe +### Authentication +If you configured the authentication in the Moon platform: +```bash +curl -i \ + -H "Content-Type: application/json" \ + -d ' +{ "auth": { + "identity": { + "methods": ["password"], + "password": { + "user": { + "name": "admin", + "domain": { "id": "default" }, + "password": "<set_your_password_here>" + } + } + }, + "scope": { + "project": { + "name": "admin", + "domain": { "id": "default" } + } + } + } +}' \ + "http://moon_hostname:30006/v3/auth/tokens" ; echo + +curl --header "X-Auth-Token: <token_retrieve_from_keystone>" http://moon_hostname:30001 +curl --header "X-Auth-Token: <token_retrieve_from_keystone>" http://moon_hostname:30001/pdp +curl --header "X-Auth-Token: <token_retrieve_from_keystone>" http://moon_hostname:30001/policies +```
\ No newline at end of file diff --git a/moon_authz/Dockerfile b/moon_authz/Dockerfile index 7ab172b0..fea9555d 100644 --- a/moon_authz/Dockerfile +++ b/moon_authz/Dockerfile @@ -1,12 +1,8 @@ -FROM ubuntu:latest - -RUN apt update && apt install python3.5 python3-pip -y -RUN pip3 install pip --upgrade +FROM python:3 ADD . /root WORKDIR /root/ -RUN pip3 install -r requirements.txt --upgrade -RUN pip3 install /root/dist/* --upgrade +RUN pip3 install -r requirements.txt RUN pip3 install . CMD ["python3", "-m", "moon_authz"]
\ No newline at end of file diff --git a/moon_authz/README.rst b/moon_authz/README.md index ded4e99a..696c29a1 100644 --- a/moon_authz/README.rst +++ b/moon_authz/README.md @@ -1,5 +1,4 @@ -Core module for the Moon project -================================ +# moon_authz This package contains the core module for the Moon project It is designed to provide authorization features to all OpenStack components. diff --git a/moon_authz/moon_authz/api/authorization.py b/moon_authz/moon_authz/api/authorization.py index 4cd8de06..d7832ef0 100644 --- a/moon_authz/moon_authz/api/authorization.py +++ b/moon_authz/moon_authz/api/authorization.py @@ -19,20 +19,20 @@ from flask_restful import Resource # - call the next security function # - call the master if an element is absent -LOG = logging.getLogger("moon.api." + __name__) +LOG = logging.getLogger("moon.authz.api." + __name__) class Authz(Resource): """ Endpoint for authz requests """ + __version__ = "0.1.0" __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 @@ -47,13 +47,11 @@ class Authz(Resource): self.cache = kwargs.get("cache") self.context = None - def post(self, uuid=None, subject_name=None, object_name=None, action_name=None): + def post(self): """Get a response on an authorization request - :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 + :request: + :return: { "args": {}, "ctx": { @@ -255,47 +253,47 @@ class Authz(Resource): 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] - 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 - if self.payload["authz_context"]['pdp_set'][current_header_id]['meta_rules']['name'] == "session": - subject = self.payload["authz_context"]['current_request'].get("subject") - subject_category_id = None - role_names = [] - for category_id, category_value in ModelManager.get_subject_categories("admin").items(): - if category_value["name"] == "role": - subject_category_id = category_id - 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"]) - new_role_ids = [] - for perimeter_id, perimeter_value in PolicyManager.get_objects("admin", current_policy_id).items(): - if perimeter_value["name"] in role_names: - new_role_ids.append(perimeter_id) - break - perimeter_id = None - for perimeter_id, perimeter_value in PolicyManager.get_actions("admin", current_policy_id).items(): - if perimeter_value["name"] == "*": - break - - 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'] + # 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] + # 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 + # if self.payload["authz_context"]['pdp_set'][current_header_id]['meta_rules']['name'] == "session": + # subject = self.payload["authz_context"]['current_request'].get("subject") + # subject_category_id = None + # role_names = [] + # for category_id, category_value in ModelManager.get_subject_categories("admin").items(): + # if category_value["name"] == "role": + # subject_category_id = category_id + # 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"]) + # new_role_ids = [] + # for perimeter_id, perimeter_value in PolicyManager.get_objects("admin", current_policy_id).items(): + # if perimeter_value["name"] in role_names: + # new_role_ids.append(perimeter_id) + # break + # perimeter_id = None + # for perimeter_id, perimeter_value in PolicyManager.get_actions("admin", current_policy_id).items(): + # if perimeter_value["name"] == "*": + # break + # + # 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'] def get_authz(self): # self.keystone_project_id = payload["id"] diff --git a/moon_authz/moon_authz/api/generic.py b/moon_authz/moon_authz/api/generic.py deleted file mode 100644 index f4e13e42..00000000 --- a/moon_authz/moon_authz/api/generic.py +++ /dev/null @@ -1,131 +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'. -""" -Those API are helping API used to manage the Moon platform. -""" - -from flask_restful import Resource, request -from oslo_log import log as logging -import moon_authz.api -from python_moonutilities.security_functions import check_auth - -__version__ = "0.1.0" - -LOG = logging.getLogger("moon.authz.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" - } - } - """ - raise NotImplemented - - -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 - - raise NotImplemented - - -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_authz.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 diff --git a/moon_authz/moon_authz/http_server.py b/moon_authz/moon_authz/http_server.py index 50e878d3..d24a02ca 100644 --- a/moon_authz/moon_authz/http_server.py +++ b/moon_authz/moon_authz/http_server.py @@ -12,7 +12,7 @@ from moon_authz.api.authorization import Authz from python_moonutilities.cache import Cache from python_moonutilities import exceptions -logger = logging.getLogger("moon." + __name__) +logger = logging.getLogger("moon.authz.http_server") CACHE = Cache() CACHE.update() diff --git a/moon_authz/moon_authz/server.py b/moon_authz/moon_authz/server.py index 974012dc..1919ebe5 100644 --- a/moon_authz/moon_authz/server.py +++ b/moon_authz/moon_authz/server.py @@ -8,20 +8,19 @@ from oslo_log import log as logging from moon_authz.http_server import HTTPServer as Server from python_moonutilities import configuration -LOG = logging.getLogger("moon.server") +LOG = logging.getLogger("moon.authz.server") DOMAIN = "moon_authz" -__CWD__ = os.path.dirname(os.path.abspath(__file__)) - def main(): + configuration.init_logging() + 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 diff --git a/moon_authz/setup.py b/moon_authz/setup.py index a8dcd0c4..c3ac33c7 100644 --- a/moon_authz/setup.py +++ b/moon_authz/setup.py @@ -21,7 +21,7 @@ setup( description="", - long_description=open('README.rst').read(), + long_description=open('README.md').read(), # install_requires= , diff --git a/moon_forming/Dockerfile b/moon_forming/Dockerfile index bc6b699e..ca0eba76 100644 --- a/moon_forming/Dockerfile +++ b/moon_forming/Dockerfile @@ -1,4 +1,5 @@ FROM python:3 + WORKDIR /usr/src/app RUN pip install --no-cache-dir --upgrade requests pyyaml python_moonutilities python_moondb python_moonclient diff --git a/moon_forming/run.sh b/moon_forming/run.sh index a4d89204..d731cb17 100644 --- a/moon_forming/run.sh +++ b/moon_forming/run.sh @@ -5,8 +5,9 @@ populate_args=$* echo "Waiting for Consul (http://consul:8500)" while ! python -c "import requests; req = requests.get('http://consul:8500')" 2>/dev/null ; do sleep 5 ; - echo "." + echo -n "." done +echo "." echo "Consul (http://consul:8500) is up." python3 /root/conf2consul.py /etc/moon/moon.conf @@ -14,8 +15,9 @@ python3 /root/conf2consul.py /etc/moon/moon.conf echo "Waiting for DB (tcp://db:3306)" while ! python -c "import socket, sys; s = socket.socket(socket.AF_INET, socket.SOCK_STREAM); s.connect(('db', 3306)); sys.exit(0)" 2>/dev/null ; do sleep 5 ; - echo "." + echo -n "." done +echo "." echo "Database (http://db:3306) is up." moon_db_manager upgrade @@ -23,17 +25,19 @@ moon_db_manager upgrade echo "Waiting for Keystone (http://keystone:5000)" while ! python -c "import requests; req = requests.get('http://keystone:5000')" 2>/dev/null ; do sleep 5 ; - echo "." + echo -n "." done +echo "." echo "Keystone (http://keystone:5000) is up." echo "Waiting for Manager (http://manager:8082)" while ! python -c "import requests; req = requests.get('http://manager:8082')" 2>/dev/null ; do sleep 5 ; - echo "." + echo -n "." done +echo "." echo "Manager (http://manager:8082) is up." -for i in /data/*.py ; do - moon_populate_values $populate_args --consul-host=consul --consul-port=8500 $i -done +#for i in /data/*.py ; do +# moon_populate_values $populate_args --consul-host=consul --consul-port=8500 $i +#done diff --git a/moon_interface/Dockerfile b/moon_interface/Dockerfile index 82160cc9..f4de15eb 100644 --- a/moon_interface/Dockerfile +++ b/moon_interface/Dockerfile @@ -1,12 +1,8 @@ -FROM ubuntu:latest - -RUN apt update && apt install python3.5 python3-pip -y -RUN pip3 install python_moonutilities python_moondb pip --upgrade +FROM python:3 ADD . /root WORKDIR /root/ -RUN pip3 install -r requirements.txt --upgrade -#RUN pip3 install /root/dist/* --upgrade +RUN pip3 install -r requirements.txt RUN pip3 install . CMD ["python3", "-m", "moon_interface"]
\ No newline at end of file diff --git a/moon_interface/Makefile b/moon_interface/Makefile deleted file mode 100644 index af91b904..00000000 --- a/moon_interface/Makefile +++ /dev/null @@ -1,12 +0,0 @@ -all: built run - -built: - docker build -t moon_policy:16.04 . - -run: - docker run -p 8000:8000 moon_policy:16.04 - -.PHONY: clean - -clean: - find . -name "*.py" -exec echo rm {}\; diff --git a/moon_manager/README.rst b/moon_interface/README.md index ded4e99a..4c0e483d 100644 --- a/moon_manager/README.rst +++ b/moon_interface/README.md @@ -1,5 +1,5 @@ -Core module for the Moon project -================================ +# moon_interface + This package contains the core module for the Moon project It is designed to provide authorization features to all OpenStack components. diff --git a/moon_interface/moon_interface/api/authz.py b/moon_interface/moon_interface/api/authz.py index c9f4697f..a284ff3a 100644 --- a/moon_interface/moon_interface/api/authz.py +++ b/moon_interface/moon_interface/api/authz.py @@ -18,7 +18,7 @@ from moon_interface.authz_requests import AuthzRequest __version__ = "0.1.0" -LOG = logging.getLogger("moon.interface.api." + __name__) +LOG = logging.getLogger("moon.interface.api.authz." + __name__) def pdp_in_cache(cache, uuid): @@ -45,39 +45,6 @@ def pdp_in_manager(cache, uuid): 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 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 diff --git a/moon_interface/moon_interface/containers.py b/moon_interface/moon_interface/containers.py deleted file mode 100644 index 4f93d742..00000000 --- a/moon_interface/moon_interface/containers.py +++ /dev/null @@ -1,102 +0,0 @@ -# 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 python_moonutilities 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/moon_interface/moon_interface/http_server.py b/moon_interface/moon_interface/http_server.py index 890bb82f..72576f6c 100644 --- a/moon_interface/moon_interface/http_server.py +++ b/moon_interface/moon_interface/http_server.py @@ -15,6 +15,10 @@ from python_moonutilities import configuration, exceptions logger = logging.getLogger("moon.interface.http") +__API__ = ( + Status, Logs, API + ) + class Server: """Base class for HTTP server""" @@ -59,10 +63,6 @@ class Server: def run(self): raise NotImplementedError() -__API__ = ( - Status, Logs, API - ) - class Root(Resource): """ @@ -132,5 +132,3 @@ class HTTPServer(Server): 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/moon_interface/moon_interface/server.py b/moon_interface/moon_interface/server.py index e53b4504..8b53d7f3 100644 --- a/moon_interface/moon_interface/server.py +++ b/moon_interface/moon_interface/server.py @@ -7,7 +7,7 @@ import logging from python_moonutilities import configuration, exceptions from moon_interface.http_server import HTTPServer -LOG = logging.getLogger("moon.interface") +LOG = logging.getLogger("moon.interface.server") def main(): @@ -23,10 +23,7 @@ def main(): port = 80 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) - return server + return HTTPServer(host=bind, port=port) if __name__ == '__main__': diff --git a/moon_interface/setup.py b/moon_interface/setup.py index 3460c991..db15ff54 100644 --- a/moon_interface/setup.py +++ b/moon_interface/setup.py @@ -21,7 +21,7 @@ setup( description="", - long_description=open('README.rst').read(), + long_description=open('README.md').read(), # install_requires= , diff --git a/moon_interface/tools/run.sh b/moon_interface/tools/run.sh deleted file mode 100644 index d1db1f00..00000000 --- a/moon_interface/tools/run.sh +++ /dev/null @@ -1,5 +0,0 @@ -#!/usr/bin/env bash - -http_proxy= /usr/bin/python3 /home/vdsq3226/projets/opnfv/opnfv-moon/moon_interface/tools/api2rst.py -pandoc api.rst --toc -o api.pdf -evince api.pdf diff --git a/moon_manager/Dockerfile b/moon_manager/Dockerfile index 873e3aa2..b5eb4e02 100644 --- a/moon_manager/Dockerfile +++ b/moon_manager/Dockerfile @@ -1,12 +1,8 @@ -FROM ubuntu:latest - -RUN apt update && apt install python3.5 python3-pip -y -RUN pip3 install pip --upgrade +FROM python:3 ADD . /root WORKDIR /root/ RUN pip3 install -r requirements.txt -#RUN pip3 install /root/dist/* --upgrade RUN pip3 install . CMD ["python3", "-m", "moon_manager"]
\ No newline at end of file diff --git a/moon_interface/README.rst b/moon_manager/README.md index ded4e99a..c74ccc28 100644 --- a/moon_interface/README.rst +++ b/moon_manager/README.md @@ -1,5 +1,4 @@ -Core module for the Moon project -================================ +# moon_manager This package contains the core module for the Moon project It is designed to provide authorization features to all OpenStack components. diff --git a/moon_manager/moon_manager/api/containers.py b/moon_manager/moon_manager/api/containers.py deleted file mode 100644 index 6dc50ea5..00000000 --- a/moon_manager/moon_manager/api/containers.py +++ /dev/null @@ -1,178 +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. - -""" - -import copy -from docker import Client -from flask import request -from flask_restful import Resource -from oslo_log import log as logging -from python_moonutilities.security_functions import check_auth -from python_moonutilities import configuration - -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/moon_manager/moon_manager/api/generic.py b/moon_manager/moon_manager/api/generic.py index bd7dcdac..f46bfd35 100644 --- a/moon_manager/moon_manager/api/generic.py +++ b/moon_manager/moon_manager/api/generic.py @@ -21,7 +21,11 @@ class Status(Resource): Endpoint for status requests """ - __urls__ = ("/status", "/status/", "/status/<string:component_id>") + __urls__ = ( + "/status", + "/status/", + "/status/<string:component_id>" + ) def get(self, component_id=None): """Retrieve status of all components @@ -43,7 +47,11 @@ class Logs(Resource): Endpoint for logs requests """ - __urls__ = ("/logs", "/logs/", "/logs/<string:component_id>") + __urls__ = ( + "/logs", + "/logs/", + "/logs/<string:component_id>" + ) def get(self, component_id=None): """Get logs from the Moon platform @@ -83,7 +91,8 @@ class API(Resource): "/api/", "/api/<string:group_id>", "/api/<string:group_id>/", - "/api/<string:group_id>/<string:endpoint_id>") + "/api/<string:group_id>/<string:endpoint_id>" + ) @check_auth def get(self, group_id="", endpoint_id="", user_id=""): diff --git a/moon_manager/moon_manager/api/meta_rules.py b/moon_manager/moon_manager/api/meta_rules.py index ceba0ffb..21552dd7 100644 --- a/moon_manager/moon_manager/api/meta_rules.py +++ b/moon_manager/moon_manager/api/meta_rules.py @@ -23,10 +23,12 @@ 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>/") + __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): diff --git a/moon_manager/moon_manager/http_server.py b/moon_manager/moon_manager/http_server.py index 584e71a2..6aa2cd44 100644 --- a/moon_manager/moon_manager/http_server.py +++ b/moon_manager/moon_manager/http_server.py @@ -20,12 +20,20 @@ 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 python_moonutilities import configuration, exceptions from python_moondb.core import PDPManager -LOG = logging.getLogger("moon.manager.http") +LOG = logging.getLogger("moon.manager.http_server") + +__API__ = ( + Status, Logs, API, + MetaRules, SubjectCategories, ObjectCategories, ActionCategories, + Subjects, Objects, Actions, Rules, + SubjectAssignments, ObjectAssignments, ActionAssignments, + SubjectData, ObjectData, ActionData, + Models, Policies, PDP + ) class Server: @@ -71,16 +79,6 @@ class Server: def run(self): raise NotImplementedError() -__API__ = ( - Status, Logs, API, - MetaRules, SubjectCategories, ObjectCategories, ActionCategories, - Subjects, Objects, Actions, - SubjectAssignments, ObjectAssignments, ActionAssignments, - SubjectData, ObjectData, ActionData, - Rules, #Container, - Models, Policies, PDP - ) - class Root(Resource): """ @@ -113,7 +111,7 @@ class HTTPServer(Server): 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 * + # TODO : specify only few urls instead of * CORS(self.app) self.api = Api(self.app) self.__set_route() @@ -133,8 +131,8 @@ class HTTPServer(Server): def __set_route(self): self.api.add_resource(Root, '/') - for api in __API__: - self.api.add_resource(api, *api.__urls__) + for _api in __API__: + self.api.add_resource(_api, *_api.__urls__) @staticmethod def __check_if_db_is_up(): @@ -154,4 +152,3 @@ class HTTPServer(Server): def run(self): self.__check_if_db_is_up() self.app.run(debug=True, host=self._host, port=self._port) # nosec - diff --git a/moon_manager/moon_manager/server.py b/moon_manager/moon_manager/server.py index bcc52cb3..f4c01611 100644 --- a/moon_manager/moon_manager/server.py +++ b/moon_manager/moon_manager/server.py @@ -3,18 +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 os from oslo_config import cfg from oslo_log import log as logging from python_moonutilities import configuration, exceptions from moon_manager.http_server import HTTPServer -LOG = logging.getLogger("moon.manager") +LOG = logging.getLogger("moon.manager.server") CONF = cfg.CONF DOMAIN = "moon_manager" -__CWD__ = os.path.dirname(os.path.abspath(__file__)) - def main(): configuration.init_logging() @@ -29,8 +26,7 @@ def main(): port = 80 configuration.add_component(uuid="manager", 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) - return server + return HTTPServer(host=bind, port=port) if __name__ == '__main__': diff --git a/moon_manager/requirements.txt b/moon_manager/requirements.txt index 15ba715b..e2dd5c96 100644 --- a/moon_manager/requirements.txt +++ b/moon_manager/requirements.txt @@ -3,4 +3,3 @@ flask_restful flask_cors python_moonutilities python_moondb -docker-py diff --git a/moon_manager/setup.py b/moon_manager/setup.py index a6fc5fc7..bd8a70f0 100644 --- a/moon_manager/setup.py +++ b/moon_manager/setup.py @@ -21,7 +21,7 @@ setup( description="", - long_description=open('README.rst').read(), + long_description=open('README.md').read(), # install_requires= , diff --git a/moon_manager/tests/functional_pod/run_functional_tests.sh b/moon_manager/tests/functional_pod/run_functional_tests.sh new file mode 100644 index 00000000..c80bf15d --- /dev/null +++ b/moon_manager/tests/functional_pod/run_functional_tests.sh @@ -0,0 +1,11 @@ +#!/usr/bin/env bash + +set -x + +kubectl create -n moon -f tools/moon_kubernetes/templates/moon_forming.yaml + +echo Waiting for jobs forming +sleep 5 +kubectl get jobs -n moon +kubectl logs -n moon jobs/forming + diff --git a/moon_orchestrator/Dockerfile b/moon_orchestrator/Dockerfile index aafe1784..e9f83094 100644 --- a/moon_orchestrator/Dockerfile +++ b/moon_orchestrator/Dockerfile @@ -1,15 +1,8 @@ -FROM ubuntu:latest - -ENV CONSUL_HOST=consul -ENV CONSUL_PORT=8500 - -RUN apt update && apt install python3.5 python3-pip python3-mysql.connector -y -RUN pip3 install pip --upgrade +FROM python:3 ADD . /root WORKDIR /root/ -RUN pip3 install -r requirements.txt --upgrade -#RUN pip3 install /root/dist/* --upgrade -RUN pip3 install . --upgrade +RUN pip3 install -r requirements.txt +RUN pip3 install . CMD ["python3", "-m", "moon_orchestrator"]
\ No newline at end of file diff --git a/moon_orchestrator/README.md b/moon_orchestrator/README.md index d4cdc4fb..aec5cda2 100644 --- a/moon_orchestrator/README.md +++ b/moon_orchestrator/README.md @@ -1,3 +1,4 @@ -# Moon Orchestrator +# moon_orchestrator + Internal orchestrator used for the Moon framework diff --git a/moon_orchestrator/conf/dockers/template.dockerfile b/moon_orchestrator/conf/dockers/template.dockerfile deleted file mode 100644 index 6bb8a0c6..00000000 --- a/moon_orchestrator/conf/dockers/template.dockerfile +++ /dev/null @@ -1,25 +0,0 @@ -# Pull base image. -FROM ubuntu:latest - -{{ proxy }} - -RUN apt-get update && apt-get install python3.5 python3-pip -y - -ADD dist/moon_utilities-0.1.0.tar.gz /root -WORKDIR /root/moon_utilities-0.1.0 -RUN pip3 install pip --upgrade -RUN pip3 install --upgrade -r requirements.txt -RUN pip3 install --upgrade . - -ADD dist/moon_db-0.1.0.tar.gz /root -WORKDIR /root/moon_db-0.1.0 -RUN pip3 install --upgrade -r requirements.txt -RUN pip3 install --upgrade . - -{{ run }} - -{% for port in ports %} -EXPOSE {{ port }} -{% endfor %} - -CMD {{ cmd }} diff --git a/moon_orchestrator/conf/moon.conf b/moon_orchestrator/conf/moon.conf deleted file mode 100644 index 49086d48..00000000 --- a/moon_orchestrator/conf/moon.conf +++ /dev/null @@ -1,84 +0,0 @@ -database: - url: mysql+pymysql://moon:p4sswOrd1@db/moon - driver: sql - -messenger: - url: rabbit://moon:p4sswOrd1@messenger:5672/moon - -docker: - url: tcp://172.88.88.1:2376 - network: moon - -slave: - name: - master: - url: - login: - password: - -openstack: - keystone: - url: http://keystone:5000/v3 - user: admin - password: p4ssw0rd - domain: default - project: admin - check_token: false - certificate: false - -plugins: - authz: - container: wukongsun/moon_authz:v4.1 - session: - container: asteroide/session:latest - -components: - interface: - port: 8081 - hostname: interface - bind: 0.0.0.0 - container: wukongsun/moon_interface:v4.1 - router: - container: wukongsun/moon_router:v4.1 - hostname: router - manager: - container: wukongsun/moon_manager:v4.1 - hostname: manager - orchestrator: - container: wukongsun/moon_orchestrator:v4.1 - hostname: orchestrator - port_start: 38001 - -logging: - version: 1 - - formatters: - brief: - format: "%(levelname)s %(name)s %(message)-30s" - custom: - format: "%(asctime)-15s %(levelname)s %(name)s %(message)s" - - handlers: - console: - class : logging.StreamHandler - formatter: brief - level : INFO - stream : ext://sys.stdout - file: - class : logging.handlers.RotatingFileHandler - formatter: custom - level : DEBUG - filename: /tmp/moon.log - maxBytes: 1048576 - backupCount: 3 - - loggers: - moon: - level: DEBUG - handlers: [console, file] - propagate: no - - root: - level: ERROR - handlers: [console] - diff --git a/moon_orchestrator/conf/plugins/authz.py b/moon_orchestrator/conf/plugins/authz.py deleted file mode 100644 index 4a1441c9..00000000 --- a/moon_orchestrator/conf/plugins/authz.py +++ /dev/null @@ -1,67 +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'. - -import os -import time -import hashlib -from oslo_config import cfg -from oslo_log import log as logging -import oslo_messaging -from moon_orchestrator.dockers import DockerBase - -LOG = logging.getLogger(__name__) -CONF = cfg.CONF -DOMAIN = "moon_orchestrator" - -__CWD__ = os.path.dirname(os.path.abspath(__file__)) -# TODO (asteroide): select the right template folder -TEMPLATES_FOLDER = os.path.join(__CWD__, "..", "conf", "dockers") -# TODO (asteroide): add specific configuration options for that plugin - - -class AuthzFunction(DockerBase): - - id = "moon_authz_function" - __build = """RUN mkdir -p /etc/moon/ -COPY conf /etc/moon/ -ADD dist/{py_pkg}.tar.gz /root -WORKDIR /root/{py_pkg} -RUN pip3 install -r requirements.txt -RUN pip3 install . -""" - - def __init__(self, uuid, conf_file="", docker=None, network_config=None): - self.id = "authz_"+hashlib.sha224(uuid.encode("utf-8")).hexdigest() - super(AuthzFunction, self).__init__( - name="moon_authz", - run_cmd=["python3", "-m", "moon_authz", uuid], - conf_file=conf_file, - docker=docker, - network_config=network_config, - build_cmd=self.__build, - id=self.id, - tag="" - # tag=CONF.security_function.container - ) - # note(asteroide): time to let the new docker boot - time.sleep(3) - # self.get_status() - - def get_status(self): - return True - # transport = oslo_messaging.get_transport(CONF) - # target = oslo_messaging.Target(topic=self.id, version='1.0') - # client = oslo_messaging.RPCClient(transport, target) - # LOG.info("Calling Status on {}".format(self.id)) - # ret = client.call({"component_id": self.id}, 'get_status', args=None) - # LOG.info(ret) - # return ret - - -def run(uuid, conf_file="", docker=None, network_config=None): - return AuthzFunction(uuid, - conf_file=conf_file, - docker=docker, - network_config=network_config) diff --git a/moon_orchestrator/conf/plugins/session.py b/moon_orchestrator/conf/plugins/session.py deleted file mode 100644 index 6fa2cfe2..00000000 --- a/moon_orchestrator/conf/plugins/session.py +++ /dev/null @@ -1,67 +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'. - -import os -import time -import hashlib -from oslo_config import cfg -from oslo_log import log as logging -import oslo_messaging -from moon_orchestrator.dockers import DockerBase - -LOG = logging.getLogger(__name__) -CONF = cfg.CONF -DOMAIN = "moon_orchestrator" - -__CWD__ = os.path.dirname(os.path.abspath(__file__)) -# TODO (asteroide): select the right template folder -TEMPLATES_FOLDER = os.path.join(__CWD__, "..", "conf", "dockers") -# TODO (asteroide): add specific configuration options for that plugin - - -class AuthzFunction(DockerBase): - - id = "moon_session_function" - __build = """RUN mkdir -p /etc/moon/ -COPY conf /etc/moon/ -ADD dist/{py_pkg}.tar.gz /root -WORKDIR /root/{py_pkg} -RUN pip3 install -r requirements.txt -RUN pip3 install . -""" - - def __init__(self, uuid, conf_file="", docker=None, network_config=None): - self.id = "session_"+hashlib.sha224(uuid.encode("utf-8")).hexdigest() - super(AuthzFunction, self).__init__( - name="moon_authz", - run_cmd=["python3", "-m", "moon_authz", uuid], - conf_file=conf_file, - docker=docker, - network_config=network_config, - build_cmd=self.__build, - id=self.id, - tag="" - # tag=CONF.security_function.container - ) - # note(asteroide): time to let the new docker boot - time.sleep(3) - # self.get_status() - - def get_status(self): - return True - # transport = oslo_messaging.get_transport(CONF) - # target = oslo_messaging.Target(topic=self.id, version='1.0') - # client = oslo_messaging.RPCClient(transport, target) - # LOG.info("Calling Status on {}".format(self.id)) - # ret = client.call({"component_id": self.id}, 'get_status', args=None) - # LOG.info(ret) - # return ret - - -def run(uuid, conf_file="", docker=None, network_config=None): - return AuthzFunction(uuid, - conf_file=conf_file, - docker=docker, - network_config=network_config) diff --git a/moon_orchestrator/conf/policies/policy_authz/assignment.json b/moon_orchestrator/conf/policies/policy_authz/assignment.json deleted file mode 100644 index 7a6c722e..00000000 --- a/moon_orchestrator/conf/policies/policy_authz/assignment.json +++ /dev/null @@ -1,55 +0,0 @@ -{ - "subject_assignments": { - "subject_security_level":{ - "admin": ["high"], - "demo": ["medium"] - }, - "domain":{ - "admin": ["ft"], - "demo": ["xx"] - }, - "role": { - "admin": ["admin"], - "demo": ["dev"] - } - }, - - "action_assignments": { - "resource_action":{ - "pause": ["vm_admin"], - "unpause": ["vm_admin"], - "start": ["vm_admin"], - "stop": ["vm_admin"], - "list": ["vm_access", "vm_admin"], - "create": ["vm_admin"], - "storage_list": ["storage_access"], - "download": ["storage_access"], - "post": ["storage_admin"], - "upload": ["storage_admin"] - }, - "access": { - "pause": ["write"], - "unpause": ["write"], - "start": ["write"], - "stop": ["write"], - "list": ["read"], - "create": ["write"], - "storage_list": ["read"], - "download": ["read"], - "post": ["write"], - "upload": ["write"] - } - }, - - "object_assignments": { - "object_security_level": { - "servers": ["low"] - }, - "type": { - "servers": ["computing"] - }, - "object_id": { - "servers": ["servers"] - } - } -} diff --git a/moon_orchestrator/conf/policies/policy_authz/metadata.json b/moon_orchestrator/conf/policies/policy_authz/metadata.json deleted file mode 100644 index 21a99eb2..00000000 --- a/moon_orchestrator/conf/policies/policy_authz/metadata.json +++ /dev/null @@ -1,23 +0,0 @@ -{ - "name": "Simple_Policy", - "genre": "authz", - "description": "Simple Security Policy", - "pdp_pipeline": ["authz:rbac_rule", "authz:mls_rule"], - - "subject_categories": [ - "subject_security_level", - "domain", - "role" - ], - - "action_categories": [ - "resource_action", - "access" - ], - - "object_categories": [ - "object_security_level", - "type", - "object_id" - ] -} diff --git a/moon_orchestrator/conf/policies/policy_authz/metarule.json b/moon_orchestrator/conf/policies/policy_authz/metarule.json deleted file mode 100644 index c9afd6c2..00000000 --- a/moon_orchestrator/conf/policies/policy_authz/metarule.json +++ /dev/null @@ -1,24 +0,0 @@ -{ - "sub_meta_rules": { - "mls_rule": { - "subject_categories": ["subject_security_level"], - "action_categories": ["resource_action"], - "object_categories": ["object_security_level"], - "algorithm": "inclusion" - }, - "dte_rule": { - "subject_categories": ["domain"], - "action_categories": ["access"], - "object_categories": ["type"], - "algorithm": "inclusion" - }, - "rbac_rule": { - "subject_categories": ["role", "domain"], - "action_categories": ["access"], - "object_categories": ["object_id"], - "algorithm": "inclusion" - } - }, - "aggregation": "all_true" -} - diff --git a/moon_orchestrator/conf/policies/policy_authz/perimeter.json b/moon_orchestrator/conf/policies/policy_authz/perimeter.json deleted file mode 100644 index 47a8ee45..00000000 --- a/moon_orchestrator/conf/policies/policy_authz/perimeter.json +++ /dev/null @@ -1,21 +0,0 @@ -{ - "subjects": [ - "admin", - "demo" - ], - "actions": [ - "pause", - "unpause", - "start", - "stop", - "create", - "list", - "upload", - "download", - "post", - "storage_list" - ], - "objects": [ - "servers" - ] -} diff --git a/moon_orchestrator/conf/policies/policy_authz/rule.json b/moon_orchestrator/conf/policies/policy_authz/rule.json deleted file mode 100644 index 25f9d93a..00000000 --- a/moon_orchestrator/conf/policies/policy_authz/rule.json +++ /dev/null @@ -1,25 +0,0 @@ -{ - "mls_rule":[ - ["high", "vm_admin", "medium"], - ["high", "vm_admin", "low"], - ["medium", "vm_admin", "low"], - ["high", "vm_access", "high"], - ["high", "vm_access", "medium"], - ["high", "vm_access", "low"], - ["medium", "vm_access", "medium"], - ["medium", "vm_access", "low"], - ["low", "vm_access", "low"] - ], - "dte_rule":[ - ["ft", "read", "computing"], - ["ft", "write", "computing"], - ["ft", "read", "storage"], - ["ft", "write", "storage"], - ["xx", "read", "storage"] - ], - "rbac_rule":[ - ["dev", "xx", "read", "servers"], - ["admin", "xx", "read", "servers"], - ["admin", "ft", "read", "servers"] - ] -} diff --git a/moon_orchestrator/conf/policies/policy_authz/scope.json b/moon_orchestrator/conf/policies/policy_authz/scope.json deleted file mode 100644 index 9b313daf..00000000 --- a/moon_orchestrator/conf/policies/policy_authz/scope.json +++ /dev/null @@ -1,49 +0,0 @@ -{ - "subject_scopes": { - "role": [ - "admin", - "dev" - ], - "subject_security_level": [ - "high", - "medium", - "low" - ], - "domain": [ - "ft", - "xx" - ] - }, - - "action_scopes": { - "resource_action": [ - "vm_admin", - "vm_access", - "storage_admin", - "storage_access" - ], - "access": [ - "write", - "read" - ] - }, - - "object_scopes": { - "object_security_level": [ - "high", - "medium", - "low" - ], - "type": [ - "computing", - "storage" - ], - "object_id": [ - "servers", - "vm1", - "vm2", - "file1", - "file2" - ] - } -} diff --git a/moon_orchestrator/conf/policies/policy_empty_admin/assignment.json b/moon_orchestrator/conf/policies/policy_empty_admin/assignment.json deleted file mode 100644 index 24018a09..00000000 --- a/moon_orchestrator/conf/policies/policy_empty_admin/assignment.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "subject_assignments": {}, - - "action_assignments": {}, - - "object_assignments": {} -} diff --git a/moon_orchestrator/conf/policies/policy_empty_admin/metadata.json b/moon_orchestrator/conf/policies/policy_empty_admin/metadata.json deleted file mode 100644 index 3c9be2e5..00000000 --- a/moon_orchestrator/conf/policies/policy_empty_admin/metadata.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "name": "Empty_Policy", - "model": "", - "genre": "admin", - "description": "Empty Policy", - - "subject_categories": [], - - "action_categories": [], - - "object_categories": [] -} diff --git a/moon_orchestrator/conf/policies/policy_empty_admin/metarule.json b/moon_orchestrator/conf/policies/policy_empty_admin/metarule.json deleted file mode 100644 index 7acd8848..00000000 --- a/moon_orchestrator/conf/policies/policy_empty_admin/metarule.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "sub_meta_rules": { - "mls_rule": { - "subject_categories": [], - "action_categories": [], - "object_categories": [], - "algorithm": "" - } - }, - "aggregation": "" -} - diff --git a/moon_orchestrator/conf/policies/policy_empty_admin/perimeter.json b/moon_orchestrator/conf/policies/policy_empty_admin/perimeter.json deleted file mode 100644 index 54dbfc31..00000000 --- a/moon_orchestrator/conf/policies/policy_empty_admin/perimeter.json +++ /dev/null @@ -1,39 +0,0 @@ -{ - "subjects": [], - "actions": [ - "read", - "write" - ], - "objects": [ - "authz.subjects", - "authz.objects", - "authz.actions", - "authz.subject_categories", - "authz.object_categories", - "authz.action_categories", - "authz.subject_scopes", - "authz.object_scopes", - "authz.action_scopes", - "authz.subject_assignments", - "authz.object_assignments", - "authz.action_assignments", - "authz.aggregation_algorithm", - "authz.sub_meta_rules", - "authz.rules", - "admin.subjects", - "admin.objects", - "admin.actions", - "admin.subject_categories", - "admin.object_categories", - "admin.action_categories", - "admin.subject_scopes", - "admin.object_scopes", - "admin.action_scopes", - "admin.subject_assignments", - "admin.object_assignments", - "admin.action_assignments", - "admin.aggregation_algorithm", - "admin.sub_meta_rules", - "admin.rules" - ] -} diff --git a/moon_orchestrator/conf/policies/policy_empty_admin/rule.json b/moon_orchestrator/conf/policies/policy_empty_admin/rule.json deleted file mode 100644 index fe4fae5a..00000000 --- a/moon_orchestrator/conf/policies/policy_empty_admin/rule.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "mls_rule":[] -} diff --git a/moon_orchestrator/conf/policies/policy_empty_admin/scope.json b/moon_orchestrator/conf/policies/policy_empty_admin/scope.json deleted file mode 100644 index 1efebe6f..00000000 --- a/moon_orchestrator/conf/policies/policy_empty_admin/scope.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "subject_scopes": {}, - - "action_scopes": {}, - - "object_scopes": {} -} diff --git a/moon_orchestrator/conf/policies/policy_empty_authz/assignment.json b/moon_orchestrator/conf/policies/policy_empty_authz/assignment.json deleted file mode 100644 index 24018a09..00000000 --- a/moon_orchestrator/conf/policies/policy_empty_authz/assignment.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "subject_assignments": {}, - - "action_assignments": {}, - - "object_assignments": {} -} diff --git a/moon_orchestrator/conf/policies/policy_empty_authz/metadata.json b/moon_orchestrator/conf/policies/policy_empty_authz/metadata.json deleted file mode 100644 index 4f300d78..00000000 --- a/moon_orchestrator/conf/policies/policy_empty_authz/metadata.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "name": "MLS_Policy", - "model": "MLS", - "genre": "authz", - "description": "Multi Level Security Policy", - - "subject_categories": [], - - "action_categories": [], - - "object_categories": [] -} diff --git a/moon_orchestrator/conf/policies/policy_empty_authz/metarule.json b/moon_orchestrator/conf/policies/policy_empty_authz/metarule.json deleted file mode 100644 index 7acd8848..00000000 --- a/moon_orchestrator/conf/policies/policy_empty_authz/metarule.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "sub_meta_rules": { - "mls_rule": { - "subject_categories": [], - "action_categories": [], - "object_categories": [], - "algorithm": "" - } - }, - "aggregation": "" -} - diff --git a/moon_orchestrator/conf/policies/policy_empty_authz/perimeter.json b/moon_orchestrator/conf/policies/policy_empty_authz/perimeter.json deleted file mode 100644 index 9da8a8c0..00000000 --- a/moon_orchestrator/conf/policies/policy_empty_authz/perimeter.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "subjects": [], - "actions": [], - "objects": [] -} diff --git a/moon_orchestrator/conf/policies/policy_empty_authz/rule.json b/moon_orchestrator/conf/policies/policy_empty_authz/rule.json deleted file mode 100644 index fe4fae5a..00000000 --- a/moon_orchestrator/conf/policies/policy_empty_authz/rule.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "mls_rule":[] -} diff --git a/moon_orchestrator/conf/policies/policy_empty_authz/scope.json b/moon_orchestrator/conf/policies/policy_empty_authz/scope.json deleted file mode 100644 index 1efebe6f..00000000 --- a/moon_orchestrator/conf/policies/policy_empty_authz/scope.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "subject_scopes": {}, - - "action_scopes": {}, - - "object_scopes": {} -} diff --git a/moon_orchestrator/conf/policies/policy_mls_authz/assignment.json b/moon_orchestrator/conf/policies/policy_mls_authz/assignment.json deleted file mode 100644 index 0712dfbc..00000000 --- a/moon_orchestrator/conf/policies/policy_mls_authz/assignment.json +++ /dev/null @@ -1,29 +0,0 @@ -{ - "subject_assignments": { - "subject_security_level":{ - "admin": ["high"], - "demo": ["medium"] - } - }, - - "action_assignments": { - "resource_action":{ - "pause": ["vm_admin"], - "unpause": ["vm_admin"], - "start": ["vm_admin"], - "stop": ["vm_admin"], - "list": ["vm_access", "vm_admin"], - "create": ["vm_admin"], - "storage_list": ["storage_access"], - "download": ["storage_access"], - "post": ["storage_admin"], - "upload": ["storage_admin"] - } - }, - - "object_assignments": { - "object_security_level": { - "servers": ["low"] - } - } -} diff --git a/moon_orchestrator/conf/policies/policy_mls_authz/metadata.json b/moon_orchestrator/conf/policies/policy_mls_authz/metadata.json deleted file mode 100644 index c419c815..00000000 --- a/moon_orchestrator/conf/policies/policy_mls_authz/metadata.json +++ /dev/null @@ -1,18 +0,0 @@ -{ - "name": "MLS_Policy", - "model": "MLS", - "genre": "authz", - "description": "Multi Level Security Policy", - - "subject_categories": [ - "subject_security_level" - ], - - "action_categories": [ - "resource_action" - ], - - "object_categories": [ - "object_security_level" - ] -} diff --git a/moon_orchestrator/conf/policies/policy_mls_authz/metarule.json b/moon_orchestrator/conf/policies/policy_mls_authz/metarule.json deleted file mode 100644 index e068927c..00000000 --- a/moon_orchestrator/conf/policies/policy_mls_authz/metarule.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "sub_meta_rules": { - "mls_rule": { - "subject_categories": ["subject_security_level"], - "action_categories": ["resource_action"], - "object_categories": ["object_security_level"], - "algorithm": "inclusion" - } - }, - "aggregation": "all_true" -} - diff --git a/moon_orchestrator/conf/policies/policy_mls_authz/perimeter.json b/moon_orchestrator/conf/policies/policy_mls_authz/perimeter.json deleted file mode 100644 index 47a8ee45..00000000 --- a/moon_orchestrator/conf/policies/policy_mls_authz/perimeter.json +++ /dev/null @@ -1,21 +0,0 @@ -{ - "subjects": [ - "admin", - "demo" - ], - "actions": [ - "pause", - "unpause", - "start", - "stop", - "create", - "list", - "upload", - "download", - "post", - "storage_list" - ], - "objects": [ - "servers" - ] -} diff --git a/moon_orchestrator/conf/policies/policy_mls_authz/rule.json b/moon_orchestrator/conf/policies/policy_mls_authz/rule.json deleted file mode 100644 index b17dc822..00000000 --- a/moon_orchestrator/conf/policies/policy_mls_authz/rule.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "mls_rule":[ - ["high", "vm_admin", "medium"], - ["high", "vm_admin", "low"], - ["medium", "vm_admin", "low"], - ["high", "vm_access", "medium"], - ["high", "vm_access", "low"], - ["medium", "vm_access", "low"], - ["high", "storage_admin", "medium"], - ["high", "storage_admin", "low"], - ["medium", "storage_admin", "low"], - ["high", "storage_access", "medium"], - ["high", "storage_access", "low"], - ["medium", "storage_access", "low"] - ] -} diff --git a/moon_orchestrator/conf/policies/policy_mls_authz/scope.json b/moon_orchestrator/conf/policies/policy_mls_authz/scope.json deleted file mode 100644 index 6cc1c28e..00000000 --- a/moon_orchestrator/conf/policies/policy_mls_authz/scope.json +++ /dev/null @@ -1,26 +0,0 @@ -{ - "subject_scopes": { - "subject_security_level": [ - "high", - "medium", - "low" - ] - }, - - "action_scopes": { - "resource_action": [ - "vm_admin", - "vm_access", - "storage_admin", - "storage_access" - ] - }, - - "object_scopes": { - "object_security_level": [ - "high", - "medium", - "low" - ] - } -} diff --git a/moon_orchestrator/conf/policies/policy_rbac_admin/assignment.json b/moon_orchestrator/conf/policies/policy_rbac_admin/assignment.json deleted file mode 100644 index f2378333..00000000 --- a/moon_orchestrator/conf/policies/policy_rbac_admin/assignment.json +++ /dev/null @@ -1,48 +0,0 @@ -{ - "subject_assignments": { - "role": { - "admin": ["root_role"], - "demo": ["dev_role"] - } - }, - "action_assignments": { - "action_id": { - "read": ["read"], - "write": ["write"] - } - }, - "object_assignments": { - "object_id": { - "authz.subjects": ["authz.subjects"], - "authz.objects": ["authz.objects"], - "authz.actions": ["authz.actions"], - "authz.subject_categories": ["authz.subject_categories"], - "authz.object_categories": ["authz.object_categories"], - "authz.action_categories": ["authz.action_categories"], - "authz.subject_scopes": ["authz.subject_scopes"], - "authz.object_scopes": ["authz.object_scopes"], - "authz.action_scopes": ["authz.action_scopes"], - "authz.subject_assignments": ["authz.subject_assignments"], - "authz.object_assignments": ["authz.object_assignments"], - "authz.action_assignments": ["authz.action_assignments"], - "authz.aggregation_algorithm": ["authz.aggregation_algorithm"], - "authz.sub_meta_rules": ["authz.sub_meta_rules"], - "authz.rules": ["authz.rules"], - "admin.subjects": ["admin.subjects"], - "admin.objects": ["admin.objects"], - "admin.actions": ["admin.actions"], - "admin.subject_categories": ["admin.subject_categories"], - "admin.object_categories": ["admin.object_categories"], - "admin.action_categories": ["admin.action_categories"], - "admin.subject_scopes": ["admin.subject_scopes"], - "admin.object_scopes": ["admin.object_scopes"], - "admin.action_scopes": ["admin.action_scopes"], - "admin.subject_assignments": ["admin.subject_assignments"], - "admin.object_assignments": ["admin.object_assignments"], - "admin.action_assignments": ["admin.action_assignments"], - "admin.aggregation_algorithm": ["admin.aggregation_algorithm"], - "admin.sub_meta_rules": ["admin.sub_meta_rules"], - "admin.rules": ["admin.rules"] - } - } -} diff --git a/moon_orchestrator/conf/policies/policy_rbac_admin/metadata.json b/moon_orchestrator/conf/policies/policy_rbac_admin/metadata.json deleted file mode 100644 index 9ee8a11d..00000000 --- a/moon_orchestrator/conf/policies/policy_rbac_admin/metadata.json +++ /dev/null @@ -1,18 +0,0 @@ -{ - "name": "RBAC Admin Policy", - "model": "RBAC", - "genre": "admin", - "description": "", - - "subject_categories": [ - "role" - ], - - "action_categories": [ - "action_id" - ], - - "object_categories": [ - "object_id" - ] -} diff --git a/moon_orchestrator/conf/policies/policy_rbac_admin/metarule.json b/moon_orchestrator/conf/policies/policy_rbac_admin/metarule.json deleted file mode 100644 index 86dbfad2..00000000 --- a/moon_orchestrator/conf/policies/policy_rbac_admin/metarule.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "sub_meta_rules": { - "rbac_rule": { - "subject_categories": ["role"], - "action_categories": ["action_id"], - "object_categories": ["object_id"], - "algorithm": "inclusion" - } - }, - "aggregation": "all_true" -} - diff --git a/moon_orchestrator/conf/policies/policy_rbac_admin/perimeter.json b/moon_orchestrator/conf/policies/policy_rbac_admin/perimeter.json deleted file mode 100644 index 1155533e..00000000 --- a/moon_orchestrator/conf/policies/policy_rbac_admin/perimeter.json +++ /dev/null @@ -1,42 +0,0 @@ -{ - "subjects": [ - "admin", - "demo" - ], - "actions": [ - "read", - "write" - ], - "objects": [ - "authz.subjects", - "authz.objects", - "authz.actions", - "authz.subject_categories", - "authz.object_categories", - "authz.action_categories", - "authz.subject_scopes", - "authz.object_scopes", - "authz.action_scopes", - "authz.subject_assignments", - "authz.object_assignments", - "authz.action_assignments", - "authz.aggregation_algorithm", - "authz.sub_meta_rules", - "authz.rules", - "admin.subjects", - "admin.objects", - "admin.actions", - "admin.subject_categories", - "admin.object_categories", - "admin.action_categories", - "admin.subject_scopes", - "admin.object_scopes", - "admin.action_scopes", - "admin.subject_assignments", - "admin.object_assignments", - "admin.action_assignments", - "admin.aggregation_algorithm", - "admin.sub_meta_rules", - "admin.rules" - ] -} diff --git a/moon_orchestrator/conf/policies/policy_rbac_admin/rule.json b/moon_orchestrator/conf/policies/policy_rbac_admin/rule.json deleted file mode 100644 index c89ceff3..00000000 --- a/moon_orchestrator/conf/policies/policy_rbac_admin/rule.json +++ /dev/null @@ -1,94 +0,0 @@ -{ - "rbac_rule":[ - ["root_role" , "read", "authz.subjects"], - ["root_role" , "read", "authz.objects"], - ["root_role" , "read", "authz.actions"], - ["root_role" , "read", "authz.subject_categories"], - ["root_role" , "read", "authz.object_categories"], - ["root_role" , "read", "authz.action_categories"], - ["root_role" , "read", "authz.subject_scopes"], - ["root_role" , "read", "authz.object_scopes"], - ["root_role" , "read", "authz.action_scopes"], - ["root_role" , "read", "authz.subject_assignments"], - ["root_role" , "read", "authz.object_assignments"], - ["root_role" , "read", "authz.action_assignments"], - ["root_role" , "read", "authz.aggregation_algorithm"], - ["root_role" , "read", "authz.sub_meta_rules"], - ["root_role" , "read", "authz.rules"], - ["root_role" , "write", "authz.subjects"], - ["root_role" , "write", "authz.objects"], - ["root_role" , "write", "authz.actions"], - ["root_role" , "write", "authz.subject_categories"], - ["root_role" , "write", "authz.object_categories"], - ["root_role" , "write", "authz.action_categories"], - ["root_role" , "write", "authz.subject_scopes"], - ["root_role" , "write", "authz.object_scopes"], - ["root_role" , "write", "authz.action_scopes"], - ["root_role" , "write", "authz.subject_assignments"], - ["root_role" , "write", "authz.object_assignments"], - ["root_role" , "write", "authz.action_assignments"], - ["root_role" , "write", "authz.aggregation_algorithm"], - ["root_role" , "write", "authz.sub_meta_rules"], - ["root_role" , "write", "authz.rules"], - ["root_role" , "read", "admin.subjects"], - ["root_role" , "read", "admin.objects"], - ["root_role" , "read", "admin.actions"], - ["root_role" , "read", "admin.subject_categories"], - ["root_role" , "read", "admin.object_categories"], - ["root_role" , "read", "admin.action_categories"], - ["root_role" , "read", "admin.subject_scopes"], - ["root_role" , "read", "admin.object_scopes"], - ["root_role" , "read", "admin.action_scopes"], - ["root_role" , "read", "admin.subject_assignments"], - ["root_role" , "read", "admin.object_assignments"], - ["root_role" , "read", "admin.action_assignments"], - ["root_role" , "read", "admin.aggregation_algorithm"], - ["root_role" , "read", "admin.sub_meta_rules"], - ["root_role" , "read", "admin.rules"], - ["root_role" , "write", "admin.subjects"], - ["root_role" , "write", "admin.objects"], - ["root_role" , "write", "admin.actions"], - ["root_role" , "write", "admin.subject_categories"], - ["root_role" , "write", "admin.object_categories"], - ["root_role" , "write", "admin.action_categories"], - ["root_role" , "write", "admin.subject_scopes"], - ["root_role" , "write", "admin.object_scopes"], - ["root_role" , "write", "admin.action_scopes"], - ["root_role" , "write", "admin.subject_assignments"], - ["root_role" , "write", "admin.object_assignments"], - ["root_role" , "write", "admin.action_assignments"], - ["root_role" , "write", "admin.aggregation_algorithm"], - ["root_role" , "write", "admin.sub_meta_rules"], - ["root_role" , "write", "admin.rules"], - ["dev_role" , "read", "authz.subjects"], - ["dev_role" , "read", "authz.objects"], - ["dev_role" , "read", "authz.actions"], - ["dev_role" , "read", "authz.subject_categories"], - ["dev_role" , "read", "authz.object_categories"], - ["dev_role" , "read", "authz.action_categories"], - ["dev_role" , "read", "authz.subject_scopes"], - ["dev_role" , "read", "authz.object_scopes"], - ["dev_role" , "read", "authz.action_scopes"], - ["dev_role" , "read", "authz.subject_assignments"], - ["dev_role" , "read", "authz.object_assignments"], - ["dev_role" , "read", "authz.action_assignments"], - ["dev_role" , "read", "authz.aggregation_algorithm"], - ["dev_role" , "read", "authz.sub_meta_rules"], - ["dev_role" , "read", "authz.rules"], - ["dev_role" , "read", "admin.subjects"], - ["dev_role" , "read", "admin.objects"], - ["dev_role" , "read", "admin.actions"], - ["dev_role" , "read", "admin.subject_categories"], - ["dev_role" , "read", "admin.object_categories"], - ["dev_role" , "read", "admin.action_categories"], - ["dev_role" , "read", "admin.subject_scopes"], - ["dev_role" , "read", "admin.object_scopes"], - ["dev_role" , "read", "admin.action_scopes"], - ["dev_role" , "read", "admin.subject_assignments"], - ["dev_role" , "read", "admin.object_assignments"], - ["dev_role" , "read", "admin.action_assignments"], - ["dev_role" , "read", "admin.aggregation_algorithm"], - ["dev_role" , "read", "admin.sub_meta_rules"], - ["dev_role" , "read", "admin.rules"] - ] -} diff --git a/moon_orchestrator/conf/policies/policy_rbac_admin/scope.json b/moon_orchestrator/conf/policies/policy_rbac_admin/scope.json deleted file mode 100644 index 149056a6..00000000 --- a/moon_orchestrator/conf/policies/policy_rbac_admin/scope.json +++ /dev/null @@ -1,48 +0,0 @@ -{ - "subject_scopes": { - "role": [ - "root_role", - "dev_role" - ] - }, - "action_scopes": { - "action_id": [ - "read", - "write" - ] - }, - "object_scopes": { - "object_id": [ - "authz.subjects", - "authz.objects", - "authz.actions", - "authz.subject_categories", - "authz.object_categories", - "authz.action_categories", - "authz.subject_scopes", - "authz.object_scopes", - "authz.action_scopes", - "authz.subject_assignments", - "authz.object_assignments", - "authz.action_assignments", - "authz.aggregation_algorithm", - "authz.sub_meta_rules", - "authz.rules", - "admin.subjects", - "admin.objects", - "admin.actions", - "admin.subject_categories", - "admin.object_categories", - "admin.action_categories", - "admin.subject_scopes", - "admin.object_scopes", - "admin.action_scopes", - "admin.subject_assignments", - "admin.object_assignments", - "admin.action_assignments", - "admin.aggregation_algorithm", - "admin.sub_meta_rules", - "admin.rules" - ] - } -} diff --git a/moon_orchestrator/conf/policies/policy_root/assignment.json b/moon_orchestrator/conf/policies/policy_root/assignment.json deleted file mode 100644 index e849ae13..00000000 --- a/moon_orchestrator/conf/policies/policy_root/assignment.json +++ /dev/null @@ -1,39 +0,0 @@ -{ - "subject_assignments": { - "role": { - "admin": ["root_role"] - } - }, - - "action_assignments": { - "action_id": { - "read": ["read"], - "write": ["write"] - } - }, - - "object_assignments": { - "object_id": { - "templates": ["templates"], - "sub_meta_rule_algorithms": ["sub_meta_rule_algorithms"], - "aggregation_algorithms": ["aggregation_algorithms"], - "tenants": ["tenants"], - "intra_extensions": ["intra_extensions"], - "admin.subjects": ["admin.subjects"], - "admin.objects": ["admin.objects"], - "admin.actions": ["admin.actions"], - "admin.subject_categories": ["admin.subject_categories"], - "admin.object_categories": ["admin.object_categories"], - "admin.action_categories": ["admin.action_categories"], - "admin.subject_category_scopes": ["admin.subject_category_scopes"], - "admin.object_category_scopes": ["admin.object_category_scopes"], - "admin.action_category_scopes": ["admin.action_category_scopes"], - "admin.subject_assignments": ["admin.subject_assignments"], - "admin.object_assignments": ["admin.object_assignments"], - "admin.action_assignments": ["admin.action_assignments"], - "admin.aggregation_algorithm": ["admin.aggregation_algorithm"], - "admin.sub_meta_rules": ["admin.sub_meta_rules"], - "admin.rules": ["admin.rules"] - } - } -} diff --git a/moon_orchestrator/conf/policies/policy_root/metadata.json b/moon_orchestrator/conf/policies/policy_root/metadata.json deleted file mode 100644 index 9dd7a928..00000000 --- a/moon_orchestrator/conf/policies/policy_root/metadata.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "name": "Root Policy", - "model": "RBAC", - "genre": "admin", - "description": "root extension", - "pdp_pipeline": ["authz:rbac_rule"], - - "subject_categories": [ - "role" - ], - - "action_categories": [ - "action_id" - ], - - "object_categories": [ - "object_id" - ] -} diff --git a/moon_orchestrator/conf/policies/policy_root/metarule.json b/moon_orchestrator/conf/policies/policy_root/metarule.json deleted file mode 100644 index 86dbfad2..00000000 --- a/moon_orchestrator/conf/policies/policy_root/metarule.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "sub_meta_rules": { - "rbac_rule": { - "subject_categories": ["role"], - "action_categories": ["action_id"], - "object_categories": ["object_id"], - "algorithm": "inclusion" - } - }, - "aggregation": "all_true" -} - diff --git a/moon_orchestrator/conf/policies/policy_root/perimeter.json b/moon_orchestrator/conf/policies/policy_root/perimeter.json deleted file mode 100644 index 788a27f2..00000000 --- a/moon_orchestrator/conf/policies/policy_root/perimeter.json +++ /dev/null @@ -1,31 +0,0 @@ -{ - "subjects": [ - "admin" - ], - "actions": [ - "read", - "write" - ], - "objects": [ - "templates", - "aggregation_algorithms", - "sub_meta_rule_algorithms", - "tenants", - "intra_extensions", - "admin.subjects", - "admin.objects", - "admin.actions", - "admin.subject_categories", - "admin.object_categories", - "admin.action_categories", - "admin.subject_category_scopes", - "admin.object_category_scopes", - "admin.action_category_scopes", - "admin.subject_assignments", - "admin.object_assignments", - "admin.action_assignments", - "admin.aggregation_algorithm", - "admin.sub_meta_rules", - "admin.rules" - ] -} diff --git a/moon_orchestrator/conf/policies/policy_root/rule.json b/moon_orchestrator/conf/policies/policy_root/rule.json deleted file mode 100644 index 9bbd5e4c..00000000 --- a/moon_orchestrator/conf/policies/policy_root/rule.json +++ /dev/null @@ -1,44 +0,0 @@ -{ - "rbac_rule":[ - ["root_role" , "read", "templates"], - ["root_role" , "read", "aggregation_algorithms"], - ["root_role" , "read", "sub_meta_rule_algorithms"], - ["root_role" , "read", "tenants"], - ["root_role" , "read", "intra_extensions"], - ["root_role" , "write", "templates"], - ["root_role" , "write", "aggregation_algorithms"], - ["root_role" , "write", "sub_meta_rule_algorithms"], - ["root_role" , "write", "tenants"], - ["root_role" , "write", "intra_extensions"], - ["root_role" , "read", "admin.subjects"], - ["root_role" , "read", "admin.objects"], - ["root_role" , "read", "admin.actions"], - ["root_role" , "read", "admin.subject_categories"], - ["root_role" , "read", "admin.object_categories"], - ["root_role" , "read", "admin.action_categories"], - ["root_role" , "read", "admin.subject_category_scopes"], - ["root_role" , "read", "admin.object_category_scopes"], - ["root_role" , "read", "admin.action_category_scopes"], - ["root_role" , "read", "admin.subject_assignments"], - ["root_role" , "read", "admin.object_assignments"], - ["root_role" , "read", "admin.action_assignments"], - ["root_role" , "read", "admin.aggregation_algorithm"], - ["root_role" , "read", "admin.sub_meta_rules"], - ["root_role" , "read", "admin.rules"], - ["root_role" , "write", "admin.subjects"], - ["root_role" , "write", "admin.objects"], - ["root_role" , "write", "admin.actions"], - ["root_role" , "write", "admin.subject_categories"], - ["root_role" , "write", "admin.object_categories"], - ["root_role" , "write", "admin.action_categories"], - ["root_role" , "write", "admin.subject_category_scopes"], - ["root_role" , "write", "admin.object_category_scopes"], - ["root_role" , "write", "admin.action_category_scopes"], - ["root_role" , "write", "admin.subject_assignments"], - ["root_role" , "write", "admin.object_assignments"], - ["root_role" , "write", "admin.action_assignments"], - ["root_role" , "write", "admin.aggregation_algorithm"], - ["root_role" , "write", "admin.sub_meta_rules"], - ["root_role" , "write", "admin.rules"] - ] -} diff --git a/moon_orchestrator/conf/policies/policy_root/scope.json b/moon_orchestrator/conf/policies/policy_root/scope.json deleted file mode 100644 index 43f9ced8..00000000 --- a/moon_orchestrator/conf/policies/policy_root/scope.json +++ /dev/null @@ -1,39 +0,0 @@ -{ - "subject_scopes": { - "role": [ - "root_role" - ] - }, - - "action_scopes": { - "action_id": [ - "read", - "write" - ] - }, - - "object_scopes": { - "object_id": [ - "templates", - "aggregation_algorithms", - "sub_meta_rule_algorithms", - "tenants", - "intra_extensions", - "admin.subjects", - "admin.objects", - "admin.actions", - "admin.subject_categories", - "admin.object_categories", - "admin.action_categories", - "admin.subject_category_scopes", - "admin.object_category_scopes", - "admin.action_category_scopes", - "admin.subject_assignments", - "admin.object_assignments", - "admin.action_assignments", - "admin.aggregation_algorithm", - "admin.sub_meta_rules", - "admin.rules" - ] - } -} diff --git a/moon_orchestrator/moon_orchestrator/http_server.py b/moon_orchestrator/moon_orchestrator/http_server.py index e6a5ee57..62d785a2 100644 --- a/moon_orchestrator/moon_orchestrator/http_server.py +++ b/moon_orchestrator/moon_orchestrator/http_server.py @@ -18,7 +18,11 @@ from python_moonutilities import configuration, exceptions from python_moonutilities.misc import get_random_name from moon_orchestrator.drivers import get_driver -LOG = logging.getLogger("moon.orchestrator.http") +LOG = logging.getLogger("moon.orchestrator.http_server") + +__API__ = ( + Status, Logs + ) class Server: @@ -64,10 +68,6 @@ class Server: def run(self): raise NotImplementedError() -__API__ = ( - Status, Logs - ) - class Root(Resource): """ diff --git a/moon_orchestrator/moon_orchestrator/server.py b/moon_orchestrator/moon_orchestrator/server.py index 0cbd535a..ea1a0fbc 100644 --- a/moon_orchestrator/moon_orchestrator/server.py +++ b/moon_orchestrator/moon_orchestrator/server.py @@ -8,11 +8,9 @@ import logging from python_moonutilities import configuration, exceptions from moon_orchestrator.http_server import HTTPServer -LOG = logging.getLogger("moon.orchestrator") +LOG = logging.getLogger("moon.orchestrator.server") DOMAIN = "moon_orchestrator" -__CWD__ = os.path.dirname(os.path.abspath(__file__)) - def main(): configuration.init_logging() @@ -27,8 +25,7 @@ def main(): port = 80 configuration.add_component(uuid="orchestrator", 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) - return server + return HTTPServer(host=bind, port=port) if __name__ == '__main__': diff --git a/moon_wrapper/Dockerfile b/moon_wrapper/Dockerfile index 55e7208d..77ffaee9 100644 --- a/moon_wrapper/Dockerfile +++ b/moon_wrapper/Dockerfile @@ -1,12 +1,8 @@ -FROM ubuntu:latest - -RUN apt update && apt install python3.5 python3-pip -y -RUN pip3 install pip --upgrade +FROM python:3 ADD . /root WORKDIR /root/ -RUN pip3 install -r requirements.txt --upgrade -RUN pip3 install /root/dist/* --upgrade +RUN pip3 install -r requirements.txt RUN pip3 install . CMD ["python3", "-m", "moon_wrapper"] diff --git a/moon_wrapper/README.md b/moon_wrapper/README.md index 4e8fd05c..cdd043a9 100644 --- a/moon_wrapper/README.md +++ b/moon_wrapper/README.md @@ -1,5 +1,4 @@ -Wrapper module for the Moon project -=================================== +# moon_wrapper This package contains the core module for the Moon project It is designed to provide authorization features to all OpenStack components. diff --git a/moon_wrapper/moon_wrapper/api/wrapper.py b/moon_wrapper/moon_wrapper/api/oslowrapper.py index e1ce783a..a422ee42 100644 --- a/moon_wrapper/moon_wrapper/api/wrapper.py +++ b/moon_wrapper/moon_wrapper/api/oslowrapper.py @@ -19,14 +19,14 @@ __version__ = "0.1.0" LOG = logging.getLogger("moon.wrapper.api." + __name__) -class Wrapper(Resource): +class OsloWrapper(Resource): """ Endpoint for authz requests """ __urls__ = ( - "/authz", - "/authz/", + "/authz/oslo", + "/authz/oslo/", ) def __init__(self, **kwargs): @@ -34,10 +34,6 @@ class Wrapper(Resource): self.CACHE = kwargs.get("cache", {}) self.TIMEOUT = 5 - # def get(self): - # LOG.info("GET") - # return self.manage_data() - def post(self): LOG.debug("POST {}".format(request.form)) response = flask.make_response("False") @@ -101,6 +97,7 @@ class Wrapper(Resource): rule = data.get('rule', "") _subject = self.__get_subject(target, credentials) _object = self.__get_object(target, credentials) + _action = rule _project_id = self.__get_project_id(target, credentials) LOG.debug("POST with args project={} / " "subject={} - object={} - action={}".format( @@ -112,7 +109,7 @@ class Wrapper(Resource): _project_id, _subject, _object, - rule + _action )) LOG.debug("Get interface {}".format(req.text)) if req.status_code == 200: diff --git a/moon_wrapper/moon_wrapper/http_server.py b/moon_wrapper/moon_wrapper/http_server.py index 1b429bc5..8027a0d3 100644 --- a/moon_wrapper/moon_wrapper/http_server.py +++ b/moon_wrapper/moon_wrapper/http_server.py @@ -8,15 +8,19 @@ from flask_restful import Resource, Api import logging from moon_wrapper import __version__ from moon_wrapper.api.generic import Status, Logs, API -from moon_wrapper.api.wrapper import Wrapper +from moon_wrapper.api.oslowrapper import OsloWrapper from python_moonutilities.cache import Cache from python_moonutilities import configuration, exceptions -logger = logging.getLogger("moon.wrapper.http") +logger = logging.getLogger("moon.wrapper.http_server") CACHE = Cache() +__API__ = ( + Status, Logs, API + ) + class Server: """Base class for HTTP server""" @@ -61,10 +65,6 @@ class Server: def run(self): raise NotImplementedError() -__API__ = ( - Status, Logs, API - ) - class Root(Resource): """ @@ -127,7 +127,7 @@ class HTTPServer(Server): for api in __API__: self.api.add_resource(api, *api.__urls__) - self.api.add_resource(Wrapper, *Wrapper.__urls__, + self.api.add_resource(OsloWrapper, *OsloWrapper.__urls__, resource_class_kwargs={ "orchestrator_url": self.orchestrator_url, "cache": CACHE, @@ -136,5 +136,4 @@ class HTTPServer(Server): 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/moon_wrapper/moon_wrapper/server.py b/moon_wrapper/moon_wrapper/server.py index 2f236c4f..280fdb68 100644 --- a/moon_wrapper/moon_wrapper/server.py +++ b/moon_wrapper/moon_wrapper/server.py @@ -7,7 +7,7 @@ import logging from python_moonutilities import configuration, exceptions from moon_wrapper.http_server import HTTPServer -LOG = logging.getLogger("moon.wrapper") +LOG = logging.getLogger("moon.wrapper.server") def main(): @@ -24,8 +24,7 @@ def main(): port = 80 configuration.add_component(uuid="wrapper", 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) - return server + return HTTPServer(host=bind, port=port) if __name__ == '__main__': diff --git a/python_moonclient/Changelog b/python_moonclient/Changelog index 854200cb..f6f6c3a4 100644 --- a/python_moonclient/Changelog +++ b/python_moonclient/Changelog @@ -9,4 +9,24 @@ CHANGES 0.1.0 ----- -- First version of the python-moonclient
\ No newline at end of file +- First version of the python-moonclient + +1.0.0 +----- +- First public version of the python-moonclient + +1.0.1 +----- +- Fix a bug in configuration + +1.1.0 +----- +- Add some commands: + - moon_get_pdp + - moon_delete_pdp + - moon_delete_policy + - moon_map_pdp_to_project +- Update some commands: + - moon_create_pdp + - moon_send_authz_to_wrapper +- Fix a bug in pdp library diff --git a/python_moonclient/README.md b/python_moonclient/README.md index d1ebc786..1a9731e7 100644 --- a/python_moonclient/README.md +++ b/python_moonclient/README.md @@ -1,4 +1,4 @@ -# python-moonclient Package +# python-moonclient This package contains the core module for the Moon project. It is designed to provide authorization feature to all OpenStack components. @@ -11,13 +11,13 @@ python_moonutilities is a common Python lib for other Moon Python packages ## Build ### Build Python Package ```bash -cd ${MOON_HOME}/moonv4/python_moonclient +cd ${MOON_HOME}/python_moonclient python3 setup.py sdist bdist_wheel ``` ### Push Python Package to PIP ```bash -cd ${MOON_HOME}/moonv4/python_moonclient +cd ${MOON_HOME}/python_moonclient gpg --detach-sign -u "${GPG_ID}" -a dist/python_moonclient-X.Y.Z-py3-none-any.whl gpg --detach-sign -u "${GPG_ID}" -a dist/python_moonclient-X.Y.Z.tar.gz twine upload dist/python_moonclient-X.Y.Z-py3-none-any.whl dist/python_moonclient-X.Y.Z-py3-none-any.whl.asc @@ -28,6 +28,6 @@ twine upload dist/python_moonclient-X.Y.Z.tar.gz dist/python_moonclient-X.Y.Z.ta ### Python Unit Test launch Docker for Python unit tests ```bash -cd ${MOON_HOME}/moonv4/python_moonclient +cd ${MOON_HOME}/python_moonclient docker run --rm --volume $(pwd):/data wukongsun/moon_python_unit_test:latest ``` diff --git a/python_moonclient/python_moonclient/__init__.py b/python_moonclient/python_moonclient/__init__.py index d7cdd111..2302dea9 100644 --- a/python_moonclient/python_moonclient/__init__.py +++ b/python_moonclient/python_moonclient/__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__ = "0.0.1" +__version__ = "1.1.0" diff --git a/python_moonclient/python_moonclient/authz.py b/python_moonclient/python_moonclient/authz.py index 9458767e..b90bf00f 100644 --- a/python_moonclient/python_moonclient/authz.py +++ b/python_moonclient/python_moonclient/authz.py @@ -13,7 +13,7 @@ HOST_KEYSTONE = None PORT_KEYSTONE = None lock = threading.Lock() -logger = logging.getLogger(__name__) +logger = logging.getLogger("moonclient.authz") def _construct_payload(creds, current_rule, enforcer, target): @@ -122,7 +122,7 @@ def send_requests(scenario, authz_host, authz_port, keystone_project_id, request while request_cpt < limit: rule = (random.choice(SUBJECTS), random.choice(OBJECTS), random.choice(ACTIONS)) if destination.lower() == "wrapper": - url = "http://{}:{}/authz".format(authz_host, authz_port) + url = "http://{}:{}/authz/oslo".format(authz_host, authz_port) data = { 'target': { "user_id": random.choice(SUBJECTS), diff --git a/python_moonclient/python_moonclient/config.py b/python_moonclient/python_moonclient/config.py index d6317820..300ebf1a 100644 --- a/python_moonclient/python_moonclient/config.py +++ b/python_moonclient/python_moonclient/config.py @@ -21,17 +21,36 @@ def get_configuration(consul_host, consul_port, key): def get_config_data(consul_host, consul_port): conf_data = dict() - conf_data['manager_host'] = get_configuration(consul_host, consul_port, - 'components/manager')['components/manager']['external']['hostname'] - conf_data['manager_port'] = get_configuration(consul_host, consul_port, - 'components/manager')['components/manager']['external']['port'] - # conf_data['authz_host'] = get_configuration(consul_host, consul_port, - # 'components/interface')['components/interface']['external']['hostname'] - # conf_data['authz_port'] = get_configuration(consul_host, consul_port, - # 'components/interface')['components/interface']['external']['port'] - conf_data['keystone_host'] = get_configuration(consul_host, consul_port, - 'openstack/keystone')['openstack/keystone']['external']['url'] - # conf_data['keystone_port'] = '5000' + conf_data['manager_host'] = get_configuration( + consul_host, consul_port, + 'components/manager')['components/manager']['external']['hostname'] + conf_data['manager_port'] = get_configuration( + consul_host, consul_port, + 'components/manager')['components/manager']['external']['port'] + try: + requests.get("http://{}:{}/".format( + conf_data['manager_host'], + conf_data['manager_port'] + ), + timeout=2) + except requests.exceptions.ConnectionError: + conf_data['manager_host'] = get_configuration(consul_host, consul_port, + 'components/manager')[ + 'components/manager']['hostname'] + conf_data['manager_port'] = get_configuration(consul_host, consul_port, + 'components/manager')[ + 'components/manager']['port'] + + conf_data['keystone_host'] = get_configuration( + consul_host, consul_port, + 'openstack/keystone')['openstack/keystone']['external']['url'] + try: + requests.get(conf_data['keystone_host'], timeout=2) + except requests.exceptions.ConnectionError: + conf_data['keystone_host'] = get_configuration( + consul_host, consul_port, + 'openstack/keystone')['openstack/keystone']['url'] + conf_data['keystone_user'] = get_configuration(consul_host, consul_port, 'openstack/keystone')['openstack/keystone']['user'] conf_data['keystone_password'] = get_configuration(consul_host, consul_port, @@ -39,6 +58,3 @@ def get_config_data(consul_host, consul_port): conf_data['keystone_project'] = get_configuration(consul_host, consul_port, 'openstack/keystone')['openstack/keystone']['project'] return conf_data - -# get_conf_data('88.88.88.2', '30005') -# get_conf_data('127.0.0.1', 8082) diff --git a/python_moonclient/python_moonclient/parse.py b/python_moonclient/python_moonclient/parse.py index 34a4a996..d31b3ebd 100644 --- a/python_moonclient/python_moonclient/parse.py +++ b/python_moonclient/python_moonclient/parse.py @@ -2,18 +2,16 @@ import logging import argparse -logger = None +logger = logging.getLogger("python_moonclient.parse") def parse(): - global logger - logger = logging.getLogger(__name__) requests_log = logging.getLogger("requests.packages.urllib3") requests_log.setLevel(logging.WARNING) requests_log.propagate = True parser = argparse.ArgumentParser() - parser.add_argument('filename', help='scenario filename', nargs=1) + parser.add_argument('filename', help='scenario filename', nargs="*") parser.add_argument("--verbose", "-v", action='store_true', help="verbose mode") parser.add_argument("--debug", "-d", action='store_true', @@ -31,8 +29,8 @@ def parse(): default="127.0.0.1") parser.add_argument("--consul-port", help="Set the port of the consult server" - "(default: 8082).", - default="8082") + "(default: 30005).", + default="30005") parser.add_argument("--authz-host", help="Set the name of the authz server to test" "(default: 127.0.0.1).", diff --git a/python_moonclient/python_moonclient/pdp.py b/python_moonclient/python_moonclient/pdp.py index a7c75a61..6841a276 100644 --- a/python_moonclient/python_moonclient/pdp.py +++ b/python_moonclient/python_moonclient/pdp.py @@ -3,16 +3,15 @@ import logging import requests from python_moonclient import config -logger = logging.getLogger("moonforming.utils.policies") +logger = logging.getLogger("python_moonclient.pdp") + URL = None -HEADER = None +HEADERS = None KEYSTONE_USER = None KEYSTONE_PASSWORD = None KEYSTONE_PROJECT = None KEYSTONE_SERVER = None -# config = utils.config.get_config_data() - pdp_template = { "name": "test_pdp", @@ -24,12 +23,12 @@ pdp_template = { def init(consul_host, consul_port): conf_data = config.get_config_data(consul_host, consul_port) - global URL, HEADER, KEYSTONE_USER, KEYSTONE_PASSWORD, KEYSTONE_PROJECT, KEYSTONE_SERVER + global URL, HEADERS, KEYSTONE_USER, KEYSTONE_PASSWORD, KEYSTONE_PROJECT, KEYSTONE_SERVER URL = "http://{}:{}".format( conf_data['manager_host'], conf_data['manager_port']) # URL = URL + "{}" - HEADER = {"content-type": "application/json"} + HEADERS = {"content-type": "application/json"} KEYSTONE_USER = conf_data['keystone_user'] KEYSTONE_PASSWORD = conf_data['keystone_password'] KEYSTONE_PROJECT = conf_data['keystone_project'] @@ -170,7 +169,8 @@ def update_pdp(pdp_id, policy_id=None): def map_to_keystone(pdp_id, keystone_project_id): - req = requests.patch(URL + "/pdp/{}".format(pdp_id), json={"keystone_project_id": keystone_project_id}, + req = requests.patch(URL + "/pdp/{}".format(pdp_id), + json={"keystone_project_id": keystone_project_id}, headers=HEADERS) assert req.status_code == 200 result = req.json() @@ -178,8 +178,8 @@ def map_to_keystone(pdp_id, keystone_project_id): if "result" in result: assert result["result"] assert pdp_id in result['pdps'] - assert "name" in result['pdps'][pdp_id] - assert pdp_template["name"] == result['pdps'][pdp_id]["name"] + # assert "name" in result['pdps'][pdp_id] + # assert pdp_template["name"] == result['pdps'][pdp_id]["name"] return pdp_id @@ -195,11 +195,11 @@ def delete_pdp(pdp_id): def create_pdp(scenario, policy_id=None, project_id=None): logger.info("Creating PDP {}".format(scenario.pdp_name)) projects = get_keystone_projects() - if not project_id: - for _project in projects['projects']: - if _project['name'] == "admin": - project_id = _project['id'] - assert project_id + # 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"]: @@ -207,5 +207,5 @@ def create_pdp(scenario, policy_id=None, project_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=project_id) + # map_to_keystone(pdp_id=_pdp_id, keystone_project_id=project_id) return _pdp_id
\ No newline at end of file diff --git a/python_moonclient/python_moonclient/policies.py b/python_moonclient/python_moonclient/policies.py index 80210811..0fae63c2 100644 --- a/python_moonclient/python_moonclient/policies.py +++ b/python_moonclient/python_moonclient/policies.py @@ -2,12 +2,10 @@ import logging import requests from . import config, models -logger = logging.getLogger("moonclient.models") +logger = logging.getLogger("moonclient.policies") URL = None HEADERS = None -FILE = open("/tmp/test.log", "w") -logger = logging.getLogger("utils.policies") policy_template = { "name": "test_policy", diff --git a/python_moonclient/python_moonclient/scripts.py b/python_moonclient/python_moonclient/scripts.py index 69746a8b..c880e497 100644 --- a/python_moonclient/python_moonclient/scripts.py +++ b/python_moonclient/python_moonclient/scripts.py @@ -18,10 +18,10 @@ def get_keystone_projects(): projects = pdp.get_keystone_projects() for _project in projects['projects']: - print("{} {}".format(_project['id'], _project['name'])) + print(" {} {}".format(_project['id'], _project['name'])) -def populate_values(): +def create_pdp(): requests_log = logging.getLogger("requests.packages.urllib3") requests_log.setLevel(logging.WARNING) requests_log.propagate = True @@ -29,14 +29,14 @@ def populate_values(): args = parse.parse() consul_host = args.consul_host consul_port = args.consul_port - project_id = args.keystone_pid + # project_id = args.keystone_pid models.init(consul_host, consul_port) policies.init(consul_host, consul_port) pdp.init(consul_host, consul_port) if args.filename: - print("Loading: {}".format(args.filename[0])) + logger.info("Loading: {}".format(args.filename[0])) m = SourceFileLoader("scenario", args.filename[0]) scenario = m.load_module() @@ -50,10 +50,10 @@ def populate_values(): else: model_id, meta_rule_list = models.create_model(scenario) policy_id = policies.create_policy(scenario, model_id, meta_rule_list) - pdp_id = pdp.create_pdp(scenario, policy_id=policy_id, project_id=project_id) + pdp_id = pdp.create_pdp(scenario, policy_id=policy_id) -def send_authz(): +def send_authz_to_wrapper(): args = parse.parse() consul_host = args.consul_host consul_port = args.consul_port @@ -63,7 +63,7 @@ def send_authz(): pdp.init(consul_host, consul_port) if args.filename: - print("Loading: {}".format(args.filename[0])) + logger.info("Loading: {}".format(args.filename[0])) m = SourceFileLoader("scenario", args.filename[0]) scenario = m.load_module() @@ -81,3 +81,83 @@ def send_authz(): ) if not args.dry_run: authz.save_data(args.write, time_data) + + +def get_pdp(): + args = parse.parse() + consul_host = args.consul_host + consul_port = args.consul_port + + models.init(consul_host, consul_port) + policies.init(consul_host, consul_port) + pdp.init(consul_host, consul_port) + + pdps = pdp.check_pdp() + for _pdp_key, _pdp_value in pdps["pdps"].items(): + print(" {} {} ({})".format(_pdp_key, _pdp_value['name'], + _pdp_value['keystone_project_id'])) + + +def delete_pdp(): + args = parse.parse() + consul_host = args.consul_host + consul_port = args.consul_port + + models.init(consul_host, consul_port) + policies.init(consul_host, consul_port) + pdp.init(consul_host, consul_port) + + if args.filename: + logger.info("Deleting: {}".format(args.filename[0])) + _search = args.filename[0] + pdps = pdp.check_pdp() + for _pdp_key, _pdp_value in pdps["pdps"].items(): + if _pdp_key == _search or _pdp_value['name'] == _search: + logger.info("Found {}".format(_pdp_key)) + pdp.delete_pdp(_pdp_key) + pdps = pdp.check_pdp() + logger.info("Listing all PDP:") + for _pdp_key, _pdp_value in pdps["pdps"].items(): + print(" {} {}".format(_pdp_key, _pdp_value['name'])) + if _pdp_key == _search or _pdp_value['name'] == _search: + logger.error("Error in deleting {}".format(_search)) + + +def delete_policy(): + args = parse.parse() + consul_host = args.consul_host + consul_port = args.consul_port + + models.init(consul_host, consul_port) + policies.init(consul_host, consul_port) + pdp.init(consul_host, consul_port) + + if args.filename: + logger.info("Deleting: {}".format(args.filename[0])) + _search = args.filename[0] + _policies = policies.check_policy() + for _policy_key, _policy_value in _policies["policies"].items(): + if _policy_key == _search or _policy_value['name'] == _search: + logger.info("Found {}".format(_policy_key)) + pdp.delete_pdp(_policy_key) + _policies = policies.check_policy() + logger.info("Listing all Policies:") + for _policy_key, _policy_value in _policies["policies"].items(): + print(" {} {}".format(_policy_key, _policy_value['name'])) + if _policy_key == _search or _policy_value['name'] == _search: + logger.error("Error in deleting {}".format(_search)) + + +def map_pdp_to_project(): + args = parse.parse() + consul_host = args.consul_host + consul_port = args.consul_port + + models.init(consul_host, consul_port) + policies.init(consul_host, consul_port) + pdp.init(consul_host, consul_port) + + if args.filename and len(args.filename) == 2: + logger.info("Mapping: {}=>{}".format(args.filename[0], args.filename[1])) + # TODO: check if pdp_id and keystone_project_id exist + pdp.map_to_keystone(pdp_id=args.filename[0], keystone_project_id=args.filename[1]) diff --git a/python_moonclient/setup.py b/python_moonclient/setup.py index f2dbc580..709e3ffa 100644 --- a/python_moonclient/setup.py +++ b/python_moonclient/setup.py @@ -9,6 +9,7 @@ import python_moonclient with open('requirements.txt') as f: required = f.read().splitlines() + setup( name='python-moonclient', @@ -42,8 +43,12 @@ setup( entry_points={ 'console_scripts': [ 'moon_get_keystone_projects = python_moonclient.scripts:get_keystone_projects', - 'moon_populate_values = python_moonclient.scripts:populate_values', - 'moon_send_authz = python_moonclient.scripts:send_authz', + 'moon_get_pdp = python_moonclient.scripts:get_pdp', + 'moon_create_pdp = python_moonclient.scripts:create_pdp', + 'moon_delete_pdp = python_moonclient.scripts:delete_pdp', + 'moon_delete_policy = python_moonclient.scripts:delete_policy', + 'moon_map_pdp_to_project = python_moonclient.scripts:map_pdp_to_project', + 'moon_send_authz_to_wrapper = python_moonclient.scripts:send_authz_to_wrapper' ], } diff --git a/python_moondb/Changelog b/python_moondb/Changelog index ff244af5..a7d10b17 100644 --- a/python_moondb/Changelog +++ b/python_moondb/Changelog @@ -53,3 +53,7 @@ CHANGES ----- - Update the name of the library (from moon_db) +1.2.5 +----- +- Code cleaning + diff --git a/python_moondb/build.sh b/python_moondb/build.sh deleted file mode 100644 index f109e9b8..00000000 --- a/python_moondb/build.sh +++ /dev/null @@ -1,38 +0,0 @@ -#!/usr/bin/env bash - -VERSION=moon_db-$(grep __version__ moon_db/__init__.py | cut -d "\"" -f 2) - -python3 setup.py sdist bdist_wheel - -rm dist/*.asc 2>/dev/null - -gpg --detach-sign -u "A0A96E75" -a dist/${VERSION}-py3-none-any.whl -gpg --detach-sign -u "A0A96E75" -a dist/${VERSION}.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}.tar.gz dist/${VERSION}.tar.gz.asc - rm -f ../moon_orchestrator/dist/moon_db* - rm -f ../moon_interface/dist/moon_db* - rm -f ../moon_manager/dist/moon_db* - rm -f ../moon_authz/dist/moon_db* - rm -f ../moon_wrapper/dist/moon_db* -fi - -if [ "$1" = "copy" ]; then - mkdir -p ../moon_orchestrator/dist/ 2>/dev/null - rm -f ../moon_orchestrator/dist/moon_db* - cp -v dist/${VERSION}-py3-none-any.whl ../moon_orchestrator/dist/ - mkdir -p ../moon_interface/dist/ 2>/dev/null - rm -f ../moon_interface/dist/moon_db* - cp -v dist/${VERSION}-py3-none-any.whl ../moon_interface/dist/ - mkdir -p ../moon_manager/dist/ 2>/dev/null - rm -f ../moon_manager/dist/moon_db* - cp -v dist/${VERSION}-py3-none-any.whl ../moon_manager/dist/ - mkdir -p ../moon_authz/dist/ 2>/dev/null - rm -f ../moon_authz/dist/moon_db* - cp -v dist/${VERSION}-py3-none-any.whl ../moon_authz/dist/ - mkdir -p ../moon_wrapper/dist/ 2>/dev/null - rm -f ../moon_wrapper/dist/moon_db* - cp -v dist/${VERSION}-py3-none-any.whl ../moon_wrapper/dist/ -fi diff --git a/python_moondb/python_moondb/__init__.py b/python_moondb/python_moondb/__init__.py index 73faf752..de7c772e 100644 --- a/python_moondb/python_moondb/__init__.py +++ b/python_moondb/python_moondb/__init__.py @@ -3,5 +3,5 @@ # 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.4" +__version__ = "1.2.5" diff --git a/python_moondb/python_moondb/api/keystone.py b/python_moondb/python_moondb/api/keystone.py index f5410190..582ae710 100644 --- a/python_moondb/python_moondb/api/keystone.py +++ b/python_moondb/python_moondb/api/keystone.py @@ -7,12 +7,12 @@ import os import requests import json from uuid import uuid4 -from oslo_log import log as logging +import logging from python_moonutilities import exceptions, configuration from python_moonutilities.security_functions import filter_input, login, logout from python_moondb.api.managers import Managers -LOG = logging.getLogger("moon.db.api.keystone") +logger = logging.getLogger("moon.db.api.keystone") class KeystoneManager(Managers): @@ -37,7 +37,7 @@ class KeystoneManager(Managers): _headers = login() req = requests.get("{}{}".format(self.__url, endpoint), headers=_headers, verify=False) if req.status_code not in (200, 201): - LOG.error(req.text) + logger.error(req.text) raise _exception data = req.json() logout(_headers) @@ -49,10 +49,10 @@ class KeystoneManager(Managers): data=json.dumps(data), headers=_headers, verify=False) if req.status_code == 409: - LOG.warning(req.text) + logger.warning(req.text) raise exceptions.KeystoneUserConflict if req.status_code not in (200, 201): - LOG.error(req.text) + logger.error(req.text) raise _exception data = req.json() logout(_headers) diff --git a/python_moondb/python_moondb/api/managers.py b/python_moondb/python_moondb/api/managers.py index 602e0f11..f500d02e 100644 --- a/python_moondb/python_moondb/api/managers.py +++ b/python_moondb/python_moondb/api/managers.py @@ -3,8 +3,8 @@ # 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_log import log as logging -LOG = logging.getLogger("moon.db.api.managers") +import logging +logger = logging.getLogger("moon.db.api.managers") class Managers(object): diff --git a/python_moondb/python_moondb/api/model.py b/python_moondb/python_moondb/api/model.py index fbfbb680..bd475365 100644 --- a/python_moondb/python_moondb/api/model.py +++ b/python_moondb/python_moondb/api/model.py @@ -4,13 +4,13 @@ # or at 'http://www.apache.org/licenses/LICENSE-2.0'. from uuid import uuid4 -from oslo_log import log as logging +import logging from python_moonutilities import exceptions from python_moonutilities.security_functions import filter_input, enforce from python_moondb.api.managers import Managers -LOG = logging.getLogger("moon.db.api.model") +logger = logging.getLogger("moon.db.api.model") class ModelManager(Managers): @@ -60,7 +60,7 @@ class ModelManager(Managers): raise exceptions.MetaRuleExisting if not meta_rule_id: meta_rule_id = uuid4().hex - LOG.info("add_meta_rule {}".format(value)) + logger.info("add_meta_rule {}".format(value)) return self.driver.set_meta_rule(meta_rule_id=meta_rule_id, value=value) @enforce(("read", "write"), "meta_rules") diff --git a/python_moondb/python_moondb/api/pdp.py b/python_moondb/python_moondb/api/pdp.py index 07feab7e..d39418b8 100644 --- a/python_moondb/python_moondb/api/pdp.py +++ b/python_moondb/python_moondb/api/pdp.py @@ -4,12 +4,12 @@ # or at 'http://www.apache.org/licenses/LICENSE-2.0'. from uuid import uuid4 -from oslo_log import log as logging -from python_moonutilities.security_functions import filter_input, enforce +import logging +from python_moonutilities.security_functions import enforce from python_moondb.api.managers import Managers from python_moonutilities import exceptions -LOG = logging.getLogger("moon.db.api.pdp") +logger = logging.getLogger("moon.db.api.pdp") class PDPManager(Managers): diff --git a/python_moondb/python_moondb/api/policy.py b/python_moondb/python_moondb/api/policy.py index 81689826..9781fda8 100644 --- a/python_moondb/python_moondb/api/policy.py +++ b/python_moondb/python_moondb/api/policy.py @@ -8,7 +8,7 @@ import logging from python_moonutilities.security_functions import enforce from python_moondb.api.managers import Managers -LOG = logging.getLogger("moon.db.api.policy") +logger = logging.getLogger("moon.db.api.policy") class PolicyManager(Managers): @@ -56,7 +56,7 @@ class PolicyManager(Managers): k_user = Managers.KeystoneManager.create_user(value) if not perimeter_id: try: - LOG.info("k_user={}".format(k_user)) + logger.info("k_user={}".format(k_user)) perimeter_id = k_user['users'][0].get('id', uuid4().hex) except IndexError: k_user = Managers.KeystoneManager.get_user_by_name( diff --git a/python_moondb/python_moondb/backends/flat.py b/python_moondb/python_moondb/backends/flat.py deleted file mode 100644 index 0fe2f00b..00000000 --- a/python_moondb/python_moondb/backends/flat.py +++ /dev/null @@ -1,89 +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'. - -import logging -import time -from python_moondb.core import LogDriver - - -class LogConnector(LogDriver): - - AUTHZ_FILE = '/var/log/moon/authz.log' - SYS_FILE = '/var/log/moon/system.log' - TIME_FORMAT = '%Y-%m-%d-%H:%M:%S' - - def __init__(self): - # Fixme (dthom): when logging from an other class, the %appname% in the event - # is always keystone.contrib.moon.backends.flat - super(LogConnector, self).__init__() - - self.SYS_LOG = logging.getLogger(__name__) - if not len(self.SYS_LOG.handlers): - fh = logging.FileHandler(self.SYS_FILE) - fh.setLevel(logging.DEBUG) - formatter = logging.Formatter('%(asctime)s ------ %(message)s', self.TIME_FORMAT) - fh.setFormatter(formatter) - self.SYS_LOG.addHandler(fh) - - self.AUTHZ_LOG = logging.getLogger("authz") - if not len(self.AUTHZ_LOG.handlers): - fh = logging.FileHandler(self.AUTHZ_FILE) - fh.setLevel(logging.WARNING) - formatter = logging.Formatter('%(asctime)s ------ %(message)s', self.TIME_FORMAT) - fh.setFormatter(formatter) - self.AUTHZ_LOG.addHandler(fh) - - def authz(self, message): - self.AUTHZ_LOG.warn(message) - - def debug(self, message): - self.SYS_LOG.debug(message) - - def info(self, message): - self.SYS_LOG.info(message) - - def warning(self, message): - self.SYS_LOG.warning(message) - - def error(self, message): - self.SYS_LOG.error(message) - - def critical(self, message): - self.SYS_LOG.critical(message) - - def get_logs(self, logger="authz", event_number=None, time_from=None, time_to=None, filter_str=None): - if logger == "authz": - _logs = open(self.AUTHZ_FILE).readlines() - else: - _logs = open(self.SYS_FILE).readlines() - if filter_str: - _logs = filter(lambda x: filter_str in x, _logs) - if time_from: - if isinstance(time_from, str): - time_from = time.strptime(time_from.split(" ")[0], self.TIME_FORMAT) - try: - __logs = [] - for log in _logs: - _log = time.strptime(log.split(" ")[0], self.TIME_FORMAT) - if time_from <= _log: - __logs.append(log) - _logs = __logs - except ValueError: - self.error("Time format error") - if time_to: - try: - if isinstance(time_to, str): - time_to = time.strptime(time_to.split(" ")[0], self.TIME_FORMAT) - __logs = [] - for log in _logs: - _log = time.strptime(log.split(" ")[0], self.TIME_FORMAT) - if time_to >= _log: - __logs.append(log) - _logs = __logs - except ValueError: - self.error("Time format error") - if event_number: - _logs = _logs[-event_number:] - return list(_logs) diff --git a/python_moondb/python_moondb/backends/sql.py b/python_moondb/python_moondb/backends/sql.py index 5dba8eb2..1ce8d016 100644 --- a/python_moondb/python_moondb/backends/sql.py +++ b/python_moondb/python_moondb/backends/sql.py @@ -17,7 +17,7 @@ from python_moonutilities import configuration from python_moonutilities.exceptions import * from python_moondb.core import PDPDriver, PolicyDriver, ModelDriver -LOG = logging.getLogger("moon.db.driver.sql") +logger = logging.getLogger("moon.db.driver.sql") Base = declarative_base() DEBUG = True if configuration.get_configuration("logging")['logging']['loggers']['moon']['level'] == "DEBUG" else False @@ -648,7 +648,7 @@ class PolicyConnector(BaseConnector, PolicyDriver): session.delete(_action) def get_subject_data(self, policy_id, data_id=None, category_id=None): - LOG.info("driver {} {} {}".format(policy_id, data_id, category_id)) + logger.info("driver {} {} {}".format(policy_id, data_id, category_id)) with self.get_session_for_read() as session: query = session.query(SubjectData) if data_id: @@ -656,7 +656,7 @@ class PolicyConnector(BaseConnector, PolicyDriver): else: query = query.filter_by(policy_id=policy_id, category_id=category_id) ref_list = query.all() - LOG.info("ref_list={}".format(ref_list)) + logger.info("ref_list={}".format(ref_list)) return { "policy_id": policy_id, "category_id": category_id, @@ -982,7 +982,7 @@ class PolicyConnector(BaseConnector, PolicyDriver): ref_list = query.all() rules = list(map(lambda x: x.rule, ref_list)) if not rules or value not in rules: - LOG.info("add_rule IN IF") + logger.info("add_rule IN IF") ref = Rule.from_dict( { "id": uuid4().hex, @@ -1815,61 +1815,3 @@ class ModelConnector(BaseConnector, ModelDriver): class SQLConnector(PDPConnector, PolicyConnector, ModelConnector): pass - -# class InterExtension(Base): -# __tablename__ = 'inter_extension' -# attributes = [ -# 'id', -# 'requesting_intra_extension_id', -# 'requested_intra_extension_id', -# 'virtual_entity_uuid', -# 'genre', -# 'description', -# ] -# id = sql.Column(sql.String(64), primary_key=True) -# requesting_intra_extension_id = sql.Column(sql.String(64)) -# requested_intra_extension_id = sql.Column(sql.String(64)) -# virtual_entity_uuid = sql.Column(sql.String(64)) -# genre = sql.Column(sql.String(64)) -# description = sql.Column(sql.Text()) -# -# @classmethod -# def from_dict(cls, d): -# """Override parent from_dict() method with a simpler implementation. -# """ -# new_d = d.copy() -# return cls(**new_d) -# -# def to_dict(self): -# """Override parent to_dict() method with a simpler implementation. -# """ -# return dict(six.iteritems(self)) -# -# -# class InterExtensionBaseConnector(InterExtensionDriver): -# -# def get_inter_extensions(self): -# with self.get_session_for_read() as session: -# query = session.query(InterExtension.id) -# interextensions = query.all() -# return [interextension.id for interextension in interextensions] -# -# def create_inter_extensions(self, inter_id, inter_extension): -# with self.get_session_for_read() as session: -# ie_ref = InterExtension.from_dict(inter_extension) -# session.add(ie_ref) -# return InterExtension.to_dict(ie_ref) -# -# def get_inter_extension(self, uuid): -# with self.get_session_for_read() as session: -# query = session.query(InterExtension) -# query = query.filter_by(id=uuid) -# ref = query.first() -# if not ref: -# raise exception.NotFound -# return ref.to_dict() -# -# def delete_inter_extensions(self, inter_extension_id): -# with self.get_session_for_read() as session: -# ref = session.query(InterExtension).get(inter_extension_id) -# session.delete(ref) diff --git a/python_moondb/python_moondb/core.py b/python_moondb/python_moondb/core.py index 49e9f711..984b81a7 100644 --- a/python_moondb/python_moondb/core.py +++ b/python_moondb/python_moondb/core.py @@ -3,20 +3,18 @@ # 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_log import log as logging -from oslo_config import cfg +import logging from stevedore.driver import DriverManager from python_moonutilities import configuration from python_moondb.api import model, policy, pdp, keystone -CONF = cfg.CONF -LOG = logging.getLogger("moon.db") +logger = logging.getLogger("moon.db") class Driver(DriverManager): def __init__(self, driver_name, engine_name): - LOG.info("initialization of Driver {}".format(driver_name)) + logger.info("initialization of Driver {}".format(driver_name)) super(Driver, self).__init__( namespace='moon_db.driver', name=driver_name, @@ -212,6 +210,7 @@ class KeystoneDriver(Driver): conf = configuration.get_configuration("database")['database'] + KeystoneManager = keystone.KeystoneManager( KeystoneDriver(conf['driver'], conf['url']) ) @@ -227,71 +226,3 @@ PolicyManager = policy.PolicyManager( PDPManager = pdp.PDPManager( PDPDriver(conf['driver'], conf['url']) ) - - -# class LogDriver(object): -# -# def authz(self, message): -# """Log authorization message -# -# :param message: the message to log -# :type message: string -# :return: None -# """ -# raise NotImplementedError() # pragma: no cover -# -# def debug(self, message): -# """Log debug message -# -# :param message: the message to log -# :type message: string -# :return: None -# """ -# raise NotImplementedError() # pragma: no cover -# -# def info(self, message): -# """Log informational message -# -# :param message: the message to log -# :type message: string -# :return: None -# """ -# raise NotImplementedError() # pragma: no cover -# -# def warning(self, message): -# """Log warning message -# -# :param message: the message to log -# :type message: string -# :return: None -# """ -# raise NotImplementedError() # pragma: no cover -# -# def error(self, message): -# """Log error message -# -# :param message: the message to log -# :type message: string -# :return: None -# """ -# raise NotImplementedError() # pragma: no cover -# -# def critical(self, message): -# """Log critical message -# -# :param message: the message to log -# :type message: string -# :return: None -# """ -# raise NotImplementedError() # pragma: no cover -# -# def get_logs(self, options): -# """Get logs -# -# :param options: options to filter log events -# :type options: string eg: "event_number=10,from=2014-01-01-10:10:10,to=2014-01-01-12:10:10,filter=expression" -# :return: a list of log events -# -# TIME_FORMAT is '%Y-%m-%d-%H:%M:%S' -# """ -# raise NotImplementedError() # pragma: no cover diff --git a/python_moondb/requirements.txt b/python_moondb/requirements.txt index 03afc879..a205666f 100644 --- a/python_moondb/requirements.txt +++ b/python_moondb/requirements.txt @@ -2,5 +2,3 @@ stevedore sqlalchemy pymysql requests -oslo.log -oslo.config diff --git a/python_moondb/setup.py b/python_moondb/setup.py index 65687c3f..e34369d4 100644 --- a/python_moondb/setup.py +++ b/python_moondb/setup.py @@ -45,7 +45,6 @@ setup( "moon_db.driver": [ "sql = python_moondb.backends.sql:SQLConnector", - "flat = python_moondb.backends.flat:LogConnector", ], 'console_scripts': [ 'moon_db_manager = python_moondb.db_manager:run', diff --git a/python_moondb/tests/unit_python/mock_keystone.py b/python_moondb/tests/unit_python/mock_keystone.py index c0b26b88..3f262538 100644 --- a/python_moondb/tests/unit_python/mock_keystone.py +++ b/python_moondb/tests/unit_python/mock_keystone.py @@ -20,4 +20,14 @@ def register_keystone(m): json={"users": [{ "id": "1111111111111" }]} - )
\ No newline at end of file + ) + m.register_uri( + 'POST', 'http://keystone:5000/v3/projects/', + json={ + "description": "test_project", + "domain_id": ['domain_id_1'], + "enabled": True, + "is_domain": False, + "name": 'project_1' + } + ) diff --git a/python_moondb/tests/unit_python/test_keystone.py b/python_moondb/tests/unit_python/test_keystone.py new file mode 100644 index 00000000..134bec0d --- /dev/null +++ b/python_moondb/tests/unit_python/test_keystone.py @@ -0,0 +1,53 @@ +import pytest + + +def create_project(tenant_dict): + from python_moondb.core import KeystoneManager + return KeystoneManager.create_project(tenant_dict) + + +def list_projects(): + from python_moondb.core import KeystoneManager + return KeystoneManager.list_projects() + + +def create_user(subject_dict): + from python_moondb.core import KeystoneManager + return KeystoneManager.create_user(subject_dict) + + +def test_create_project(): + tenant_dict = { + "description": "test_project", + "domain_id": ['domain_id_1'], + "enabled": True, + "is_domain": False, + "name": 'project_1' + } + project = create_project(tenant_dict) + assert project + assert project.get('name') == tenant_dict.get('name') + + +def test_create_project_without_name(): + tenant_dict = { + "description": "test_project", + "domain_id": ['domain_id_1'], + "enabled": True, + "is_domain": False, + } + with pytest.raises(Exception) as exception_info: + create_project(tenant_dict) + assert '400: Keystone project error' == str(exception_info.value) + + +def test_create_user(): + subject_dict = { + "password": "password", + "domain_id": ['domain_id_1'], + "enabled": True, + "project": 'test_project', + "name": 'user_id_1' + } + user = create_user(subject_dict) + assert user diff --git a/python_moonutilities/Changelog b/python_moonutilities/Changelog index dd441427..91f09cbf 100644 --- a/python_moonutilities/Changelog +++ b/python_moonutilities/Changelog @@ -70,3 +70,7 @@ CHANGES 1.4.3 ----- - Fix a bug in MANIFEST.in + +1.4.4 +----- +- Code cleaning diff --git a/python_moonutilities/python_moonutilities/__init__.py b/python_moonutilities/python_moonutilities/__init__.py index fb899fe2..6d1ac746 100644 --- a/python_moonutilities/python_moonutilities/__init__.py +++ b/python_moonutilities/python_moonutilities/__init__.py @@ -3,4 +3,6 @@ # 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.4.3" +__version__ = "1.4.4" + + diff --git a/python_moonutilities/python_moonutilities/api.py b/python_moonutilities/python_moonutilities/api.py deleted file mode 100644 index 8e80c21d..00000000 --- a/python_moonutilities/python_moonutilities/api.py +++ /dev/null @@ -1,28 +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'. - - -class APIList(object): - - API_LIST = () - - def __init__(self, api_list): - self.API_LIST = api_list - - def list_api(self, ctx): - api = dict() - for obj in self.API_LIST: - api[obj.__name__] = dict() - api[obj.__name__]["description"] = obj.__doc__.strip() if obj.__doc__ else "" - api[obj.__name__]["version"] = obj.__version__ - api[obj.__name__]["commands"] = dict() - for cmd in filter(lambda x: not x.startswith("__"), dir(obj)): - doc = eval("obj.{}.__doc__".format(cmd)) - if not doc: - doc = "" - api[obj.__name__]["commands"][cmd] = doc.strip() - return api - - diff --git a/python_moonutilities/python_moonutilities/auth.py b/python_moonutilities/python_moonutilities/auth.py index 7656f4e7..5f921d0b 100644 --- a/python_moonutilities/python_moonutilities/auth.py +++ b/python_moonutilities/python_moonutilities/auth.py @@ -12,7 +12,7 @@ from oslo_log import log as logging from python_moonutilities import exceptions, configuration -LOG = logging.getLogger(__name__) +logger = logging.getLogger(__name__) KEYSTONE_CONFIG = configuration.get_configuration("openstack/keystone")["openstack/keystone"] TOKENS = {} @@ -52,13 +52,13 @@ def check_token(token, url=None): TOKENS[token]["expires_at"] = time.strptime(token_time[0], "%Y-%m-%dT%H:%M:%S") TOKENS[token]["user"] = req.json().get("token").get("user").get("id") return TOKENS[token]["user"] - LOG.error("{} - {}".format(req.status_code, req.text)) + logger.error("{} - {}".format(req.status_code, req.text)) raise exceptions.KeystoneError elif KEYSTONE_CONFIG['check_token'].lower() == "strict": req = requests.head("{}/auth/tokens".format(url), headers=headers, verify=_verify) if req.status_code in (200, 201): return token - LOG.error("{} - {}".format(req.status_code, req.text)) + logger.error("{} - {}".format(req.status_code, req.text)) raise exceptions.KeystoneError raise exceptions.KeystoneError diff --git a/python_moonutilities/python_moonutilities/cache.py b/python_moonutilities/python_moonutilities/cache.py index 93e3daca..49f1dd53 100644 --- a/python_moonutilities/python_moonutilities/cache.py +++ b/python_moonutilities/python_moonutilities/cache.py @@ -4,7 +4,7 @@ import requests from uuid import uuid4 from python_moonutilities import configuration, exceptions -LOG = logging.getLogger("moon.utilities.cache") +logger = logging.getLogger("moon.utilities.cache") class Cache(object): @@ -174,12 +174,12 @@ class Cache(object): def __update_rules(self): for policy_id in self.__POLICIES: - LOG.info("Get {}".format("{}/policies/{}/rules".format( + logger.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)) + logger.info("UPDATE RULES {}".format(self.__RULES)) # assignment functions @@ -509,7 +509,7 @@ class Cache(object): continue self.__update_container_chaining(value["keystone_project_id"]) self.__CONTAINER_CHAINING_UPDATE = current_time - LOG.info(self.__CONTAINER_CHAINING_UPDATE) + logger.info(self.__CONTAINER_CHAINING_UPDATE) return self.__CONTAINER_CHAINING def __update_container_chaining(self, keystone_project_id): @@ -527,7 +527,7 @@ class Cache(object): _raw = requests.get("{}/pods/{}".format( self.orchestrator_url, container_value["name"]) ) - LOG.debug("_raw={}".format(_raw.text)) + logger.debug("_raw={}".format(_raw.text)) container_ids.append( { "container_id": container_value["name"], diff --git a/python_moonutilities/python_moonutilities/configuration.py b/python_moonutilities/python_moonutilities/configuration.py index f0ef74a6..51587582 100644 --- a/python_moonutilities/python_moonutilities/configuration.py +++ b/python_moonutilities/python_moonutilities/configuration.py @@ -7,11 +7,10 @@ import base64 import json import requests -import logging import logging.config from python_moonutilities import exceptions -LOG = logging.getLogger("moon.utilities") +logger = logging.getLogger("moon.utilities.configuration") CONSUL_HOST = "consul" CONSUL_PORT = "8500" @@ -33,7 +32,7 @@ def increment_port(): url = "http://{}:{}/v1/kv/components_port_start".format(CONSUL_HOST, CONSUL_PORT) req = requests.put(url, json=str(components_port_start)) if req.status_code != 200: - LOG.info("url={}".format(url)) + logger.info("url={}".format(url)) raise exceptions.ConsulError return components_port_start @@ -42,7 +41,7 @@ def get_configuration(key): url = "http://{}:{}/v1/kv/{}".format(CONSUL_HOST, CONSUL_PORT, key) req = requests.get(url) if req.status_code != 200: - LOG.error("url={}".format(url)) + logger.error("url={}".format(url)) raise exceptions.ConsulComponentNotFound("error={}: {}".format(req.status_code, req.text)) data = req.json() if len(data) == 1: @@ -70,18 +69,18 @@ def add_component(name, uuid, port=None, bind="127.0.0.1", keystone_id="", extra json=data ) if req.status_code != 200: - LOG.debug("url={}".format("http://{}:{}/v1/kv/components/{}".format(CONSUL_HOST, CONSUL_PORT, uuid))) - LOG.debug("data={}".format(data)) + logger.debug("url={}".format("http://{}:{}/v1/kv/components/{}".format(CONSUL_HOST, CONSUL_PORT, uuid))) + logger.debug("data={}".format(data)) raise exceptions.ConsulError - LOG.info("Add component {}".format(req.text)) - return get_configuration("components/"+uuid) + logger.info("Add component {}".format(req.text)) + return configuration.get_configuration("components/"+uuid) def get_plugins(): url = "http://{}:{}/v1/kv/plugins?recurse=true".format(CONSUL_HOST, CONSUL_PORT) req = requests.get(url) if req.status_code != 200: - LOG.info("url={}".format(url)) + logger.info("url={}".format(url)) raise exceptions.ConsulError data = req.json() if len(data) == 1: @@ -98,7 +97,7 @@ def get_components(): url = "http://{}:{}/v1/kv/components?recurse=true".format(CONSUL_HOST, CONSUL_PORT) req = requests.get(url) if req.status_code != 200: - LOG.info("url={}".format(url)) + logger.info("url={}".format(url)) raise exceptions.ConsulError data = req.json() if len(data) == 1: diff --git a/python_moonutilities/python_moonutilities/context.py b/python_moonutilities/python_moonutilities/context.py new file mode 100644 index 00000000..626b25dc --- /dev/null +++ b/python_moonutilities/python_moonutilities/context.py @@ -0,0 +1,319 @@ +# 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 copy +import logging +from python_moonutilities import exceptions + +logger = logging.getLogger("moon.utilities." + __name__) + + +class Context: + + 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 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 + 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 = 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 = 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 = 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() + + @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): + for header in self.__headers: + self.__pdp_set[header] = dict() + self.__pdp_set[header]["meta_rules"] = self.__meta_rules[header] + self.__pdp_set[header]["target"] = self.__add_target(header) + self.__pdp_set[header]["effect"] = "unset" + self.__pdp_set["effect"] = "deny" + + # 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): + """build target from meta_rule + + Target is dict of categories as keys ; and the value of each category + will be a list of assignments + + """ + result = dict() + _subject = self.__current_request["subject"] + _object = self.__current_request["object"] + _action = self.__current_request["action"] + 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] = [] + 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] = [] + 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] = [] + result[act_cat].extend( + self.cache.get_action_assignments(policy_id, _action, act_cat)) + return result + + def __repr__(self): + return """PDP ID: {id} +current_request: {current_request} +request_id: {request_id} +index: {index} +headers: {headers} +pdp_set: {pdp_set} + """.format( + id=self.__pdp_id, + current_request=self.__current_request, + request_id=self.__request_id, + headers=self.__headers, + pdp_set=self.__pdp_set, + index=self.__index + ) + + def to_dict(self): + return { + "initial_request": copy.deepcopy(self.initial_request), + "current_request": copy.deepcopy(self.__current_request), + "headers": copy.deepcopy(self.__headers), + "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 + def request_id(self): + return self.__request_id + + @request_id.setter + def request_id(self, value): + raise Exception("You cannot update the request_id") + + @request_id.deleter + def request_id(self): + 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, + "object": self.__object, + "action": self.__action, + } + + @initial_request.setter + def initial_request(self, value): + raise Exception("You are not allowed to update the initial_request") + + @initial_request.deleter + def initial_request(self): + raise Exception("You are not allowed to delete the initial_request") + + @property + def current_request(self): + if not self.__current_request: + self.__current_request = copy.deepcopy(self.initial_request) + return self.__current_request + + @current_request.setter + def current_request(self, value): + self.__current_request = copy.deepcopy(value) + # Note (asteroide): if the current request is modified, + # we must update the PDP Set. + self.__init_pdp_set() + + @current_request.deleter + def current_request(self): + self.__current_request = {} + self.__pdp_set = {} + + @property + def headers(self): + return self.__headers + + @headers.setter + def headers(self, headers): + self.__headers = headers + + @headers.deleter + def headers(self): + self.__headers = list() + + @property + def index(self): + return self.__index + + @index.setter + def index(self, index): + self.__index += 1 + + @index.deleter + def index(self): + self.__index = -1 + + @property + def pdp_set(self): + return self.__pdp_set + + @pdp_set.setter + def pdp_set(self, value): + raise Exception("You are not allowed to modify the pdp_set") + + @pdp_set.deleter + def pdp_set(self): + self.__pdp_set = {} + + diff --git a/python_moonutilities/python_moonutilities/exceptions.py b/python_moonutilities/python_moonutilities/exceptions.py index 5bbab2be..f14d6abf 100644 --- a/python_moonutilities/python_moonutilities/exceptions.py +++ b/python_moonutilities/python_moonutilities/exceptions.py @@ -6,7 +6,7 @@ from oslo_log import log as logging from werkzeug.exceptions import HTTPException -LOG = logging.getLogger("moon.utilities.exceptions") +logger = logging.getLogger("moon.utilities.exceptions") _ = str @@ -14,7 +14,7 @@ class MoonErrorMetaClass(type): def __init__(cls, name, bases, dct): super(MoonErrorMetaClass, cls).__init__(name, bases, dct) - cls.hierarchy += "/"+str(name) + cls.hierarchy += "/" + str(name) class MoonError(HTTPException): @@ -40,30 +40,30 @@ class MoonError(HTTPException): message = "{} ({}) {}".format(self.hierarchy, self.description, self.payload) if self.logger == "ERROR": try: - LOG.error(message) + logger.error(message) except AttributeError: - LOG.error(message) + logger.error(message) elif self.logger == "WARNING": try: - LOG.warning(message) + logger.warning(message) except AttributeError: - LOG.warning(message) + logger.warning(message) elif self.logger == "CRITICAL": try: - LOG.critical(message) + logger.critical(message) except AttributeError: - LOG.critical(message) + logger.critical(message) elif self.logger == "AUTHZ": try: - LOG.authz(self.hierarchy) - LOG.error(message) + logger.authz(self.hierarchy) + logger.error(message) except AttributeError: - LOG.error(message) + logger.error(message) else: try: - LOG.info(message) + logger.info(message) except AttributeError: - LOG.info(message) + logger.info(message) # def to_dict(self): # rv = dict(self.payload or ()) @@ -109,6 +109,7 @@ class TenantNoIntraAuthzExtension(TenantNoIntraExtension): title = 'Tenant No Intra_Admin_Extension' logger = "ERROR" + # Exceptions for IntraExtension @@ -520,3 +521,16 @@ class ContainerMissing(DockerError): title = 'Container missing' logger = "ERROR" + +class PdpUnknown(MoonError): + description = _("The pdp is unknown.") + code = 400 + title = 'Pdp Unknown' + logger = "Error" + + +class PdpExisting(MoonError): + description = _("The pdp already exists.") + code = 409 + title = 'Pdp Error' + logger = "Error" diff --git a/python_moonutilities/python_moonutilities/misc.py b/python_moonutilities/python_moonutilities/misc.py index b83523c3..1db4d7cd 100644 --- a/python_moonutilities/python_moonutilities/misc.py +++ b/python_moonutilities/python_moonutilities/misc.py @@ -7,33 +7,7 @@ import logging import random -LOG = logging.getLogger(__name__) - - -def get_uuid_from_name(name, elements, **kwargs): - for element in elements: - if type(elements[element]) is dict and elements[element].get('name') == name: - if kwargs: - for args in kwargs: - if elements[element].get(args) != kwargs[args]: - return - else: - return element - else: - return element - - -def get_name_from_uuid(uuid, elements, **kwargs): - for element in elements: - if element == uuid: - if kwargs: - for args in kwargs: - if elements[element].get(args) != kwargs[args]: - return - else: - return elements[element].get('name') - else: - return elements[element].get('name') +logger = logging.getLogger("moon.utilities.misc") def get_random_name(): diff --git a/python_moonutilities/python_moonutilities/security_functions.py b/python_moonutilities/python_moonutilities/security_functions.py index 6d9307fe..15cbc8be 100644 --- a/python_moonutilities/python_moonutilities/security_functions.py +++ b/python_moonutilities/python_moonutilities/security_functions.py @@ -4,7 +4,6 @@ # or at 'http://www.apache.org/licenses/LICENSE-2.0'. -import copy import re import os import types @@ -15,7 +14,7 @@ from flask import request import logging from python_moonutilities import exceptions, configuration -LOG = logging.getLogger("moon.utilities." + __name__) +logger = logging.getLogger("moon.utilities." + __name__) keystone_config = configuration.get_configuration("openstack/keystone")["openstack/keystone"] TOKENS = {} @@ -145,9 +144,9 @@ def login(user=None, password=None, domain=None, project=None, url=None): if req.status_code in (200, 201, 204): headers['X-Auth-Token'] = req.headers['X-Subject-Token'] return headers - LOG.warning("Waiting for Keystone...") + logger.warning("Waiting for Keystone...") if time.time() - start_time == 100: - LOG.error(req.text) + logger.error(req.text) raise exceptions.KeystoneError time.sleep(5) @@ -159,316 +158,10 @@ def logout(headers, url=None): req = requests.delete("{}/auth/tokens".format(url), headers=headers, verify=keystone_config['certificate']) if req.status_code in (200, 201, 204): return - LOG.error(req.text) + logger.error(req.text) raise exceptions.KeystoneError -class Context: - - 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 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 - 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 = 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 = 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 = 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() - - @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): - for header in self.__headers: - self.__pdp_set[header] = dict() - self.__pdp_set[header]["meta_rules"] = self.__meta_rules[header] - self.__pdp_set[header]["target"] = self.__add_target(header) - self.__pdp_set[header]["effect"] = "unset" - self.__pdp_set["effect"] = "deny" - - # 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): - """build target from meta_rule - - Target is dict of categories as keys ; and the value of each category - will be a list of assignments - - """ - result = dict() - _subject = self.__current_request["subject"] - _object = self.__current_request["object"] - _action = self.__current_request["action"] - 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] = [] - 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] = [] - 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] = [] - result[act_cat].extend( - self.cache.get_action_assignments(policy_id, _action, act_cat)) - return result - - def __repr__(self): - return """PDP ID: {id} -current_request: {current_request} -request_id: {request_id} -index: {index} -headers: {headers} -pdp_set: {pdp_set} - """.format( - id=self.__pdp_id, - current_request=self.__current_request, - request_id=self.__request_id, - headers=self.__headers, - pdp_set=self.__pdp_set, - index=self.__index - ) - - def to_dict(self): - return { - "initial_request": copy.deepcopy(self.initial_request), - "current_request": copy.deepcopy(self.__current_request), - "headers": copy.deepcopy(self.__headers), - "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 - def request_id(self): - return self.__request_id - - @request_id.setter - def request_id(self, value): - raise Exception("You cannot update the request_id") - - @request_id.deleter - def request_id(self): - 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, - "object": self.__object, - "action": self.__action, - } - - @initial_request.setter - def initial_request(self, value): - raise Exception("You are not allowed to update the initial_request") - - @initial_request.deleter - def initial_request(self): - raise Exception("You are not allowed to delete the initial_request") - - @property - def current_request(self): - if not self.__current_request: - self.__current_request = copy.deepcopy(self.initial_request) - return self.__current_request - - @current_request.setter - def current_request(self, value): - self.__current_request = copy.deepcopy(value) - # Note (asteroide): if the current request is modified, - # we must update the PDP Set. - self.__init_pdp_set() - - @current_request.deleter - def current_request(self): - self.__current_request = {} - self.__pdp_set = {} - - @property - def headers(self): - return self.__headers - - @headers.setter - def headers(self, headers): - self.__headers = headers - - @headers.deleter - def headers(self): - self.__headers = list() - - @property - def index(self): - return self.__index - - @index.setter - def index(self, index): - self.__index += 1 - - @index.deleter - def index(self): - self.__index = -1 - - @property - def pdp_set(self): - return self.__pdp_set - - @pdp_set.setter - def pdp_set(self, value): - raise Exception("You are not allowed to modify the pdp_set") - - @pdp_set.deleter - def pdp_set(self): - self.__pdp_set = {} - - def check_token(token, url=None): _verify = False if keystone_config['certificate']: @@ -507,13 +200,13 @@ def check_token(token, url=None): TOKENS[token]["expires_at"] = time.strptime(token_time[0], "%Y-%m-%dT%H:%M:%S") TOKENS[token]["user"] = req.json().get("token").get("user").get("id") return TOKENS[token]["user"] - LOG.error("{} - {}".format(req.status_code, req.text)) + logger.error("{} - {}".format(req.status_code, req.text)) raise exceptions.KeystoneError elif keystone_config['check_token'].lower() == "strict": req = requests.head("{}/auth/tokens".format(url), headers=headers, verify=_verify) if req.status_code in (200, 201): return token - LOG.error("{} - {}".format(req.status_code, req.text)) + logger.error("{} - {}".format(req.status_code, req.text)) raise exceptions.KeystoneError raise exceptions.KeystoneError diff --git a/python_moonutilities/tests/unit_python/conftest.py b/python_moonutilities/tests/unit_python/conftest.py index 7217586a..34e5c272 100644 --- a/python_moonutilities/tests/unit_python/conftest.py +++ b/python_moonutilities/tests/unit_python/conftest.py @@ -1,8 +1,6 @@ import pytest import requests_mock -import mock_components -import mock_keystone -import mock_cache +import mock_repo @pytest.fixture(autouse=True) @@ -10,8 +8,7 @@ def no_requests(monkeypatch): """ Modify the response from Requests module """ with requests_mock.Mocker(real_http=True) as m: - mock_components.register_components(m) - mock_keystone.register_keystone(m) - mock_cache.register_cache(m) + mock_repo.register_cache(m) + print("End registering URI") yield m
\ No newline at end of file diff --git a/python_moonutilities/tests/unit_python/mock_cache.py b/python_moonutilities/tests/unit_python/mock_cache.py deleted file mode 100644 index b2b287a9..00000000 --- a/python_moonutilities/tests/unit_python/mock_cache.py +++ /dev/null @@ -1,321 +0,0 @@ -from utilities import CONF - -pdp_mock = { - "pdp_id1": { - "name": "...", - "security_pipeline": ["policy_id_1", "policy_id_2"], - "keystone_project_id": "keystone_project_id1", - "description": "...", - }, - "pdp_id12": { - "name": "...", - "security_pipeline": ["policy_id_1", "policy_id_2"], - "keystone_project_id": "keystone_project_id1", - "description": "...", - } -} - -meta_rules_mock = { - "meta_rule_id1": { - "name": "meta_rule1", - "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"] - }, - "meta_rule_id2": { - "name": "name of the meta rules2", - "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"] - } -} - -policies_mock = { - "policy_id_1": { - "name": "test_policy1", - "model_id": "model_id_1", - "genre": "authz", - "description": "test", - }, - "policy_id_2": { - "name": "test_policy2", - "model_id": "model_id_2", - "genre": "authz", - "description": "test", - } -} - -subject_mock = { - "policy_id_1": { - "subject_id": { - "name": "subject_name", - "keystone_id": "keystone_project_id1", - "description": "a description" - } - }, - "policy_id_2": { - "subject_id": { - "name": "subject_name", - "keystone_id": "keystone_project_id1", - "description": "a description" - } - } -} - -subject_assignment_mock = { - "subject_id": { - "policy_id": "ID of the policy", - "subject_id": "ID of the subject", - "category_id": "ID of the category", - "assignments": [], - } -} - -object_mock = { - "policy_id_1": { - "object_id": { - "name": "object_name", - "description": "a description" - } - }, - "policy_id_2": { - "object_id": { - "name": "object_name", - "description": "a description" - } - } -} - -object_assignment_mock = { - "object_id": { - "policy_id": "ID of the policy", - "object_id": "ID of the object", - "category_id": "ID of the category", - "assignments": [], - } -} - -action_mock = { - "policy_id_1": { - "action_id": { - "name": "action_name", - "description": "a description" - } - }, - "policy_id_2": { - "action_id": { - "name": "action_name", - "description": "a description" - } - } -} - -action_assignment_mock = { - "action_id": { - "policy_id": "ID of the policy", - "action_id": "ID of the action", - "category_id": "ID of the category", - "assignments": [], - } -} - -models_mock = { - "model_id_1": { - "name": "test_model", - "description": "test", - "meta_rules": ["meta_rule_id1"] - }, - "model_id_2": { - "name": "test_model", - "description": "test", - "meta_rules": ["meta_rule_id2"] - }, -} - -rules_mock = { - "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 - ) - } - } -} - - -def register_cache(m): - """ Modify the response from Requests module - """ - register_pdp(m) - register_meta_rules(m) - register_policies(m) - register_models(m) - register_policy_subject(m, "policy_id_1") - register_policy_subject(m, "policy_id_2") - register_policy_object(m, "policy_id_1") - register_policy_object(m, "policy_id_2") - register_policy_action(m, "policy_id_1") - register_policy_action(m, "policy_id_2") - register_policy_subject_assignment(m, "policy_id_1", "subject_id") - # register_policy_subject_assignment_list(m1, "policy_id_1") - register_policy_subject_assignment(m, "policy_id_2", "subject_id") - # register_policy_subject_assignment_list(m1, "policy_id_2") - register_policy_object_assignment(m, "policy_id_1", "object_id") - # register_policy_object_assignment_list(m1, "policy_id_1") - register_policy_object_assignment(m, "policy_id_2", "object_id") - # register_policy_object_assignment_list(m1, "policy_id_2") - register_policy_action_assignment(m, "policy_id_1", "action_id") - # register_policy_action_assignment_list(m1, "policy_id_1") - register_policy_action_assignment(m, "policy_id_2", "action_id") - # register_policy_action_assignment_list(m1, "policy_id_2") - register_rules(m, "policy_id1") - - -def register_pdp(m): - m.register_uri( - 'GET', 'http://{}:{}/{}'.format(CONF['components']['manager']['hostname'], - CONF['components']['manager']['port'], 'pdp'), - json={'pdps': pdp_mock} - ) - - -def register_meta_rules(m): - m.register_uri( - 'GET', 'http://{}:{}/{}'.format(CONF['components']['manager']['hostname'], - CONF['components']['manager']['port'], 'meta_rules'), - json={'meta_rules': meta_rules_mock} - ) - - -def register_policies(m): - m.register_uri( - 'GET', 'http://{}:{}/{}'.format(CONF['components']['manager']['hostname'], - CONF['components']['manager']['port'], 'policies'), - json={'policies': policies_mock} - ) - - -def register_models(m): - m.register_uri( - 'GET', 'http://{}:{}/{}'.format(CONF['components']['manager']['hostname'], - CONF['components']['manager']['port'], 'models'), - json={'models': models_mock} - ) - - -def register_policy_subject(m, policy_id): - m.register_uri( - 'GET', 'http://{}:{}/{}/{}/subjects'.format(CONF['components']['manager']['hostname'], - CONF['components']['manager']['port'], 'policies', policy_id), - json={'subjects': subject_mock[policy_id]} - ) - - -def register_policy_object(m, policy_id): - m.register_uri( - 'GET', 'http://{}:{}/{}/{}/objects'.format(CONF['components']['manager']['hostname'], - CONF['components']['manager']['port'], 'policies', policy_id), - json={'objects': object_mock[policy_id]} - ) - - -def register_policy_action(m, policy_id): - m.register_uri( - 'GET', 'http://{}:{}/{}/{}/actions'.format(CONF['components']['manager']['hostname'], - CONF['components']['manager']['port'], 'policies', policy_id), - json={'actions': action_mock[policy_id]} - ) - - -def register_policy_subject_assignment(m, policy_id, subj_id): - m.register_uri( - 'GET', 'http://{}:{}/{}/{}/subject_assignments/{}'.format(CONF['components']['manager']['hostname'], - CONF['components']['manager']['port'], 'policies', - policy_id, - subj_id), - json={'subject_assignments': subject_assignment_mock} - ) - - -def register_policy_subject_assignment_list(m, policy_id): - m.register_uri( - 'GET', 'http://{}:{}/{}/{}/subject_assignments'.format(CONF['components']['manager']['hostname'], - CONF['components']['manager']['port'], 'policies', - policy_id), - json={'subject_assignments': subject_assignment_mock} - ) - - -def register_policy_object_assignment(m, policy_id, obj_id): - m.register_uri( - 'GET', 'http://{}:{}/{}/{}/object_assignments/{}'.format(CONF['components']['manager']['hostname'], - CONF['components']['manager']['port'], 'policies', - policy_id, - obj_id), - json={'object_assignments': object_assignment_mock} - ) - - -def register_policy_object_assignment_list(m, policy_id): - m.register_uri( - 'GET', 'http://{}:{}/{}/{}/object_assignments'.format(CONF['components']['manager']['hostname'], - CONF['components']['manager']['port'], 'policies', - policy_id), - json={'object_assignments': object_assignment_mock} - ) - - -def register_policy_action_assignment(m, policy_id, action_id): - m.register_uri( - 'GET', 'http://{}:{}/{}/{}/action_assignments/{}'.format(CONF['components']['manager']['hostname'], - CONF['components']['manager']['port'], 'policies', - policy_id, - action_id), - json={'action_assignments': action_assignment_mock} - ) - - -def register_policy_action_assignment_list(m, policy_id): - m.register_uri( - 'GET', 'http://{}:{}/{}/{}/action_assignments'.format(CONF['components']['manager']['hostname'], - CONF['components']['manager']['port'], 'policies', - policy_id), - json={'action_assignments': action_assignment_mock} - ) - - -def register_rules(m, policy_id): - m.register_uri( - 'GET', 'http://{}:{}/{}/{}/{}'.format(CONF['components']['manager']['hostname'], - CONF['components']['manager']['port'], 'policies', - policy_id, 'rules'), - json={'rules': rules_mock} - )
\ No newline at end of file diff --git a/python_moonutilities/tests/unit_python/mock_components.py b/python_moonutilities/tests/unit_python/mock_components.py deleted file mode 100644 index a0319e1a..00000000 --- a/python_moonutilities/tests/unit_python/mock_components.py +++ /dev/null @@ -1,27 +0,0 @@ -import utilities - -COMPONENTS = ( - "logging", - "openstack/keystone", - "database", - "slave", - "components/manager", - "components/orchestrator", - "components/interface", -) - - -def register_components(m): - for component in COMPONENTS: - m.register_uri( - 'GET', 'http://consul:8500/v1/kv/{}'.format(component), - json=[{'Key': component, 'Value': utilities.get_b64_conf(component)}] - ) - - m.register_uri( - 'GET', 'http://consul:8500/v1/kv/components?recurse=true', - json=[ - {"Key": key, "Value": utilities.get_b64_conf(key)} for key in COMPONENTS - ], - # json={'Key': "components", 'Value': get_b64_conf("components")} - )
\ No newline at end of file diff --git a/python_moonutilities/tests/unit_python/mock_keystone.py b/python_moonutilities/tests/unit_python/mock_keystone.py deleted file mode 100644 index c0b26b88..00000000 --- a/python_moonutilities/tests/unit_python/mock_keystone.py +++ /dev/null @@ -1,23 +0,0 @@ -def register_keystone(m): - m.register_uri( - 'POST', 'http://keystone:5000/v3/auth/tokens', - headers={'X-Subject-Token': "111111111"} - ) - m.register_uri( - 'DELETE', 'http://keystone:5000/v3/auth/tokens', - headers={'X-Subject-Token': "111111111"} - ) - m.register_uri( - 'POST', 'http://keystone:5000/v3/users?name=testuser&domain_id=default', - json={"users": {}} - ) - m.register_uri( - 'GET', 'http://keystone:5000/v3/users?name=testuser&domain_id=default', - json={"users": {}} - ) - m.register_uri( - 'POST', 'http://keystone:5000/v3/users/', - json={"users": [{ - "id": "1111111111111" - }]} - )
\ No newline at end of file diff --git a/python_moonutilities/tests/unit_python/mock_repo/__init__.py b/python_moonutilities/tests/unit_python/mock_repo/__init__.py new file mode 100644 index 00000000..60dfbc3b --- /dev/null +++ b/python_moonutilities/tests/unit_python/mock_repo/__init__.py @@ -0,0 +1,38 @@ +import mock_repo.urls as register_urls +import mock_repo.data as data_mock + + +def register_cache(m): + """ Modify the response from Requests module + """ + register_urls.register_components(m) + register_urls.register_keystone(m) + + register_urls.register_pdp(m) + register_urls.register_meta_rules(m) + register_urls.register_policies(m) + register_urls.register_models(m) + + register_urls.register_policy_subject(m, data_mock.shared_ids["policy"]["policy_id_1"]) + register_urls.register_policy_subject_invalid_response(m, data_mock.shared_ids["policy"]["policy_id_invalid_response"]) + register_urls.register_policy_object(m, data_mock.shared_ids["policy"]["policy_id_1"]) + register_urls.register_policy_action(m, data_mock.shared_ids["policy"]["policy_id_1"]) + + register_urls.register_policy_subject_assignment(m, data_mock.shared_ids["policy"]["policy_id_1"], data_mock.shared_ids["perimeter"]["perimeter_id_1"]) + + register_urls.register_policy_subject_assignment_list(m, data_mock.shared_ids["policy"]["policy_id_2"]) + + register_urls.register_policy_object_assignment(m, data_mock.shared_ids["policy"]["policy_id_1"], data_mock.shared_ids["perimeter"]["perimeter_id_2"]) + + register_urls.register_policy_object_assignment_list(m, data_mock.shared_ids["policy"]["policy_id_2"]) + + register_urls.register_policy_action_assignment(m, data_mock.shared_ids["policy"]["policy_id_1"], data_mock.shared_ids["perimeter"]["perimeter_id_3"]) + + register_urls.register_policy_action_assignment_list(m, data_mock.shared_ids["policy"]["policy_id_2"]) + # register_urls.register_pods(m) + + # register_urls.register_policy_action_assignment(m, "policy_id_2", "perimeter_id_2") + # register_urls.register_policy_action_assignment(m, "policy_id_2", "perimeter_id_2") + # register_urls.register_policy_action_assignment(m, "policy_id_2", "perimeter_id_2") + + register_urls.register_rules(m, "policy_id1") diff --git a/python_moonutilities/tests/unit_python/utilities.py b/python_moonutilities/tests/unit_python/mock_repo/components_utilities.py index 1d79d890..1d79d890 100644 --- a/python_moonutilities/tests/unit_python/utilities.py +++ b/python_moonutilities/tests/unit_python/mock_repo/components_utilities.py diff --git a/python_moonutilities/tests/unit_python/mock_repo/data.py b/python_moonutilities/tests/unit_python/mock_repo/data.py new file mode 100644 index 00000000..736d4704 --- /dev/null +++ b/python_moonutilities/tests/unit_python/mock_repo/data.py @@ -0,0 +1,215 @@ +components = ( + "logging", + "openstack/keystone", + "database", + "slave", + "components/manager", + "components/orchestrator", + "components/interface", + "components/port_start" +) + +shared_ids = { + "policy": { + "policy_id_1": "policy_id_1", + "policy_id_2": "policy_id_2", + "policy_id_3": "policy_id_3", + "policy_id_invalid_response": "policy_id_invalid_response" + }, + "category": { + "category_id_1": "category_id_1", + "invalid_category_id_1": " invalid_category_id_1" + }, + "perimeter": { + "perimeter_id_1": "subject_id_1", + "perimeter_id_2": "object_id_1", + "perimeter_id_3": "action_id_1" + }, + "meta_rule": { + "meta_rule_id_1": "meta_rule_id_1", + "meta_rule_id_2": "meta_rule_id_2" + }, + "rule": { + "rule_id_1": "rule_id_2", + "rule_id_2": "rule_id_2" + }, + "model": { + "model_id_1": "model_id_1" + } +} + +pdp_mock = { + "pdp_id1": { + "name": "...", + "security_pipeline": ["policy_id_1", "policy_id_2"], + "keystone_project_id": "keystone_project_id1", + "description": "...", + } +} + +meta_rules_mock = { + shared_ids["meta_rule"]["meta_rule_id_1"]: { + "name": "meta_rule1", + "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"] + }, + shared_ids["meta_rule"]["meta_rule_id_2"]: { + "name": "name of the meta rules2", + "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"] + } +} + +policies_mock = { + shared_ids["policy"]["policy_id_1"]: { + "name": "test_policy1", + "model_id": shared_ids["model"]["model_id_1"], + "genre": "authz", + "description": "test", + } +} + +subject_mock = { + shared_ids["policy"]["policy_id_1"]: { + "subject_id": { + "name": "subject_name", + "keystone_id": "keystone_project_id1", + "description": "a description" + } + }, + shared_ids["policy"]["policy_id_invalid_response"]: { + "subject_id": { + "name": "subject_name", + "keystone_id": "keystone_project_id1", + "description": "a description" + } + } + +} + +subject_assignment_mock = { + "subject_id_1": { + "policy_id": shared_ids["policy"]["policy_id_1"], + "subject_id": "subject_id_1", + "category_id": shared_ids["category"]["category_id_1"], + "assignments": ["data_id_1, data_id_2"], + } +} + +object_mock = { + shared_ids["policy"]["policy_id_1"]: { + "object_id": { + "name": "object_name", + "description": "a description" + } + } +} + +object_assignment_mock = { + "object_id_1": { + "policy_id": shared_ids["policy"]["policy_id_1"], + "object_id": "object_id_1", + "category_id": shared_ids["category"]["category_id_1"], + "assignments": ["data_id_1, data_id_2"], + } +} + +action_mock = { + shared_ids["policy"]["policy_id_1"]: { + "action_id": { + "name": "action_name", + "description": "a description" + } + } +} + +action_assignment_mock = { + "action_id_1": { + "policy_id": shared_ids["policy"]["policy_id_1"], + "action_id": "action_id_1", + "category_id": shared_ids["category"]["category_id_1"], + "assignments": ["data_id_1, data_id_2"], + } +} + +models_mock = { + shared_ids["model"]["model_id_1"]: { + "name": "test_model", + "description": "test", + "meta_rules": [shared_ids["meta_rule"]["meta_rule_id_1"]] + } +} + +rules_mock = { + "rules": { + "meta_rule_id": shared_ids["meta_rule"]["meta_rule_id_1"], + shared_ids["rule"]["rule_id_1"]: { + "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 + ) + }, + shared_ids["rule"]["rule_id_2"]: { + "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 + ) + } + } +} + +# pods_mock = { +# # "name": "pod_id1", +# # "hostname": "pod_host", +# # "port": { +# # "PrivatePort": "8998", +# # "Type": "tcp", +# # "IP": "0.0.0.0", +# # "PublicPort": "8080" +# # }, +# # "keystone_project_id": "keystone_project_id1", +# # "pdp_id": "", +# # "meta_rule_id": "meta_rule_id1", +# # "container_name": "container_name1", +# # "plugin_name": "plugin_name1", +# # "container_id": "container_id" +# "pod_id1": { +# "name": "pod_id1", +# "hostname": "pod_host", +# "port": { +# "PrivatePort": "8998", +# "Type": "tcp", +# "IP": "0.0.0.0", +# "PublicPort": "8080" +# }, +# "keystone_project_id": [1], +# "pdp_id": "", +# "meta_rule_id": "meta_rule_id1", +# "container_name": "container_name1", +# "plugin_name": "plugin_name1", +# "container_id": "container_id" +# }, +# +# } diff --git a/python_moonutilities/tests/unit_python/mock_repo/urls.py b/python_moonutilities/tests/unit_python/mock_repo/urls.py new file mode 100644 index 00000000..a5b1e63b --- /dev/null +++ b/python_moonutilities/tests/unit_python/mock_repo/urls.py @@ -0,0 +1,147 @@ +import mock_repo.components_utilities as comp_util +import mock_repo.data as data_mock + + +def register_components(m): + for component in data_mock.components: + m.register_uri( + 'GET', 'http://consul:8500/v1/kv/{}'.format(component), + json=[{'Key': component, 'Value': comp_util.get_b64_conf(component)}] + ) + m.register_uri( + 'GET', 'http://consul:8500/v1/kv/components_port_start', + json=[{'Key': 'components_port_start', 'Value': comp_util.get_b64_conf("components/port_start")}] + ) + m.register_uri( + 'PUT', 'http://consul:8500/v1/kv/components_port_start', + json=[] + ) + + m.register_uri( + 'GET', 'http://consul:8500/v1/kv/components?recurse=true', + json=[ + {"Key": key, "Value": comp_util.get_b64_conf(key)} for key in data_mock.components + ], + # json={'Key': "components", 'Value': get_b64_comp_util.CONF("components")} + ) + + +def register_keystone(m): + m.register_uri( + 'POST', 'http://keystone:5000/v3/auth/tokens', + headers={'X-Subject-Token': "111111111"} + ) + m.register_uri( + 'DELETE', 'http://keystone:5000/v3/auth/tokens', + headers={'X-Subject-Token': "111111111"} + ) + m.register_uri( + 'POST', 'http://keystone:5000/v3/users?name=testuser&domain_id=default', + json={"users": {}} + ) + m.register_uri( + 'GET', 'http://keystone:5000/v3/users?name=testuser&domain_id=default', + json={"users": {}} + ) + m.register_uri( + 'POST', 'http://keystone:5000/v3/users/', + json={"users": [{ + "id": "1111111111111" + }]} + ) + +def register_model_any(m, module_name, mocked_data, key=None): + if key is None: + key = module_name + m.register_uri( + 'GET', 'http://{}:{}/{}'.format(comp_util.CONF['components']['manager']['hostname'], + comp_util.CONF['components']['manager']['port'], module_name), + + json={key: mocked_data} + ) + +def register_policy_any(m, policy_id, module_name, mocked_data, key=None): + if key is None: + key = module_name + m.register_uri( + 'GET', 'http://{}:{}/{}/{}/{}'.format(comp_util.CONF['components']['manager']['hostname'], + comp_util.CONF['components']['manager']['port'], 'policies', + policy_id, module_name), + json={key: mocked_data} + ) + +def register_pdp(m): + register_model_any(m, 'pdp', data_mock.pdp_mock,'pdps') + +def register_meta_rules(m): + register_model_any(m, 'meta_rules',data_mock.meta_rules_mock) + +def register_policies(m): + register_model_any(m, 'policies', data_mock.policies_mock) + + +def register_models(m): + register_model_any(m, 'models', data_mock.models_mock) + +def register_policy_subject(m, policy_id): + register_policy_any(m, policy_id, 'subjects', data_mock.subject_mock[policy_id]) + + +def register_policy_subject_invalid_response(m, policy_id): + register_policy_any(m, policy_id, 'subjects', data_mock.subject_mock[policy_id],'subjects_invalid_key') + +def register_policy_object(m, policy_id): + register_policy_any(m, policy_id, 'objects', data_mock.object_mock[policy_id]) + +def register_policy_action(m, policy_id): + register_policy_any(m, policy_id, 'actions', data_mock.action_mock[policy_id]) + +def register_policy_subject_assignment_list(m, policy_id): + register_policy_any(m, policy_id, 'subject_assignments', data_mock.subject_assignment_mock) + +def register_policy_object_assignment_list(m, policy_id): + register_policy_any(m, policy_id, 'object_assignments', data_mock.object_assignment_mock) + + +def register_policy_action_assignment_list(m, policy_id): + register_policy_any(m, policy_id, 'action_assignments', data_mock.action_assignment_mock) + +def register_policy_subject_assignment(m, policy_id, perimeter_id): + m.register_uri( + 'GET', 'http://{}:{}/{}/{}/subject_assignments/{}'.format(comp_util.CONF['components']['manager']['hostname'], + comp_util.CONF['components']['manager']['port'], + 'policies', + policy_id, + perimeter_id), + json={'subject_assignments': data_mock.subject_assignment_mock} + ) + +def register_policy_object_assignment(m, policy_id, perimeter_id): + m.register_uri( + 'GET', 'http://{}:{}/{}/{}/object_assignments/{}'.format(comp_util.CONF['components']['manager']['hostname'], + comp_util.CONF['components']['manager']['port'], + 'policies', + policy_id, + perimeter_id), + json={'object_assignments': data_mock.object_assignment_mock} + ) + +def register_policy_action_assignment(m, policy_id, perimeter_id): + m.register_uri( + 'GET', 'http://{}:{}/{}/{}/action_assignments/{}'.format(comp_util.CONF['components']['manager']['hostname'], + comp_util.CONF['components']['manager']['port'], + 'policies', + policy_id, + perimeter_id), + json={'action_assignments': data_mock.action_assignment_mock} + ) + +def register_rules(m, policy_id): + register_policy_any(m, policy_id, 'rules', data_mock.rules_mock) + +# def register_pods(m): +# m.register_uri( +# 'GET', 'http://{}:{}/pods'.format(comp_util.CONF['components']['orchestrator']['hostname'], +# comp_util.CONF['components']['orchestrator']['port']), +# json={'pods': data_mock.pods_mock} +# ) diff --git a/python_moonutilities/tests/unit_python/test_cache.py b/python_moonutilities/tests/unit_python/test_cache.py index c479395b..db1e3ae7 100644 --- a/python_moonutilities/tests/unit_python/test_cache.py +++ b/python_moonutilities/tests/unit_python/test_cache.py @@ -1,4 +1,5 @@ import pytest +import mock_repo.data as data_mock def test_authz_request(): @@ -7,63 +8,219 @@ def test_authz_request(): assert isinstance(c.authz_requests, dict) +# tests for get (subject, object, action) in cache +# ================================================ def test_get_subject_success(): from python_moonutilities import cache cache_obj = cache.Cache() - policy_id = 'policy_id_1' name = 'subject_name' - subject_id = cache_obj.get_subject(policy_id, name) + subject_id = cache_obj.get_subject(data_mock.shared_ids["policy"]["policy_id_1"], name) assert subject_id is not None -def test_get_subject_failure(): +def test_get_subject_not_found(): from python_moonutilities import cache - cache_obj = cache.Cache() - policy_id = 'policy_id_1' + cache_obj2 = cache.Cache() name = 'invalid name' with pytest.raises(Exception) as exception_info: - cache_obj.get_subject(policy_id, name) + cache_obj2.get_subject(data_mock.shared_ids["policy"]["policy_id_1"], name) assert str(exception_info.value) == '400: Subject Unknown' +# [TODO] this test used to test the invalid response +# it should be un commented and run after refactoring the related part +def test_get_subject_invalid_response(): + from python_moonutilities import cache + cache_obj2 = cache.Cache() + # policy_id = 'policy_id_invalid_response' + name = 'invalid name' + + +# with pytest.raises(Exception) as exception_info: +# cache_obj2.get_subject(data_mock.shared_ids["policy"]["policy_id_invalid_response"], name) +# assert str(exception_info.value) == '400: Subject Unknown' + + def test_get_object_success(): from python_moonutilities import cache cache_obj = cache.Cache() - policy_id = 'policy_id_1' name = 'object_name' - object_id = cache_obj.get_object(policy_id, name) + object_id = cache_obj.get_object(data_mock.shared_ids["policy"]["policy_id_1"], name) assert object_id is not None def test_get_object_failure(): from python_moonutilities import cache cache_obj = cache.Cache() - policy_id = 'policy_id_1' name = 'invalid name' with pytest.raises(Exception) as exception_info: - cache_obj.get_object(policy_id, name) + cache_obj.get_object(data_mock.shared_ids["policy"]["policy_id_1"], name) assert str(exception_info.value) == '400: Subject Unknown' def test_get_action_success(): from python_moonutilities import cache cache_obj = cache.Cache() - policy_id = 'policy_id_1' name = 'action_name' - action_id = cache_obj.get_action(policy_id, name) + action_id = cache_obj.get_action(data_mock.shared_ids["policy"]["policy_id_1"], name) assert action_id is not None def test_get_action_failure(): from python_moonutilities import cache cache_obj = cache.Cache() - policy_id = 'policy_id_1' name = 'invalid name' with pytest.raises(Exception) as exception_info: - cache_obj.get_action(policy_id, name) + cache_obj.get_action(data_mock.shared_ids["policy"]["policy_id_1"], name) assert str(exception_info.value) == '400: Subject Unknown' +# ==================================================================================================== + +# tests for get (subject_assignment, object_assignment, action_assignment) in cache +# ================================================================================= + +def test_get_subject_assignment_success(): + from python_moonutilities import cache + cache_obj = cache.Cache() + subject_assignments = cache_obj.get_subject_assignments(data_mock.shared_ids["policy"]["policy_id_1"], + data_mock.shared_ids["perimeter"]["perimeter_id_1"], + data_mock.shared_ids["category"]["category_id_1"]) + assert subject_assignments is not None + + +def test_get_subject_assignment_failure(): + from python_moonutilities import cache + cache_obj = cache.Cache() + subject_assignments = cache_obj.get_subject_assignments(data_mock.shared_ids["policy"]["policy_id_2"], + '', + data_mock.shared_ids["category"]["category_id_1"]) + assert len(subject_assignments) == 0 + + +def test_get_subject_assignment_invalid_category_failure(): + from python_moonutilities import cache + cache_obj = cache.Cache() + subject_assignments = cache_obj.get_subject_assignments(data_mock.shared_ids["policy"]["policy_id_1"], + data_mock.shared_ids["perimeter"]["perimeter_id_1"], + data_mock.shared_ids["category"]["invalid_category_id_1"]) + assert len(subject_assignments) == 0 + + +def test_get_object_assignment_success(): + from python_moonutilities import cache + cache_obj = cache.Cache() + object_assignments = cache_obj.get_object_assignments(data_mock.shared_ids["policy"]["policy_id_1"], + data_mock.shared_ids["perimeter"]["perimeter_id_2"], + data_mock.shared_ids["category"]["category_id_1"]) + assert object_assignments is not None + + +def test_get_object_assignment_failure(): + from python_moonutilities import cache + cache_obj = cache.Cache() + object_assignments = cache_obj.get_object_assignments(data_mock.shared_ids["policy"]["policy_id_2"], + '', + data_mock.shared_ids["category"]["category_id_1"]) + assert len(object_assignments) == 0 + + +def test_get_object_assignment_invalid_category_failure(): + from python_moonutilities import cache + cache_obj = cache.Cache() + object_assignments = cache_obj.get_object_assignments(data_mock.shared_ids["policy"]["policy_id_1"], + data_mock.shared_ids["perimeter"]["perimeter_id_1"], + data_mock.shared_ids["category"]["invalid_category_id_1"]) + assert len(object_assignments) == 0 + + +def test_get_action_assignment_success(): + from python_moonutilities import cache + cache_obj = cache.Cache() + action_assignments = cache_obj.get_action_assignments(data_mock.shared_ids["policy"]["policy_id_1"], + data_mock.shared_ids["perimeter"]["perimeter_id_3"], + data_mock.shared_ids["category"]["category_id_1"]) + assert action_assignments is not None + + +def test_get_action_assignment_failure(): + from python_moonutilities import cache + cache_obj = cache.Cache() + action_assignments = cache_obj.get_action_assignments(data_mock.shared_ids["policy"]["policy_id_2"], + '', + data_mock.shared_ids["category"]["category_id_1"]) + assert len(action_assignments) == 0 + + +def test_get_action_assignment_invalid_category_failure(): + from python_moonutilities import cache + cache_obj = cache.Cache() + action_assignments = cache_obj.get_action_assignments(data_mock.shared_ids["policy"]["policy_id_1"], + data_mock.shared_ids["perimeter"]["perimeter_id_1"], + data_mock.shared_ids["category"]["invalid_category_id_1"]) + assert len(action_assignments) == 0 + + +# ==================================================================================================== + +# tests for helper function in cache +# ================================== +def test_get_policy_from_meta_rules_success(): + from python_moonutilities import cache + cache_obj = cache.Cache() + policy_id = cache_obj.get_policy_from_meta_rules(data_mock.shared_ids["meta_rule"]["meta_rule_id_1"]) + assert policy_id is not None + + +# def test_get_policy_from_meta_rules_failure(): +# from python_moonutilities import cache +# cache_obj = cache.Cache() +# meta_rule_id = 'meta_rule_id3' +# policy_id = cache_obj.get_policy_from_meta_rules(meta_rule_id) +# assert policy_id is None + + +def test_get_pdp_from_keystone_project_success(): + from python_moonutilities import cache + cache_obj = cache.Cache() + keystone_project_id = 'keystone_project_id1' + pdp_key = cache_obj.get_pdp_from_keystone_project(keystone_project_id) + assert pdp_key is not None + + +def test_get_pdp_from_keystone_project_failure(): + from python_moonutilities import cache + cache_obj = cache.Cache() + keystone_project_id = 'keystone_project_id2' + pdp_key = cache_obj.get_pdp_from_keystone_project(keystone_project_id) + assert pdp_key is None + + +def test_get_keystone_project_id_from_policy_id_success(): + from python_moonutilities import cache + cache_obj = cache.Cache() + keystone_project_id = cache_obj.get_keystone_project_id_from_policy_id( + data_mock.shared_ids["policy"]["policy_id_1"]) + assert keystone_project_id is not None + + +def test_get_keystone_project_id_from_policy_id_failure(): + from python_moonutilities import cache + cache_obj = cache.Cache() + policy_id = 'policy_id_3' + keystone_project_id = cache_obj.get_keystone_project_id_from_policy_id(policy_id) + assert keystone_project_id is None + + +# def test_get_containers_from_keystone_project_id_success(): +# from python_moonutilities import cache +# cache_obj = cache.Cache() +# keystone_project_id = 1 +# meta_rule_id = 'meta_rule_id1' +# container_id, container_value = cache_obj.get_containers_from_keystone_project_id(keystone_project_id, meta_rule_id) +# assert container_id, container_value is not None + + def test_cache_manager(): from python_moonutilities import cache cache_obj = cache.Cache() @@ -71,5 +228,5 @@ def test_cache_manager(): assert cache_obj.meta_rules is not None assert len(cache_obj.meta_rules) == 2 assert cache_obj.policies is not None - assert len(cache_obj.policies) == 2 - assert cache_obj.models is not None
\ No newline at end of file + assert len(cache_obj.policies) == 1 + assert cache_obj.models is not None diff --git a/python_moonutilities/tests/unit_python/test_configuration.py b/python_moonutilities/tests/unit_python/test_configuration.py index 48699062..10618f1c 100644 --- a/python_moonutilities/tests/unit_python/test_configuration.py +++ b/python_moonutilities/tests/unit_python/test_configuration.py @@ -1,5 +1,57 @@ +import mock_repo.components_utilities as comp_util +import pytest +import requests_mock -def test_get_components(): + +def test_get_configuration_success(): + from python_moonutilities import configuration + assert configuration.get_configuration("components/port_start")["components/port_start"] == comp_util.CONF["components"]["port_start"] + + +@requests_mock.Mocker(kw='mock') +def test_get_configuration_not_found(**kwargs): from python_moonutilities import configuration - assert isinstance(configuration.get_components(), dict) + kwargs['mock'].get('http://consul:8500/v1/kv/components/port_start_wrong', json=[ + ], status_code=500) + with pytest.raises(Exception) as exception_info: + configuration.get_configuration("components/port_start_wrong") + assert str(exception_info.value) == '500: Consul error' + + +# [TODO] this test used to test the invalid response +# it should be un commented and run after refactoring the related part +@requests_mock.Mocker(kw='mock') +def test_get_configuration_invalid_response(**kwargs): + from python_moonutilities import configuration + + kwargs['mock'].get('http://consul:8500/v1/kv/components_port_start', json=[ + {"components_port_start":'components_port_start', 'Value': comp_util.get_b64_conf("components/port_start")} + ]) + # with pytest.raises(Exception) as exception_info: + # configuration.get_configuration("components_port_start") + # assert str(exception_info.value) == '500: Consul error' + + +@requests_mock.Mocker(kw='mock') +def test_put_increment_port_failure(**kwargs): + from python_moonutilities import configuration + kwargs['mock'].put('http://consul:8500/v1/kv/components_port_start', json=[], status_code=400) + kwargs['mock'].get('http://consul:8500/v1/kv/components_port_start', json=[ + {'Key': 'components_port_start', 'Value': comp_util.get_b64_conf("components/port_start")} + ], status_code=200) + with pytest.raises(Exception) as exception_info: + configuration.increment_port() + assert str(exception_info.value) == '400: Consul error' + + +def test_increment_port_success(): + from python_moonutilities import configuration + cur_port = comp_util.CONF["components"]["port_start"] + incremented_port = configuration.increment_port() + assert incremented_port == cur_port + 1 + + +def test_get_components(): + from python_moonutilities import configuration + assert isinstance(configuration.get_components(), dict)
\ No newline at end of file diff --git a/tests/README.md b/tests/README.md new file mode 100644 index 00000000..c1437a2d --- /dev/null +++ b/tests/README.md @@ -0,0 +1,77 @@ +# Moon Tests +## Functional Tests +### Test Platform Setup +#### Docker Installation +```bash +apt update +apt install -y docker.io +``` + +#### Kubeadm Installation +see: https://kubernetes.io/docs/setup/independent/install-kubeadm/ +```bash +apt-get update && apt-get install -y apt-transport-https +curl -s https://packages.cloud.google.com/apt/doc/apt-key.gpg | apt-key add - +cat <<EOF >/etc/apt/sources.list.d/kubernetes.list +deb http://apt.kubernetes.io/ kubernetes-xenial main +EOF +apt-get update +apt-get install -y kubelet kubeadm kubectl +``` + +#### K8S Initialisation +```bash +cd $MOON_HOME +bash tools/moon_kubernetes/init_k8s.sh +``` + +Wait until all the kubeadm containers are in the `running` state: +```bash +watch kubectl get po --namespace=kube-system +``` + +You must see something like this: + + $ kubectl get po --namespace=kube-system + NAME READY STATUS RESTARTS AGE + calico-etcd-7qgjb 1/1 Running 0 1h + calico-node-f8zvm 2/2 Running 1 1h + calico-policy-controller-59fc4f7888-ns9kv 1/1 Running 0 1h + etcd-varuna 1/1 Running 0 1h + kube-apiserver-varuna 1/1 Running 0 1h + kube-controller-manager-varuna 1/1 Running 0 1h + kube-dns-bfbb49cd7-rgqxn 3/3 Running 0 1h + kube-proxy-x88wg 1/1 Running 0 1h + kube-scheduler-varuna 1/1 Running 0 1h + + +#### Deploy Moon +```bash +cd $MOON_HOME +sudo bash tools/moon_kubernetes/start_moon.sh +``` + +Wait until all the Moon containers are in the `running` state: +```bash +watch kubectl get po --namespace=moon +``` + +You must see something like this: + + $ kubectl get po --namespace=moon + NAME READY STATUS RESTARTS AGE + consul-57b6d66975-9qnfx 1/1 Running 0 52m + db-867f9c6666-bq8cf 1/1 Running 0 52m + gui-bc9878b58-q288x 1/1 Running 0 51m + keystone-7d9cdbb69f-bl6ln 1/1 Running 0 52m + manager-5bfbb96988-2nvhd 1/1 Running 0 51m + manager-5bfbb96988-fg8vj 1/1 Running 0 51m + manager-5bfbb96988-w9wnk 1/1 Running 0 51m + orchestrator-65d8fb4574-tnfx2 1/1 Running 0 51m + wrapper-astonishing-748b7dcc4f-ngsvp 1/1 Running 0 51m + +### Launch Functional for Target Module +```bash +cd $MOON_HOME +sudo bash $TARGET_MODULE/tests/functional_pod/run_functional_tests.sh +``` diff --git a/tests/functional/scenario_tests/mls.py b/tests/functional/scenario_tests/mls.py new file mode 100644 index 00000000..0e6285c9 --- /dev/null +++ b/tests/functional/scenario_tests/mls.py @@ -0,0 +1,59 @@ + +pdp_name = "pdp_mls" +policy_name = "MLS Policy example" +model_name = "MLS" +policy_genre = "authz" + +subjects = {"adminuser": "", "user1": "", "user2": "", } +objects = {"vm0": "", "vm1": "", } +actions = {"start": "", "stop": ""} + +subject_categories = {"subject-security-level": "", } +object_categories = {"object-security-level": "", } +action_categories = {"action-type": "", } + +subject_data = { + "subject-security-level": {"low": "", "medium": "", "high": ""}, +} +object_data = { + "object-security-level": {"low": "", "medium": "", "high": ""}, +} +action_data = {"action-type": {"vm-action": "", "storage-action": "", }} + +subject_assignments = { + "adminuser": {"subject-security-level": "high"}, + "user1": {"subject-security-level": "medium"}, +} +object_assignments = { + "vm0": {"object-security-level": "medium"}, + "vm1": {"object-security-level": "low"}, +} +action_assignments = { + "start": {"action-type": "vm-action"}, + "stop": {"action-type": "vm-action"} +} + +meta_rule = { + "mls": { + "id": "", + "value": ("subject-security-level", + "object-security-level", + "action-type")}, +} + +rules = { + "mls": ( + { + "rule": ("high", "medium", "vm-action"), + "instructions": ({"decision": "grant"}) + }, + { + "rule": ("high", "low", "vm-action"), + "instructions": ({"decision": "grant"}) + }, + { + "rule": ("medium", "low", "vm-action"), + "instructions": ({"decision": "grant"}) + }, + ) +} diff --git a/tests/functional/scenario_tests/rbac.py b/tests/functional/scenario_tests/rbac.py new file mode 100644 index 00000000..1d2cabee --- /dev/null +++ b/tests/functional/scenario_tests/rbac.py @@ -0,0 +1,61 @@ + +pdp_name = "pdp_rbac1" +policy_name = "RBAC policy example" +model_name = "RBAC" +policy_genre = "authz" + +subjects = {"adminuser": "", "user1": "", } +objects = {"vm0": "", "vm1": "", } +actions = {"start": "", "stop": ""} + +subject_categories = {"role": "", } +object_categories = {"id": "", } +action_categories = {"action-type": "", } + +subject_data = {"role": {"admin": "", "employee": "", "*": ""}} +object_data = {"id": {"vm0": "", "vm1": "", "*": ""}} +action_data = {"action-type": {"vm-action": "", "*": ""}} + +subject_assignments = { + "adminuser": + ({"role": "admin"}, {"role": "employee"}, {"role": "*"}), + "user1": + ({"role": "employee"}, {"role": "*"}), +} +object_assignments = { + "vm0": + ({"id": "vm0"}, {"id": "*"}), + "vm1": + ({"id": "vm1"}, {"id": "*"}) +} +action_assignments = { + "start": + ({"action-type": "vm-action"}, {"action-type": "*"}), + "stop": + ({"action-type": "vm-action"}, {"action-type": "*"}) +} + +meta_rule = { + "rbac": {"id": "", "value": ("role", "id", "action-type")}, +} + +rules = { + "rbac": ( + { + "rule": ("admin", "vm0", "vm-action"), + "instructions": ( + {"decision": "grant"}, + # "grant" to immediately exit, + # "continue" to wait for the result of next policy + ) + }, + { + "rule": ("employee", "vm1", "vm-action"), + "instructions": ( + {"decision": "grant"}, + ) + }, + ) +} + + diff --git a/tests/performance/README.md b/tests/performance/README.md index 52613d2c..fcb80589 100644 --- a/tests/performance/README.md +++ b/tests/performance/README.md @@ -1,69 +1,80 @@ -# Moon Yardstick and Bottlenecks Performance Tests +# Moon Yardstick/Bottlenecks Performance Tests The main objective of this document is to describe the performance tests for the Moon project/module. -Moon is a security managment platform which provides a set of security functions to project the underlying OPNFV infrastructure and/or VNFs. -Moon is consisted of 2 parts: a master and a set of slaves. The master holds all security-related information and each slave only fetches and holds -related informations for its local usage from master. +Moon is a security management platform which provides a set of security functions to project the underlying OPNFV infrastructure and/or VNFs. +It is consisted of 2 parts: a master and a set of slaves. The master holds all security-related information and each slave only fetches and holds +related information for its local usage from master. -## Moon Master Performance Tests -In this test, we should: +## Master Performance Tests +### Pre-requisite - setup a Moon master service on a physical server -- create a tenant/scope through the Moon master service -- create a MSL security policy with 4 subject security levels and 4 object security levels for this tenant +- create a project in OpenStack/Keystone +- create a MSL PDP with a model of 4 subject security levels and 4 object security levels, the MLS policy will be defined later -- increase N to find the limit of the security policy (implemented in format of a Docker) - - create N users and N resources (VMs in our case) in this tenant - - simulate 2 operation requests per user per second to Moon's authorization endpoint - - gather performance metrics like CPU, memory, network usages - - throught the iteration, determine the capacity limit for one Docker +### Policy Size Test +Increase the number of users and resources N to find the limit of the security policy +- create N users and N resources (VMs in our case) in this MLS security policy +- sends 5 authz requests/second +- gather performance metrics like CPU, memory, network usages +Through the iteration, determine the maximal number of N to support 5 requests/second -- setup 20 user and 20 resources (VMs in our case) for one tenant - - increase the number of tenants to test the maximal number of tenants on the server +### PDP Number Test +- setup 20 user and 20 resources (VMs in our case) for each MLS PDP +- sends 5 authz requests/second for each MLS PDP +- increase the number of PDP to test the maximal number of PDP on the master -- setup 5 tenants of N users and N resources (VMs in our case) in each tenant - - increase N by simulating 2 operation requests per user per second to the Moon's authorization endpoint - - gather performance metrics like CPU, memory, network usages - - throught the iteration, dermine the maximal user/resource number of these 5 tenants/Dockers on the server +### Policy Size Test for 5 PDPs +- setup 5 PDPs of N users and N resources (VMs in our case) +- sends 5 authz requests/second for each MLS PDP +- gather performance metrics like CPU, memory, network usages +Through the iteration, determine the maximal user/resource number of these 5 PDPs -- setup 10 tenants of N users and N resources (VMs in our case) in each tenant - - increase N by simulating 2 operation requests per user per second to the Moon's authorization endpoint - - gather performance metrics like CPU, memory, network usages - - throught the iteration, dermine the maximal user/resource number of these 10 tenants/Dockers on the server +### Policy Size Test for 10 PDPs +- setup 10 PDPs of N users and N resources (VMs in our case) +- sends 5 authz requests/second for each MLS PDP +- gather performance metrics like CPU, memory, network usages +Through the iteration, determine the maximal user/resource number of these 10 PDPs -- setup 20 tenants of N users and N resources (VMs in our case) in each tenant - - increase N by simulating 2 operation requests per user per second to the Moon's authorization endpoint - - gather performance metrics like CPU, memory, network usages - - throught the iteration, dermine the maximal user/resource number of these 20 tenants/Dockers on the server - -## Moon Slave Performace Tests -In this test, we should: -- setup a Moon master service on a physical server -- setup a Moon slave service on a physical server -- create a tenant/scope through the Moon master service -- create a MSL security policy with 4 subject security levels and 4 object security levels for this tenant through the Moon master service +### Policy Size Test for 20 PDPs +- setup 20 PDPs of N users and N resources (VMs in our case) +- sends 5 authz requests/second for each MLS PDP +- gather performance metrics like CPU, memory, network usages +Through the iteration, determine the maximal user/resource number of these 20 PDPs -- increase N to find the limit of the security policy (implemented in format of a Docker) - - create N users and N resources (VMs in our case) in this tenant - - simulate 2 operation requests per user per second to Moon slave's authorizatoin endpoint - - gather performance metrics like CPU, memory, network usages of Moon slave - - throught the iteration, dermine the capacity limit for one Docker of Moon slave - -- setup 20 user and 20 resources (VMs in our case) for one tenant through the Moon slave service - - increate the number of tenants to test the maximal number of tenants on the server of the Moon slave - -- setup 5 tenants of N users and N resources (VMs in our case) in each tenant through the Moon master service - - increate N by simulating 2 operation requests per user per second to the Moon slave's authorization endpoint - - gather performance metrics like CPU, memory, network usages of both Moon master and Moon slave - - throught the iteration, dermine the maximal user/resource number of these 5 tenants/Dockers on the server of Moon slave -- setup 10 tenants of N users and N resources (VMs in our case) in each tenant through the Moon master service - - increate N by simulating 2 operation requests per user per second to the Moon slave's authorization endpoint - - gather performance metrics like CPU, memory, network usages of both Moon master and slave - - throught the iteration, dermine the maximal user/resource number of these 10 tenants/Dockers on the server of the Moon slave +## Master-Slave Performance Tests +### Pre-requisite +- setup a Moon master on a physical server +- setup a Moon slave on a physical server +- create a project in OpenStack/Keystone +- create a MSL PDP with a model of 4 subject security levels and 4 object security levels, the MLS policy will be defined later on the master + +### Slave Policy Size Test +Increase the number of users and resources N to find the limit of the security policy +- create N users and N resources (VMs in our case) in this MLS security policy on the master +- sends 5 authz requests/second to the slave +- gather performance metrics like CPU, memory, network usages of the slave +Through the iteration, determine the maximal number of N to support 5 requests/second of the slave + +### Slave PDP Number Test +- setup 20 user and 20 resources (VMs in our case) for each MLS PDP on the master +- sends 5 authz requests/second for each MLS PDP to the slave +Through the iteration, determine the maximal number of PDP to support 5 requests/second of the slave -- setup 20 tenants of N users and N resources (VMs in our case) in each tenant through the Moon master service - - increate N by simulating 2 operation requests per user per second to the Moon slave's authorization endpoint - - gather performance metrics like CPU, memory, network usages of both Moon master and slave - - throught the iteration, dermine the maximal user/resource number of these 20 tenants/Dockers on the server of the Moon slave +### Slave Policy Size Test for 5 PDPs +- setup 5 PDPs of N users and N resources (VMs in our case) on the master +- sends 5 authz requests/second for each MLS PDP to the slave +- gather performance metrics like CPU, memory, network usages of the slave +Through the iteration, determine the maximal user/resource number of these 5 PDPs +### Slave Policy Size Test for 10 PDPs +- setup 10 PDPs of N users and N resources (VMs in our case) on the master +- sends 5 authz requests/second for each MLS PDP to the slave +- gather performance metrics like CPU, memory, network usages of the slave +Through the iteration, determine the maximal user/resource number of these 10 PDPs +### Slave Policy Size Test for 20 PDPs +- setup 20 PDPs of N users and N resources (VMs in our case) on the master +- sends 5 authz requests/second for each MLS PDP to the slave +- gather performance metrics like CPU, memory, network usages of the slave +Through the iteration, determine the maximal user/resource number of these 20 PDPs diff --git a/tools/bin/README.md b/tools/bin/README.md index 3125c468..71ff4a44 100644 --- a/tools/bin/README.md +++ b/tools/bin/README.md @@ -1,5 +1,8 @@ # Automated Tools/Scripts -## moon_utilities_update -- update moon_utilities to PIP: `./moon_utilities_update.sh upload` -- locally update moon_utilities for each moon Python package: `./moon_utilities_update.sh copy`
\ No newline at end of file +## api2pdf +```bash +python3 $MOON_HOME/tools/bin/api2rst.py +pandoc api.rst --toc -o api.pdf +evince api.pdf +``` diff --git a/moon_interface/tools/api2rst.py b/tools/bin/api2rst.py index 6d407bdf..6d407bdf 100644 --- a/moon_interface/tools/api2rst.py +++ b/tools/bin/api2rst.py diff --git a/tools/bin/delete_orchestrator.sh b/tools/bin/delete_orchestrator.sh index 95fcfddd..9b531e22 100644 --- a/tools/bin/delete_orchestrator.sh +++ b/tools/bin/delete_orchestrator.sh @@ -2,7 +2,7 @@ set +x -kubectl delete -n moon -f kubernetes/templates/moon_orchestrator.yaml +kubectl delete -n moon -f tools/moon_kubernetes/templates/moon_orchestrator.yaml for i in $(kubectl get deployments -n moon | grep wrapper | cut -d " " -f 1 | xargs); do kubectl delete deployments/$i -n moon; done diff --git a/moon_interface/tools/get_keystone_token.py b/tools/bin/get_keystone_token.py index 1856aab8..1856aab8 100644 --- a/moon_interface/tools/get_keystone_token.py +++ b/tools/bin/get_keystone_token.py diff --git a/tools/bin/moon_lib_update.sh b/tools/bin/moon_lib_update.sh deleted file mode 100644 index 3925e336..00000000 --- a/tools/bin/moon_lib_update.sh +++ /dev/null @@ -1,43 +0,0 @@ -#!/usr/bin/env bash - -# usage: moon_update.sh {build,upload,copy} {python_moondb,python_moonutilities} <GPG_ID> - -CMD=$1 -COMPONENT=$2 -GPG_ID=$3 - -VERSION=${COMPONENT}-$(grep __version__ ${COMPONENT}/${COMPONENT}/__init__.py | cut -d "\"" -f 2) - -cd ${COMPONENT} - -python3 setup.py sdist bdist_wheel - -if [ "$CMD" = "upload" ]; then - # Instead of "A0A96E75", use your own GPG ID - rm dist/*.asc 2>/dev/null - gpg --detach-sign -u "${GPG_ID}" -a dist/${VERSION}-py3-none-any.whl - gpg --detach-sign -u "${GPG_ID}" -a dist/${VERSION/_/-}.tar.gz - twine upload dist/${VERSION}-py3-none-any.whl dist/${VERSION}-py3-none-any.whl.asc - twine upload dist/${VERSION/_/-}.tar.gz dist/${VERSION/_/-}.tar.gz.asc -fi - -rm -f ../moon_manager/dist/${COMPONENT}* -rm -f ../moon_orchestrator/dist/${COMPONENT}* -rm -f ../moon_wrapper/dist/${COMPONENT}* -rm -f ../moon_interface/dist/${COMPONENT}* -rm -f ../moon_authz/dist/${COMPONENT}* - - -if [ "$CMD" = "copy" ]; then - mkdir -p ../moon_manager/dist/ 2>/dev/null - cp -v dist/${VERSION}-py3-none-any.whl ../moon_manager/dist/ - mkdir -p ../moon_orchestrator/dist/ 2>/dev/null - cp -v dist/${VERSION}-py3-none-any.whl ../moon_orchestrator/dist/ - mkdir -p ../moon_wrapper/dist/ 2>/dev/null - cp -v dist/${VERSION}-py3-none-any.whl ../moon_wrapper/dist/ - mkdir -p ../moon_interface/dist/ 2>/dev/null - cp -v dist/${VERSION}-py3-none-any.whl ../moon_interface/dist/ - mkdir -p ../moon_authz/dist/ 2>/dev/null - cp -v dist/${VERSION}-py3-none-any.whl ../moon_authz/dist/ -fi - diff --git a/tools/bin/moon_lib_upload.sh b/tools/bin/moon_lib_upload.sh new file mode 100644 index 00000000..d2dc2a3f --- /dev/null +++ b/tools/bin/moon_lib_upload.sh @@ -0,0 +1,27 @@ +#!/usr/bin/env bash + +# usage: moon_update.sh <GPG_ID> + +COMPONENT=$(basename $(pwd)) +GPG_ID=$1 + +if [ -f setup.py ]; then + echo +else + echo "Not a python package" + exit 1 +fi + +VERSION=${COMPONENT}-$(grep __version__ ${COMPONENT}/__init__.py | cut -d "\"" -f 2) + +python3 setup.py sdist bdist_wheel + +echo $COMPONENT +echo $VERSION + +# Instead of "A0A96E75", use your own GPG ID +rm dist/*.asc 2>/dev/null +gpg --detach-sign -u "${GPG_ID}" -a dist/${VERSION}-py3-none-any.whl +gpg --detach-sign -u "${GPG_ID}" -a dist/${VERSION/_/-}.tar.gz +twine upload dist/${VERSION}-py3-none-any.whl dist/${VERSION}-py3-none-any.whl.asc +twine upload dist/${VERSION/_/-}.tar.gz dist/${VERSION/_/-}.tar.gz.asc diff --git a/tools/moon_kubernetes/README.md b/tools/moon_kubernetes/README.md index a74a1321..73d342fa 100644 --- a/tools/moon_kubernetes/README.md +++ b/tools/moon_kubernetes/README.md @@ -30,8 +30,8 @@ apt-get install -y kubelet kubeadm kubectl ## Moon Deployment ### Initiate K8S ```bash -cd $MOON_HOME/tools/moon_kubernes -sudo bash init_k8s.sh +cd $MOON_HOME +bash tools/moon_kubernetes/init_k8s.sh ``` Wait until all the kubeadm containers are in the `running` state: @@ -56,8 +56,8 @@ You must see something like this: ### Deploy Moon ```bash -cd $MOON_HOME/tools/moon_kubernes -sudo bash start_moon.sh +cd $MOON_HOME +sudo bash tools/moon_kubernetes/start_moon.sh ``` Wait until all the Moon containers are in the `running` state: diff --git a/tools/moon_kubernetes/init_k8s.sh b/tools/moon_kubernetes/init_k8s.sh index fcfdfb5e..8ec1237c 100644 --- a/tools/moon_kubernetes/init_k8s.sh +++ b/tools/moon_kubernetes/init_k8s.sh @@ -20,7 +20,7 @@ kubectl apply -f http://docs.projectcalico.org/v2.4/getting-started/kubernetes/i #kubectl create -f https://raw.githubusercontent.com/kubernetes/dashboard/master/src/deploy/recommended/kubernetes-dashboard.yaml kubectl delete deployment kube-dns --namespace=kube-system -kubectl apply -f templates/kube-dns.yaml +kubectl apply -f tools/moon_kubernetes/templates/kube-dns.yaml kubectl taint nodes --all node-role.kubernetes.io/master- # make the master also as a node diff --git a/tools/moon_kubernetes/start_moon.sh b/tools/moon_kubernetes/start_moon.sh index 3892a3fa..32d9740d 100644 --- a/tools/moon_kubernetes/start_moon.sh +++ b/tools/moon_kubernetes/start_moon.sh @@ -3,21 +3,22 @@ set -x kubectl create namespace moon -kubectl create configmap moon-config --from-file conf/moon.conf -n moon +kubectl create configmap moon-config --from-file tools/moon_kubernetes/conf/moon.conf -n moon kubectl create configmap config --from-file ~/.kube/config -n moon -kubectl create secret generic mysql-root-pass --from-file=conf/password_root.txt -n moon -kubectl create secret generic mysql-pass --from-file=conf/password_moon.txt -n moon +kubectl create configmap moon-policy-templates --from-file tests/functional/scenario_tests -n moon +kubectl create secret generic mysql-root-pass --from-file=tools/moon_kubernetes/conf/password_root.txt -n moon +kubectl create secret generic mysql-pass --from-file=tools/moon_kubernetes/conf/password_moon.txt -n moon -kubectl create -n moon -f templates/consul.yaml -kubectl create -n moon -f templates/db.yaml -kubectl create -n moon -f templates/keystone.yaml +kubectl create -n moon -f tools/moon_kubernetes/templates/consul.yaml +kubectl create -n moon -f tools/moon_kubernetes/templates/db.yaml +kubectl create -n moon -f tools/moon_kubernetes/templates/keystone.yaml echo ========================================= kubectl get pods -n moon echo ========================================= sleep 10 -kubectl create -n moon -f templates/moon_forming.yaml +kubectl create -n moon -f tools/moon_kubernetes/templates/moon_forming.yaml echo Waiting for jobs forming sleep 5 @@ -25,11 +26,13 @@ kubectl get jobs -n moon kubectl logs -n moon jobs/forming sleep 5 -kubectl create -n moon -f templates/moon_manager.yaml +kubectl create -n moon -f tools/moon_kubernetes/templates/moon_manager.yaml sleep 2 -kubectl create -n moon -f templates/moon_orchestrator.yaml +kubectl create -n moon -f tools/moon_kubernetes/templates/moon_orchestrator.yaml -kubectl create -n moon -f templates/moon_gui.yaml +kubectl create -n moon -f tools/moon_kubernetes/templates/moon_gui.yaml +# load moon_wrapper on both master and slaves +# moon_create_wrapper diff --git a/tools/moon_kubernetes/templates/moon_forming.yaml b/tools/moon_kubernetes/templates/moon_forming.yaml index efcc51d8..334ee175 100644 --- a/tools/moon_kubernetes/templates/moon_forming.yaml +++ b/tools/moon_kubernetes/templates/moon_forming.yaml @@ -10,22 +10,21 @@ spec: spec: containers: - name: forming - image: wukongsun/moon_forming:v1.3 + image: wukongsun/moon_forming:latest env: - name: POPULATE_ARGS value: "--verbose" # debug mode: --debug volumeMounts: - name: config-volume mountPath: /etc/moon - - name: test-volume + - name: templates-volume mountPath: /data volumes: - name: config-volume configMap: name: moon-config - - name: test-volume - hostPath: - path: tests/functional/scenario_enabled - type: Directory + - name: templates-volume + configMap: + name: moon-policy-templates restartPolicy: Never #backoffLimit: 4
\ No newline at end of file |