aboutsummaryrefslogtreecommitdiffstats
path: root/moon_engine/moon_engine/api
diff options
context:
space:
mode:
Diffstat (limited to 'moon_engine/moon_engine/api')
-rw-r--r--moon_engine/moon_engine/api/__init__.py29
-rw-r--r--moon_engine/moon_engine/api/authz/__init__.py12
-rw-r--r--moon_engine/moon_engine/api/authz/authz.py28
-rw-r--r--moon_engine/moon_engine/api/authz/managers.py20
-rw-r--r--moon_engine/moon_engine/api/configuration.py195
-rw-r--r--moon_engine/moon_engine/api/import_json.py29
-rw-r--r--moon_engine/moon_engine/api/logs.py25
-rw-r--r--moon_engine/moon_engine/api/orchestration/__init__.py12
-rw-r--r--moon_engine/moon_engine/api/orchestration/managers.py21
-rw-r--r--moon_engine/moon_engine/api/orchestration/pipeline.py51
-rw-r--r--moon_engine/moon_engine/api/orchestration/slave.py44
-rw-r--r--moon_engine/moon_engine/api/pipeline/__init__.py11
-rw-r--r--moon_engine/moon_engine/api/pipeline/authz.py35
-rw-r--r--moon_engine/moon_engine/api/pipeline/update.py188
-rw-r--r--moon_engine/moon_engine/api/pipeline/update_pipeline.py220
-rw-r--r--moon_engine/moon_engine/api/pipeline/validator.py125
-rw-r--r--moon_engine/moon_engine/api/status.py30
-rw-r--r--moon_engine/moon_engine/api/wrapper/__init__.py11
-rw-r--r--moon_engine/moon_engine/api/wrapper/api/__init__.py11
-rw-r--r--moon_engine/moon_engine/api/wrapper/api/authz.py43
-rw-r--r--moon_engine/moon_engine/api/wrapper/api/pipeline.py100
-rw-r--r--moon_engine/moon_engine/api/wrapper/api/update.py179
-rw-r--r--moon_engine/moon_engine/api/wrapper/router.py115
-rw-r--r--moon_engine/moon_engine/api/wrapper/update_wrapper.py233
24 files changed, 1767 insertions, 0 deletions
diff --git a/moon_engine/moon_engine/api/__init__.py b/moon_engine/moon_engine/api/__init__.py
new file mode 100644
index 00000000..deafe11b
--- /dev/null
+++ b/moon_engine/moon_engine/api/__init__.py
@@ -0,0 +1,29 @@
+# Software Name: MOON
+
+# Version: 5.4
+
+# SPDX-FileCopyrightText: Copyright (c) 2018-2020 Orange and its contributors
+# SPDX-License-Identifier: Apache-2.0
+
+# This software is distributed under the 'Apache License 2.0',
+# the text of which is available at 'http://www.apache.org/licenses/LICENSE-2.0.txt'
+# or see the "LICENSE" file for more details.
+
+
+
+from falcon import HTTP_400, HTTP_401, HTTP_402, HTTP_403, HTTP_404, HTTP_405, \
+ HTTP_406, HTTP_407, HTTP_408, HTTP_409, HTTP_500
+
+ERROR_CODE = {
+ 400: HTTP_400,
+ 401: HTTP_401,
+ 402: HTTP_402,
+ 403: HTTP_403,
+ 404: HTTP_404,
+ 405: HTTP_405,
+ 406: HTTP_406,
+ 407: HTTP_407,
+ 408: HTTP_408,
+ 409: HTTP_409,
+ 500: HTTP_500
+}
diff --git a/moon_engine/moon_engine/api/authz/__init__.py b/moon_engine/moon_engine/api/authz/__init__.py
new file mode 100644
index 00000000..1856aa2c
--- /dev/null
+++ b/moon_engine/moon_engine/api/authz/__init__.py
@@ -0,0 +1,12 @@
+# Software Name: MOON
+
+# Version: 5.4
+
+# SPDX-FileCopyrightText: Copyright (c) 2018-2020 Orange and its contributors
+# SPDX-License-Identifier: Apache-2.0
+
+# This software is distributed under the 'Apache License 2.0',
+# the text of which is available at 'http://www.apache.org/licenses/LICENSE-2.0.txt'
+# or see the "LICENSE" file for more details.
+
+
diff --git a/moon_engine/moon_engine/api/authz/authz.py b/moon_engine/moon_engine/api/authz/authz.py
new file mode 100644
index 00000000..caf95f93
--- /dev/null
+++ b/moon_engine/moon_engine/api/authz/authz.py
@@ -0,0 +1,28 @@
+# Software Name: MOON
+
+# Version: 5.4
+
+# SPDX-FileCopyrightText: Copyright (c) 2018-2020 Orange and its contributors
+# SPDX-License-Identifier: Apache-2.0
+
+# This software is distributed under the 'Apache License 2.0',
+# the text of which is available at 'http://www.apache.org/licenses/LICENSE-2.0.txt'
+# or see the "LICENSE" file for more details.
+
+
+import logging
+from moon_engine.api.authz.managers import Managers
+
+logger = logging.getLogger("moon.engine.api.authz.pipeline")
+
+
+class AuthzManager(Managers):
+
+ def __init__(self, connector=None):
+ self.driver = connector.driver
+ Managers.AuthzManager = self
+
+ def get_authz(self, subject_name, object_name, action_name):
+ return self.driver.get_authz(subject_name=subject_name,
+ object_name=object_name,
+ action_name=action_name)
diff --git a/moon_engine/moon_engine/api/authz/managers.py b/moon_engine/moon_engine/api/authz/managers.py
new file mode 100644
index 00000000..dedb148d
--- /dev/null
+++ b/moon_engine/moon_engine/api/authz/managers.py
@@ -0,0 +1,20 @@
+# Software Name: MOON
+
+# Version: 5.4
+
+# SPDX-FileCopyrightText: Copyright (c) 2018-2020 Orange and its contributors
+# SPDX-License-Identifier: Apache-2.0
+
+# This software is distributed under the 'Apache License 2.0',
+# the text of which is available at 'http://www.apache.org/licenses/LICENSE-2.0.txt'
+# or see the "LICENSE" file for more details.
+
+
+import logging
+
+logger = logging.getLogger("moon.engine.api.authz.managers")
+
+
+class Managers(object):
+ """Object that links managers together"""
+ AuthzManager = None
diff --git a/moon_engine/moon_engine/api/configuration.py b/moon_engine/moon_engine/api/configuration.py
new file mode 100644
index 00000000..398497a1
--- /dev/null
+++ b/moon_engine/moon_engine/api/configuration.py
@@ -0,0 +1,195 @@
+# Software Name: MOON
+
+# Version: 5.4
+
+# SPDX-FileCopyrightText: Copyright (c) 2018-2020 Orange and its contributors
+# SPDX-License-Identifier: Apache-2.0
+
+# This software is distributed under the 'Apache License 2.0',
+# the text of which is available at 'http://www.apache.org/licenses/LICENSE-2.0.txt'
+# or see the "LICENSE" file for more details.
+
+
+"""Configuration API"""
+import hug.interface
+import os
+import logging
+import logging.config
+import yaml
+import copy
+from importlib.machinery import SourceFileLoader
+
+LOGGER = logging.getLogger("moon.engine.api.configuration")
+__CONF = {}
+CONF_FILE = ""
+
+
+def init_logging(log_file=None):
+ """Initialize the logging system
+
+ :return: nothing
+ """
+ logging_conf = get_configuration(key='logging', file=log_file)
+ if get_configuration(key='debug', default=False):
+ logging_conf.get("handlers", {}).get("console", {})['level'] = logging.DEBUG
+ LOGGER.warning("Setting debug to True!")
+ logging.config.dictConfig(logging_conf)
+
+
+def get_plugins_by_type(plugin_type):
+ """
+
+ :param plugin_type:
+ :return:
+ """
+ plugins_dir = __CONF["plugins"]["directory"]
+ LOGGER.info("Getting all plugins for {}".format(plugin_type))
+ import moon_engine.plugins
+ import glob
+ for plugname in glob.glob(os.path.join(moon_engine.plugins.__path__[0], "*.py")):
+ try:
+ plugname = os.path.basename(plugname)[:-3]
+ plug = __import__("moon_engine.plugins.{}".format(plugname), fromlist=["plugins", ])
+ if getattr(plug, "PLUGIN_TYPE", "") == plugin_type:
+ yield plug
+ LOGGER.debug("Plug {} loaded".format(plugname))
+ except ModuleNotFoundError:
+ pass
+ for plugname in glob.glob(os.path.join(plugins_dir, "*.py")):
+ m = SourceFileLoader("myplugs", os.path.join(plugins_dir, plugname+".py"))
+ plug = m.load_module()
+ if getattr(plug, "PLUGIN_TYPE", "") == plugin_type:
+ yield plug
+ LOGGER.debug("Plug {} loaded".format(plugname))
+
+
+def load_plugin(plugname):
+ """Load a python module
+
+ :param plugname: the name of the module to load
+ :return: a reference to the module
+ """
+ plugins_dir = __CONF["plugins"]["directory"]
+ LOGGER.info(f"load_plugin {plugname}")
+ try:
+ return __import__(plugname, fromlist=["plugins", ])
+ except ImportError as e:
+ LOGGER.warning("Cannot import module ({})".format(e))
+ try:
+ m = SourceFileLoader("myplugs", os.path.join(plugins_dir, plugname+".py"))
+ return m.load_module()
+ except ImportError as e:
+ LOGGER.error("Error in importing plugin {} from {}".format(plugname, plugins_dir))
+ LOGGER.exception(e)
+
+
+def get_authz_driver():
+ """Load and check the plugin module
+
+ :return: a reference to the module
+ """
+ plug = load_plugin(__CONF["authorization"]["driver"])
+ if plug.PLUGIN_TYPE != "authz":
+ raise Exception("Trying to load a bad Authz plugin (got {} plugin instead)".format(
+ plug.PLUGIN_TYPE))
+ if "Connector" not in dir(plug):
+ raise Exception("Trying to load a bad Authz plugin (cannot find Connector)")
+ return plug
+
+
+def get_orchestration_driver():
+ """Load and check the plugin module
+
+ :return: a reference to the module
+ """
+ plug = load_plugin(__CONF["orchestration"]["driver"])
+ if plug.PLUGIN_TYPE != "orchestration":
+ raise Exception("Trying to load a bad Orchestration plugin (got {} plugin instead)".format(
+ plug.PLUGIN_TYPE))
+ if "Connector" not in dir(plug):
+ raise Exception("Trying to load a bad Orchestration plugin (cannot find Connector)")
+ return plug
+
+
+def get_pipeline_driver():
+ """Load and check the plugin module
+
+ :return: a reference to the module
+ """
+ plug = load_plugin(__CONF["information"]["driver"])
+ if plug.PLUGIN_TYPE != "information":
+ raise Exception("Trying to load a bad Information plugin (got {} plugin instead)".format(
+ plug.PLUGIN_TYPE))
+ if "Connector" not in dir(plug):
+ raise Exception("Trying to load a bad Information plugin (cannot find Connector)")
+ return plug
+
+
+def search_config_file(filename):
+ """Look for the configuration file
+
+ :param filename: a filename to search for
+ :return: the content of the configuration file
+ """
+ data_config = None
+ for _filename in (filename, "moon.conf", "moon.yaml"):
+ for _dir in (
+ "{}",
+ "/conf/{}",
+ "../{}",
+ "../conf/{}",
+ "/etc/moon/{}",
+ "conf/{}",
+ ):
+ _file = _dir.format(_filename)
+ try:
+ data_config = yaml.safe_load(open(_file))
+ except FileNotFoundError:
+ data_config = None
+ continue
+ else:
+ LOGGER.warning("Configuration file: {}".format(_file))
+ break
+ if data_config:
+ break
+ if not data_config:
+ LOGGER.error("Configuration file not found ({})...".format(filename))
+ raise Exception("Configuration file not found ({})...".format(filename))
+ return data_config
+
+
+def set_configuration(conf):
+ """ Force the configuration dictionary
+
+ :param conf: the configuration dictionary
+ :return: nothing
+ """
+ global __CONF
+ __CONF = conf
+
+
+def reload_configuration():
+ global __CONF, CONF_FILE
+ __CONF = None
+ set_configuration(search_config_file(CONF_FILE))
+
+
+@hug.cli("get_conf")
+@hug.local()
+def get_configuration(key=None, default=None, file=None):
+ """
+ List configuration attributes
+ :return: JSON configuration value
+ """
+ global __CONF
+ if not __CONF:
+ if file:
+ __CONF = search_config_file(file)
+ else:
+ __CONF = search_config_file("moon.yaml")
+ init_logging()
+ if not key:
+ # TODO: delete passwords!
+ return copy.deepcopy(__CONF)
+ else:
+ return copy.deepcopy(__CONF.get(key, default))
diff --git a/moon_engine/moon_engine/api/import_json.py b/moon_engine/moon_engine/api/import_json.py
new file mode 100644
index 00000000..d1296ff1
--- /dev/null
+++ b/moon_engine/moon_engine/api/import_json.py
@@ -0,0 +1,29 @@
+# Software Name: MOON
+
+# Version: 5.4
+
+# SPDX-FileCopyrightText: Copyright (c) 2018-2020 Orange and its contributors
+# SPDX-License-Identifier: Apache-2.0
+
+# This software is distributed under the 'Apache License 2.0',
+# the text of which is available at 'http://www.apache.org/licenses/LICENSE-2.0.txt'
+# or see the "LICENSE" file for more details.
+
+
+"""Import JSON API"""
+import hug
+
+
+@hug.local()
+@hug.post("/import/")
+def import_json(body):
+ """Import data into the cache of the pipeline
+
+ :return: OK if imported
+ """
+ if "attributes" in body:
+ description = "Will update " + ", ".join(body.get("attributes"))
+ else:
+ description = "Will update all attributes"
+ # FIXME: dev the real import functionality
+ return {"status": "OK", "description": description}
diff --git a/moon_engine/moon_engine/api/logs.py b/moon_engine/moon_engine/api/logs.py
new file mode 100644
index 00000000..b6269648
--- /dev/null
+++ b/moon_engine/moon_engine/api/logs.py
@@ -0,0 +1,25 @@
+# Software Name: MOON
+
+# Version: 5.4
+
+# SPDX-FileCopyrightText: Copyright (c) 2018-2020 Orange and its contributors
+# SPDX-License-Identifier: Apache-2.0
+
+# This software is distributed under the 'Apache License 2.0',
+# the text of which is available at 'http://www.apache.org/licenses/LICENSE-2.0.txt'
+# or see the "LICENSE" file for more details.
+
+
+"""Test hug API (local, command-line, and HTTP access)"""
+import hug
+
+
+@hug.local()
+@hug.get("/logs/")
+def list_logs():
+ """List logs
+
+ :return: JSON status output
+ """
+
+ return {"logs": []}
diff --git a/moon_engine/moon_engine/api/orchestration/__init__.py b/moon_engine/moon_engine/api/orchestration/__init__.py
new file mode 100644
index 00000000..1856aa2c
--- /dev/null
+++ b/moon_engine/moon_engine/api/orchestration/__init__.py
@@ -0,0 +1,12 @@
+# Software Name: MOON
+
+# Version: 5.4
+
+# SPDX-FileCopyrightText: Copyright (c) 2018-2020 Orange and its contributors
+# SPDX-License-Identifier: Apache-2.0
+
+# This software is distributed under the 'Apache License 2.0',
+# the text of which is available at 'http://www.apache.org/licenses/LICENSE-2.0.txt'
+# or see the "LICENSE" file for more details.
+
+
diff --git a/moon_engine/moon_engine/api/orchestration/managers.py b/moon_engine/moon_engine/api/orchestration/managers.py
new file mode 100644
index 00000000..e07851c5
--- /dev/null
+++ b/moon_engine/moon_engine/api/orchestration/managers.py
@@ -0,0 +1,21 @@
+# Software Name: MOON
+
+# Version: 5.4
+
+# SPDX-FileCopyrightText: Copyright (c) 2018-2020 Orange and its contributors
+# SPDX-License-Identifier: Apache-2.0
+
+# This software is distributed under the 'Apache License 2.0',
+# the text of which is available at 'http://www.apache.org/licenses/LICENSE-2.0.txt'
+# or see the "LICENSE" file for more details.
+
+
+import logging
+
+logger = logging.getLogger("moon.engine.api.orchestration.managers")
+
+
+class Managers(object):
+ """Object that links managers together"""
+ SlaveManager = None
+ PipelineManager = None
diff --git a/moon_engine/moon_engine/api/orchestration/pipeline.py b/moon_engine/moon_engine/api/orchestration/pipeline.py
new file mode 100644
index 00000000..47a84409
--- /dev/null
+++ b/moon_engine/moon_engine/api/orchestration/pipeline.py
@@ -0,0 +1,51 @@
+# Software Name: MOON
+
+# Version: 5.4
+
+# SPDX-FileCopyrightText: Copyright (c) 2018-2020 Orange and its contributors
+# SPDX-License-Identifier: Apache-2.0
+
+# This software is distributed under the 'Apache License 2.0',
+# the text of which is available at 'http://www.apache.org/licenses/LICENSE-2.0.txt'
+# or see the "LICENSE" file for more details.
+
+
+from uuid import uuid4
+import logging
+from moon_utilities.security_functions import enforce
+from moon_engine.api.orchestration.managers import Managers
+
+logger = logging.getLogger("moon.engine.api.orchestration.pipeline")
+
+
+class PipelineManager(Managers):
+
+ def __init__(self, connector=None):
+ self.driver = connector.driver
+ Managers.PipelineManager = self
+
+ @enforce(("read", "write"), "pipelines")
+ def update_pipeline(self, moon_user_id, pipeline_id, data):
+ return self.driver.update_pipeline(pipeline_id=pipeline_id, data=data)
+
+ @enforce("write", "pipelines")
+ def delete_pipeline(self, moon_user_id, pipeline_id):
+ return self.driver.delete_pipeline(pipeline_id=pipeline_id)
+
+ @enforce("write", "pipelines")
+ def add_pipeline(self, moon_user_id, pipeline_id=None, data=None):
+ if not pipeline_id:
+ pipeline_id = uuid4().hex
+ if data is None:
+ data = {}
+ if "plugins" not in data:
+ data["plugins"] = ["moon_engine.plugins.authz"]
+ return self.driver.add_pipeline(pipeline_id=pipeline_id, data=data)
+
+ @enforce("read", "pipelines")
+ def get_pipelines(self, moon_user_id, pipeline_id=None):
+ return self.driver.get_pipelines(pipeline_id=pipeline_id)
+
+ @enforce("read", "pipelines")
+ def get_pipeline_api_key(self, moon_user_id, pipeline_id):
+ return self.driver.get_pipeline_api_key(pipeline_id=pipeline_id)
diff --git a/moon_engine/moon_engine/api/orchestration/slave.py b/moon_engine/moon_engine/api/orchestration/slave.py
new file mode 100644
index 00000000..fa4412ba
--- /dev/null
+++ b/moon_engine/moon_engine/api/orchestration/slave.py
@@ -0,0 +1,44 @@
+# Software Name: MOON
+
+# Version: 5.4
+
+# SPDX-FileCopyrightText: Copyright (c) 2018-2020 Orange and its contributors
+# SPDX-License-Identifier: Apache-2.0
+
+# This software is distributed under the 'Apache License 2.0',
+# the text of which is available at 'http://www.apache.org/licenses/LICENSE-2.0.txt'
+# or see the "LICENSE" file for more details.
+
+
+from uuid import uuid4
+import logging
+from moon_utilities import exceptions
+from moon_utilities.security_functions import enforce
+from moon_engine.api.orchestration.managers import Managers
+
+logger = logging.getLogger("moon.manager.api.orchestration.pod")
+
+
+class SlaveManager(Managers):
+
+ def __init__(self, connector=None):
+ self.driver = connector.driver
+ Managers.SlaveManager = self
+
+ @enforce(("read", "write"), "slaves")
+ def update_slave(self, user_id, slave_id, value):
+ self.driver.update_slave(slave_id=slave_id, value=value)
+
+ @enforce("write", "slaves")
+ def delete_slave(self, user_id, slave_id):
+ self.driver.delete_slave(slave_id=slave_id)
+
+ @enforce("write", "slaves")
+ def add_slave(self, user_id, slave_id=None, data=None):
+ if not slave_id:
+ slave_id = uuid4().hex
+ self.driver.add_slave(slave_id=slave_id, data=data)
+
+ @enforce("read", "slaves")
+ def get_slaves(self, user_id, slave_id=None):
+ self.driver.get_slaves(slave_id=slave_id)
diff --git a/moon_engine/moon_engine/api/pipeline/__init__.py b/moon_engine/moon_engine/api/pipeline/__init__.py
new file mode 100644
index 00000000..582be686
--- /dev/null
+++ b/moon_engine/moon_engine/api/pipeline/__init__.py
@@ -0,0 +1,11 @@
+# Software Name: MOON
+
+# Version: 5.4
+
+# SPDX-FileCopyrightText: Copyright (c) 2018-2020 Orange and its contributors
+# SPDX-License-Identifier: Apache-2.0
+
+# This software is distributed under the 'Apache License 2.0',
+# the text of which is available at 'http://www.apache.org/licenses/LICENSE-2.0.txt'
+# or see the "LICENSE" file for more details.
+
diff --git a/moon_engine/moon_engine/api/pipeline/authz.py b/moon_engine/moon_engine/api/pipeline/authz.py
new file mode 100644
index 00000000..02fb7d30
--- /dev/null
+++ b/moon_engine/moon_engine/api/pipeline/authz.py
@@ -0,0 +1,35 @@
+# Software Name: MOON
+
+# Version: 5.4
+
+# SPDX-FileCopyrightText: Copyright (c) 2018-2020 Orange and its contributors
+# SPDX-License-Identifier: Apache-2.0
+
+# This software is distributed under the 'Apache License 2.0',
+# the text of which is available at 'http://www.apache.org/licenses/LICENSE-2.0.txt'
+# or see the "LICENSE" file for more details.
+
+
+import hug
+from moon_engine.api.pipeline.validator import Validator
+
+
+class Authz(object):
+
+ @staticmethod
+ @hug.local()
+ @hug.get("/authz/{subject_name}/{object_name}/{action_name}")
+ def get(subject_name: hug.types.text, object_name: hug.types.text,
+ action_name: hug.types.text, response):
+ """Get a response on Main Authorization request
+
+ :param subject_name: name of the subject or the request
+ :param object_name: name of the object
+ :param action_name: name of the action
+ :return:
+ "result": {true or false }
+ :internal_api: authz
+ """
+
+ validator = Validator()
+ response.status = validator.authz(subject_name, object_name, action_name)
diff --git a/moon_engine/moon_engine/api/pipeline/update.py b/moon_engine/moon_engine/api/pipeline/update.py
new file mode 100644
index 00000000..deaf9c12
--- /dev/null
+++ b/moon_engine/moon_engine/api/pipeline/update.py
@@ -0,0 +1,188 @@
+# Software Name: MOON
+
+# Version: 5.4
+
+# SPDX-FileCopyrightText: Copyright (c) 2018-2020 Orange and its contributors
+# SPDX-License-Identifier: Apache-2.0
+
+# This software is distributed under the 'Apache License 2.0',
+# the text of which is available at 'http://www.apache.org/licenses/LICENSE-2.0.txt'
+# or see the "LICENSE" file for more details.
+
+
+"""Update API"""
+import hug
+from moon_utilities.auth_functions import api_key_authentication
+from moon_engine.api.pipeline.update_pipeline import Update
+
+
+class PipelineUpdate(object):
+
+ @staticmethod
+ @hug.local()
+ @hug.put("/update/slave/{slave_id}", requires=api_key_authentication)
+ def update_slave(body, slave_id: hug.types.uuid, response):
+ """Tell the moon_engine wrapper that its cache should be updated
+ body may contain the attributes that the moon_engine should get from the manager
+ body example:
+ {
+ "name": "...",
+ "description": "..."
+ }
+ :return: 202 status code
+ """
+ update_pipeline = Update()
+ response.status = update_pipeline.update_slaves(slave_id=str(slave_id).replace("-", ""), is_delete=False,
+ data=body)
+
+ @staticmethod
+ @hug.local()
+ @hug.put("/update/pdp/{pdp_id}", requires=api_key_authentication)
+ def update_pdp(body, pdp_id: hug.types.uuid, response):
+ """Tell the moon_engine wrapper that its cache should be updated
+ body may contain the attributes that the moon_engine should get from the manager
+ if the attributes key is empty, all data should be retrieved
+ body example:
+ {
+ "vim_project_id": "...",
+ "security_pipeline": ["policy_id1", "policy_id2"],
+ "attributes": ["subjects", "subject_assignments", "subject_categories"]
+ }
+ :return: 202 status code
+ """
+
+ # todo call wrapper to update its pdp at the cache
+ update_pipeline = Update()
+ response.status = update_pipeline.update_pdp(is_delete=False, pdp_id=str(pdp_id).replace("-", ""), data=body)
+
+ @staticmethod
+ @hug.local()
+ @hug.delete("/update/pdp/{pdp_id}", requires=api_key_authentication)
+ def delete_pdp(pdp_id: hug.types.uuid, response):
+ """Tell the moon_engine wrapper that its cache should be updated
+ body may contain the attributes that the moon_engine should get from the manager
+ if the attributes key is empty, all data should be retrieved
+ body example:
+ {
+ "vim_project_id": "...",
+ "security_pipeline": ["policy_id1", "policy_id2"],
+ "attributes": ["subjects", "subject_assignments", "subject_categories"]
+ }
+ :return: 202 status code
+ """
+
+ # todo call wrapper to update its pdp at the cache
+ update_pipeline = Update()
+ response.status = update_pipeline.update_pdp(is_delete=True, pdp_id=str(pdp_id).replace("-", ""))
+
+ @staticmethod
+ @hug.local()
+ @hug.put("/update/policy/{policy_id}", requires=api_key_authentication)
+ def update_policy(body, policy_id: hug.types.uuid, response):
+ update_pipeline = Update()
+ response.status = update_pipeline.update_policy(is_delete=False, policy_id=str(policy_id).replace("-", ""),
+ data=body)
+
+ @staticmethod
+ @hug.local()
+ @hug.delete("/update/policy/{policy_id}", requires=api_key_authentication)
+ def delete_policy(policy_id: hug.types.uuid, response):
+ update_pipeline = Update()
+ response.status = update_pipeline.update_policy(is_delete=True, policy_id=str(policy_id).replace("-", ""))
+
+ @staticmethod
+ @hug.local()
+ @hug.delete("/update/assignment/{policy_id}/{type}/", requires=api_key_authentication)
+ @hug.delete("/update/assignment/{policy_id}/{type}/{perimeter_id}",
+ requires=api_key_authentication)
+ @hug.delete("/update/assignment/{policy_id}/{type}/{perimeter_id}/{category_id}",
+ requires=api_key_authentication)
+ @hug.delete("/update/assignment/{policy_id}/{type}/{perimeter_id}/{category_id}/{data_id}",
+ requires=api_key_authentication)
+ def delete_assignment(response, policy_id: hug.types.uuid, type: hug.types.text,
+ perimeter_id: hug.types.uuid = None, category_id: hug.types.uuid = None,
+ data_id: hug.types.uuid = None, authed_user: hug.directives.user=None):
+ update_pipeline = Update()
+ response.status = update_pipeline.delete_assignment(type=type, policy_id=str(policy_id).replace("-", ""),
+ perimeter_id=str(perimeter_id).replace("-", ""),
+ category_id=str(category_id).replace("-", ""),
+ data_id=data_id)
+
+ @staticmethod
+ @hug.local()
+ @hug.put("/update/perimeter/{perimeter_id}/{policy_id}/{type}", requires=api_key_authentication)
+ def update_perimeter(body, perimeter_id: hug.types.uuid, policy_id: hug.types.uuid,
+ type: hug.types.text, response):
+ update_pipeline = Update()
+ response.status = update_pipeline.update_perimeter(is_delete=False, type=type,
+ perimeter_id=str(perimeter_id).replace("-", ""), data=body,
+ policy_id=str(policy_id).replace("-", ""))
+
+ @staticmethod
+ @hug.local()
+ @hug.delete("/update/perimeter/{perimeter_id}/{policy_id}/{type}", requires=api_key_authentication)
+ def delete_perimeter(perimeter_id: hug.types.uuid, policy_id: hug.types.uuid,
+ type: hug.types.text, response):
+ update_pipeline = Update()
+ response.status = update_pipeline.update_perimeter(is_delete=True, type=type,
+ perimeter_id=str(perimeter_id).replace("-", ""),
+ policy_id=str(policy_id).replace("-", ""))
+
+ @staticmethod
+ @hug.local()
+ @hug.delete("/update/rule/{policy_id}/{rule_id}", requires=api_key_authentication)
+ def delete_rule(policy_id: hug.types.uuid, rule_id: hug.types.uuid, response):
+ update_pipeline = Update()
+ response.status = update_pipeline.delete_rule(rule_id=str(rule_id).replace("-", ""), policy_id=str(policy_id).replace("-", ""))
+
+ @staticmethod
+ @hug.local()
+ @hug.put("/update/model/{model_id}", requires=api_key_authentication)
+ def update_model(body, model_id: hug.types.uuid, response):
+ update_pipeline = Update()
+ response.status = update_pipeline.update_model(model_id=str(model_id).replace("-", ""), is_delete=False,
+ data=body)
+
+ @staticmethod
+ @hug.local()
+ @hug.delete("/update/model/{model_id}", requires=api_key_authentication)
+ def delete_model(model_id: hug.types.uuid, response):
+ update_pipeline = Update()
+ response.status = update_pipeline.update_model(model_id=str(model_id).replace("-", ""), is_delete=True)
+
+ @staticmethod
+ @hug.local()
+ @hug.delete("/update/meta_data/{category_id}/{type}", requires=api_key_authentication)
+ def delete_category(category_id: hug.types.uuid, type: hug.types.text, response):
+ update_pipeline = Update()
+ response.status = update_pipeline.delete_category(category_id=str(category_id).replace("-", ""), type=type)
+
+ @staticmethod
+ @hug.local()
+ @hug.put("/update/meta_rule/{meta_rule_id}", requires=api_key_authentication)
+ def update_meta_rule(body, meta_rule_id: hug.types.uuid, response):
+ update_pipeline = Update()
+ response.status = update_pipeline.update_meta_rule(is_delete=False,
+ meta_rule_id=str(meta_rule_id).replace("-", ""), data=body)
+
+ @staticmethod
+ @hug.local()
+ @hug.delete("/update/meta_rule/{meta_rule_id}", requires=api_key_authentication)
+ def delete_meta_rule(meta_rule_id: hug.types.uuid, response):
+ update_pipeline = Update()
+ response.status = update_pipeline.update_meta_rule(is_delete=True,
+ meta_rule_id=str(meta_rule_id).replace("-", ""))
+
+ @staticmethod
+ @hug.local()
+ @hug.delete("/update/data/{data_id}/{type}", requires=api_key_authentication)
+ def delete_data(data_id: hug.types.uuid, type: hug.types.text, response):
+ update_pipeline = Update()
+ response.status = update_pipeline.delete_data(data_id=str(data_id).replace("-", ""), type=type)
+
+ @staticmethod
+ @hug.local()
+ @hug.delete("/update/attributes/{name}", requires=api_key_authentication)
+ def delete_data(name: hug.types.text, response):
+ update_pipeline = Update()
+ response.status = update_pipeline.delete_attributes(name=name)
diff --git a/moon_engine/moon_engine/api/pipeline/update_pipeline.py b/moon_engine/moon_engine/api/pipeline/update_pipeline.py
new file mode 100644
index 00000000..3b312efb
--- /dev/null
+++ b/moon_engine/moon_engine/api/pipeline/update_pipeline.py
@@ -0,0 +1,220 @@
+# Software Name: MOON
+
+# Version: 5.4
+
+# SPDX-FileCopyrightText: Copyright (c) 2018-2020 Orange and its contributors
+# SPDX-License-Identifier: Apache-2.0
+
+# This software is distributed under the 'Apache License 2.0',
+# the text of which is available at 'http://www.apache.org/licenses/LICENSE-2.0.txt'
+# or see the "LICENSE" file for more details.
+
+
+import hug
+from moon_cache.cache import Cache
+from moon_engine.api.configuration import get_configuration
+import logging
+
+logger = logging.getLogger("moon.engine.api.pipeline.update_pipeline")
+
+
+class Update(object):
+ __CACHE = None
+
+ def __init__(self):
+ if not self.__CACHE:
+ self.__CACHE = Cache.getInstance(manager_url=get_configuration("manager_url"),
+ incremental=get_configuration("incremental_updates"),
+ manager_api_key=get_configuration("api_token"))
+
+ def update_policy(self, is_delete, policy_id, data=None):
+
+ policies = self.__CACHE.policies
+ if is_delete:
+ if policy_id in policies:
+ del policies[policy_id]
+ else:
+ if policy_id in policies:
+ policies[policy_id] = data
+ else:
+ return hug.HTTP_208
+ return hug.HTTP_202
+
+ def update_pdp(self, is_delete, pdp_id, data=None):
+
+ pdps = self.__CACHE.pdp
+ if is_delete:
+ if pdp_id in pdps:
+ del pdps[pdp_id]
+ else:
+ if pdp_id in pdps:
+ pdps[pdp_id] = data
+ else:
+ return hug.HTTP_208
+ return hug.HTTP_202
+
+ def delete_assignment(self, type, policy_id, perimeter_id=None, category_id=None, data_id=None):
+
+ if type == "subject":
+ assignments = self.__CACHE.subject_assignments
+ if policy_id in assignments:
+ for key in assignments[policy_id]:
+ if (perimeter_id is None or assignments[policy_id][key]['subject_id'] ==
+ perimeter_id) and (
+ category_id is None or assignments[policy_id][key]['category_id'] == category_id):
+ if data_id is None or data_id in assignments[policy_id][key]['assignments']:
+ assignments[policy_id][key]['assignments'].remove(data_id)
+ if len(assignments[policy_id][key]['assignments']) == 0:
+ del assignments[policy_id][key];
+ else:
+ del assignments[policy_id][key]
+ break
+
+ elif type == "object":
+ assignments = self.__CACHE.object_assignments
+ if policy_id in assignments:
+ for key in assignments[policy_id]:
+ if (perimeter_id is None or assignments[policy_id][key]['object_id'] ==
+ perimeter_id) and (
+ category_id is None or assignments[policy_id][key]['category_id'] == category_id):
+ if data_id is None or data_id in assignments[policy_id][key]['assignments']:
+ assignments[policy_id][key]['assignments'].remove(data_id)
+ if len(assignments[policy_id][key]['assignments']) == 0:
+ del assignments[policy_id][key];
+ else:
+ del assignments[policy_id][key]
+ break
+ else:
+ assignments = self.__CACHE.action_assignments
+ if policy_id in assignments:
+ for key in assignments[policy_id]:
+ if (perimeter_id is None or assignments[policy_id][key]['action_id'] ==
+ perimeter_id) and (
+ category_id is None or assignments[policy_id][key]['category_id'] == category_id):
+ if data_id is None or data_id in assignments[policy_id][key]['assignments']:
+ assignments[policy_id][key]['assignments'].remove(data_id)
+ if len(assignments[policy_id][key]['assignments']) == 0:
+ del assignments[policy_id][key];
+ else:
+ del assignments[policy_id][key]
+ break
+ return hug.HTTP_202
+
+ def update_perimeter(self, is_delete, type, perimeter_id, data=None, policy_id=None):
+
+ if is_delete:
+ if type == "subject":
+ perimeters = self.__CACHE.subjects
+ if policy_id in perimeters and perimeter_id in perimeters[policy_id] and \
+ policy_id in perimeters[policy_id][perimeter_id]['policy_list']:
+ del perimeters[policy_id][perimeter_id]
+ elif type == "object":
+ perimeters = self.__CACHE.objects
+ if policy_id in perimeters and perimeter_id in perimeters[policy_id] and \
+ policy_id in perimeters[policy_id][perimeter_id]['policy_list']:
+ del perimeters[policy_id][perimeter_id]
+ else:
+ perimeters = self.__CACHE.actions
+ if policy_id in perimeters and perimeter_id in perimeters[policy_id] and \
+ policy_id in perimeters[policy_id][perimeter_id]['policy_list']:
+ del perimeters[policy_id][perimeter_id]
+ else:
+ if type == "subject":
+ perimeters = self.__CACHE.subjects
+ if policy_id in perimeters and perimeter_id in perimeters[policy_id] and \
+ policy_id in perimeters[policy_id][perimeter_id]['policy_list']:
+ perimeters[policy_id][perimeter_id]['name'] = data['name']
+ perimeters[policy_id][perimeter_id]['description'] = data['description']
+ else:
+ return hug.HTTP_208
+ elif type == "object":
+ perimeters = self.__CACHE.objects
+ if policy_id in perimeters and perimeter_id in perimeters[policy_id] and \
+ policy_id in perimeters[policy_id][perimeter_id]['policy_list']:
+ perimeters[policy_id][perimeter_id]['name'] = data['name']
+ perimeters[policy_id][perimeter_id]['description'] = data['description']
+ else:
+ return hug.HTTP_208
+ else:
+ perimeters = self.__CACHE.actions
+ if policy_id in perimeters and perimeter_id in perimeters[policy_id] and \
+ policy_id in perimeters[policy_id][perimeter_id]['policy_list']:
+ perimeters[policy_id][perimeter_id]['name'] = data['name']
+ perimeters[policy_id][perimeter_id]['description'] = data['description']
+ else:
+ return hug.HTTP_208
+ return hug.HTTP_202
+
+ def delete_rule(self, rule_id, policy_id):
+
+ rules = self.__CACHE.rules
+ if policy_id in rules and rule_id in rules[policy_id]:
+ del rules[policy_id][rule_id]
+ return hug.HTTP_202
+
+ def update_model(self, model_id, is_delete, data=None):
+ if is_delete:
+ models = self.__CACHE.models
+ if model_id in models:
+ del models[model_id]
+ else:
+ models = self.__CACHE.models
+ if model_id in models:
+ models[model_id] = data
+ else:
+ return hug.HTTP_208
+ return hug.HTTP_202
+
+ def delete_category(self, category_id, type):
+
+ if type == "subject":
+ categories = self.__CACHE.subject_categories
+ if category_id in categories:
+ del categories[category_id]
+ elif type == 'object':
+ categories = self.__CACHE.object_categories
+ if category_id in categories:
+ del categories[category_id]
+ else:
+ categories = self.__CACHE.action_categories
+ if category_id in categories:
+ del categories[category_id]
+ return hug.HTTP_202
+
+ def update_meta_rule(self, is_delete, meta_rule_id, data=None):
+
+ if is_delete:
+ meta_rules = self.__CACHE.meta_rules
+ if meta_rule_id in meta_rules:
+ del meta_rules[meta_rule_id]
+ else:
+ meta_rules = self.__CACHE.meta_rules
+ if meta_rule_id in meta_rules:
+ meta_rules[meta_rule_id] = data
+ else:
+ return hug.HTTP_208
+ return hug.HTTP_202
+
+ def delete_data(self, data_id, type):
+
+ if type == 'subject':
+ data = self.__CACHE.subject_data
+ if data_id in data:
+ del data[data_id]
+ elif type == 'object':
+ data = self.__CACHE.object_data
+ if data_id in data:
+ del data[data_id]
+ else:
+ data = self.__CACHE.action_data
+ if data_id in data:
+ del data[data_id]
+
+ return hug.HTTP_202
+
+ def delete_attributes(self, name):
+
+ attributes = self.__CACHE.attributes
+ self.__CACHE.set_attribute(name)
+
+ return hug.HTTP_202
diff --git a/moon_engine/moon_engine/api/pipeline/validator.py b/moon_engine/moon_engine/api/pipeline/validator.py
new file mode 100644
index 00000000..1fc8588a
--- /dev/null
+++ b/moon_engine/moon_engine/api/pipeline/validator.py
@@ -0,0 +1,125 @@
+# Software Name: MOON
+
+# Version: 5.4
+
+# SPDX-FileCopyrightText: Copyright (c) 2018-2020 Orange and its contributors
+# SPDX-License-Identifier: Apache-2.0
+
+# This software is distributed under the 'Apache License 2.0',
+# the text of which is available at 'http://www.apache.org/licenses/LICENSE-2.0.txt'
+# or see the "LICENSE" file for more details.
+
+
+from moon_cache.context import Context
+from moon_utilities import exceptions
+import itertools
+import logging
+import hug
+from moon_cache.cache import Cache
+from moon_engine.api.configuration import get_configuration
+
+LOGGER = logging.getLogger("moon.authz.api." + __name__)
+
+
+class Validator(object):
+ __CACHE = None
+
+ def __init__(self):
+
+ self.__CACHE = Cache.getInstance(manager_url=get_configuration("manager_url"),
+ incremental=get_configuration("incremental_updates"),
+ manager_api_key=get_configuration("api_token"))
+ self.context = None
+
+ def authz(self, subject_name, object_name, action_name):
+
+ ctx = {
+ "pdp_id": get_configuration("uuid"),
+ "subject_name": subject_name,
+ "object_name": object_name,
+ "action_name": action_name
+ }
+ self.context = Context(ctx, self.__CACHE)
+
+ self.context.set_cache(self.__CACHE)
+ self.context.increment_index()
+ response = self.__authz_request()
+ self.context.delete_cache()
+ return response
+
+ def __authz_request(self):
+
+ LOGGER.debug("self.context.pdp_set={}".format(self.context.pdp_set))
+ result, message = self.__check_rules()
+ if result:
+ if self.__exec_instructions(result):
+ return hug.HTTP_204
+ else:
+ self.context.current_state = "deny"
+ return hug.HTTP_403
+
+ def __check_rules(self):
+
+ scopes_list = list()
+ current_header_id = self.context.headers[self.context.index]
+ if not self.context.pdp_set:
+ raise exceptions.PdpUnknown
+ if current_header_id not in self.context.pdp_set:
+ raise Exception('Invalid index')
+ current_pdp = self.context.pdp_set[current_header_id]
+ category_list = list()
+ if 'meta_rules' not in current_pdp:
+ raise exceptions.PdpContentError
+ try:
+ category_list.extend(current_pdp["meta_rules"]["subject_categories"])
+ category_list.extend(current_pdp["meta_rules"]["object_categories"])
+ category_list.extend(current_pdp["meta_rules"]["action_categories"])
+ except Exception:
+ raise exceptions.MetaRuleContentError
+ if 'target' not in current_pdp:
+ raise exceptions.PdpContentError
+ for category in category_list:
+ scope = list(current_pdp['target'][category])
+ scopes_list.append(scope)
+ if self.context.current_policy_id not in self.__CACHE.rules:
+ raise exceptions.PolicyUnknown
+ if 'rules' not in self.__CACHE.rules[self.context.current_policy_id]:
+ raise exceptions.RuleUnknown
+
+ for item in itertools.product(*scopes_list):
+ req = list(item)
+ for rule in self.__CACHE.rules[self.context.current_policy_id]["rules"]:
+ if req == rule['rule']:
+ return rule['instructions'], ""
+ if not list(itertools.product(*scopes_list)):
+ LOGGER.error("There is an error in retrieved scopes ({})".format(scopes_list))
+ cat_list = []
+ categories = dict(self.__CACHE.subject_categories)
+ categories.update(dict(self.__CACHE.object_categories))
+ categories.update(dict(self.__CACHE.action_categories))
+ for category in category_list:
+ if category.startswith("attributes:"):
+ cat_list.append(category)
+ else:
+ cat_list.append(categories[category].get('name'))
+ LOGGER.error("Categories are ({})".format(", ".join(cat_list)))
+ return False, "There is an error in retrieved scopes"
+ LOGGER.warning("No rule match the request...")
+ return False, "No rule match the request..."
+
+ def __exec_instructions(self, instructions):
+
+ for instruction in instructions:
+ for key in instruction:
+ if key == "decision":
+ if instruction["decision"] == "grant":
+ self.context.current_state = "grant"
+ LOGGER.info("__exec_instructions True {}".format(
+ self.context.current_state))
+ return True
+ else:
+ self.context.current_state = instruction["decision"].lower()
+
+ LOGGER.info("__exec_instructions False {}".format(self.context.current_state))
+
+ return False
diff --git a/moon_engine/moon_engine/api/status.py b/moon_engine/moon_engine/api/status.py
new file mode 100644
index 00000000..2a44a865
--- /dev/null
+++ b/moon_engine/moon_engine/api/status.py
@@ -0,0 +1,30 @@
+# Software Name: MOON
+
+# Version: 5.4
+
+# SPDX-FileCopyrightText: Copyright (c) 2018-2020 Orange and its contributors
+# SPDX-License-Identifier: Apache-2.0
+
+# This software is distributed under the 'Apache License 2.0',
+# the text of which is available at 'http://www.apache.org/licenses/LICENSE-2.0.txt'
+# or see the "LICENSE" file for more details.
+
+
+"""Status API"""
+import hug
+from moon_engine.api import configuration
+
+@hug.local()
+@hug.get("/status/")
+def list_status():
+ """
+ List statuses
+ :return: JSON status output
+ """
+
+ return {"status": {
+ "uuid": configuration.get_configuration("uuid"),
+ "type": configuration.get_configuration("type"),
+ "log" : configuration.get_configuration("logging").get(
+ "handlers", {}).get("file", {}).get("filename", "")
+ }}
diff --git a/moon_engine/moon_engine/api/wrapper/__init__.py b/moon_engine/moon_engine/api/wrapper/__init__.py
new file mode 100644
index 00000000..582be686
--- /dev/null
+++ b/moon_engine/moon_engine/api/wrapper/__init__.py
@@ -0,0 +1,11 @@
+# Software Name: MOON
+
+# Version: 5.4
+
+# SPDX-FileCopyrightText: Copyright (c) 2018-2020 Orange and its contributors
+# SPDX-License-Identifier: Apache-2.0
+
+# This software is distributed under the 'Apache License 2.0',
+# the text of which is available at 'http://www.apache.org/licenses/LICENSE-2.0.txt'
+# or see the "LICENSE" file for more details.
+
diff --git a/moon_engine/moon_engine/api/wrapper/api/__init__.py b/moon_engine/moon_engine/api/wrapper/api/__init__.py
new file mode 100644
index 00000000..582be686
--- /dev/null
+++ b/moon_engine/moon_engine/api/wrapper/api/__init__.py
@@ -0,0 +1,11 @@
+# Software Name: MOON
+
+# Version: 5.4
+
+# SPDX-FileCopyrightText: Copyright (c) 2018-2020 Orange and its contributors
+# SPDX-License-Identifier: Apache-2.0
+
+# This software is distributed under the 'Apache License 2.0',
+# the text of which is available at 'http://www.apache.org/licenses/LICENSE-2.0.txt'
+# or see the "LICENSE" file for more details.
+
diff --git a/moon_engine/moon_engine/api/wrapper/api/authz.py b/moon_engine/moon_engine/api/wrapper/api/authz.py
new file mode 100644
index 00000000..4d1e4a84
--- /dev/null
+++ b/moon_engine/moon_engine/api/wrapper/api/authz.py
@@ -0,0 +1,43 @@
+# Software Name: MOON
+
+# Version: 5.4
+
+# SPDX-FileCopyrightText: Copyright (c) 2018-2020 Orange and its contributors
+# SPDX-License-Identifier: Apache-2.0
+
+# This software is distributed under the 'Apache License 2.0',
+# the text of which is available at 'http://www.apache.org/licenses/LICENSE-2.0.txt'
+# or see the "LICENSE" file for more details.
+
+
+"""Authz API"""
+
+import hug
+from moon_engine.api.wrapper.router import Router
+
+
+class Authz(object):
+ """
+ Endpoint for Authz requests
+ """
+
+ @staticmethod
+ @hug.local()
+ @hug.get("/authz/{project_id}/{subject_name}/{object_name}/{action_name}")
+ def get(project_id: hug.types.text, subject_name: hug.types.text, object_name: hug.types.text,
+ action_name: hug.types.text):
+ """Get a response on Main Authorization request
+
+ :param project_id: uuid of the project
+ :param subject_name: name of the subject or the request
+ :param object_name: name of the object
+ :param action_name: name of the action
+ :return:
+ "result": {true or false }
+ :internal_api: authz
+ """
+
+ with Router(project_id, subject_name, object_name, action_name) as router:
+
+ response = router.auth_request()
+ return response
diff --git a/moon_engine/moon_engine/api/wrapper/api/pipeline.py b/moon_engine/moon_engine/api/wrapper/api/pipeline.py
new file mode 100644
index 00000000..19b9578a
--- /dev/null
+++ b/moon_engine/moon_engine/api/wrapper/api/pipeline.py
@@ -0,0 +1,100 @@
+# Software Name: MOON
+
+# Version: 5.4
+
+# SPDX-FileCopyrightText: Copyright (c) 2018-2020 Orange and its contributors
+# SPDX-License-Identifier: Apache-2.0
+
+# This software is distributed under the 'Apache License 2.0',
+# the text of which is available at 'http://www.apache.org/licenses/LICENSE-2.0.txt'
+# or see the "LICENSE" file for more details.
+
+
+"""Pipeline API"""
+import hug
+from moon_utilities.auth_functions import api_key_authentication
+from moon_engine import orchestration_driver
+from moon_utilities.security_functions import validate_input
+from moon_engine.api import configuration
+from moon_cache.cache import Cache
+
+CACHE = Cache.getInstance(manager_url=configuration.get_configuration("manager_url"),
+ incremental=configuration.get_configuration("incremental_updates"),
+ manager_api_key=configuration.get_configuration("api_token"))
+
+
+class Pipeline(object):
+ """
+ Endpoint for pipelines requests
+ """
+
+ @staticmethod
+ @hug.local()
+ @hug.get("/pipelines", requires=api_key_authentication)
+ @hug.get("/pipeline/{uuid}", requires=api_key_authentication)
+ def get(uuid: hug.types.uuid=None, authed_user: hug.directives.user=None):
+ """Retrieve all pipelines
+
+ :param uuid: uuid of the pipeline
+ :param authed_user: the name of the authenticated user
+ :return: {
+ "pipeline_id1": {
+ "name": "...",
+ "description": "... (optional)",
+ }
+ }
+ """
+ uuid = str(uuid).replace("-", "")
+ orchestration_driver.init()
+ data = orchestration_driver.PipelineManager.get_pipelines(moon_user_id=authed_user,
+ pipeline_id=uuid)
+ return {"pipelines": data}
+
+ @staticmethod
+ @hug.local()
+ @hug.put("/pipeline/{uuid}", requires=api_key_authentication)
+ def put(uuid: hug.types.uuid, body: validate_input("name"),
+ authed_user: hug.directives.user = None):
+ """
+ Ask for the creation of a new pipeline
+ :param uuid: uuid of the pipeline
+ :param body: body of the request
+ :param authed_user: the name of the authenticated user
+ :return: {
+ "name": "my_pdp",
+ "description": "...",
+ "vim_project_id": "an existing ID",
+ "security_pipelines": ["an existing policy ID", ],
+ "slave": ["name of a slave", ]
+ }
+ """
+ uuid = str(uuid).replace("-", "")
+ orchestration_driver.init()
+ data = orchestration_driver.PipelineManager.add_pipeline(moon_user_id=authed_user,
+ pipeline_id=uuid,
+ data=body)
+ CACHE.add_pipeline(uuid, data)
+ return {"pipelines": data}
+
+ @staticmethod
+ @hug.local()
+ @hug.delete("/pipeline/{uuid}", requires=api_key_authentication)
+ def delete(uuid: hug.types.uuid, authed_user: hug.directives.user = None):
+ """
+ Ask for the deletion of a new pipeline
+ :param uuid: uuid of the pipeline
+ :param authed_user: the name of the authenticated user
+ :return: {
+ "name": "my_pdp",
+ "description": "...",
+ "vim_project_id": "an existing ID",
+ "security_pipelines": ["an existing policy ID", ],
+ "slave": ["name of a slave", ]
+ }
+ """
+ uuid = str(uuid).replace("-", "")
+ orchestration_driver.init()
+ orchestration_driver.PipelineManager.delete_pipeline(moon_user_id=authed_user,
+ pipeline_id=uuid)
+ CACHE.delete_pipeline(uuid)
+ return True
diff --git a/moon_engine/moon_engine/api/wrapper/api/update.py b/moon_engine/moon_engine/api/wrapper/api/update.py
new file mode 100644
index 00000000..7af274e5
--- /dev/null
+++ b/moon_engine/moon_engine/api/wrapper/api/update.py
@@ -0,0 +1,179 @@
+# Software Name: MOON
+
+# Version: 5.4
+
+# SPDX-FileCopyrightText: Copyright (c) 2018-2020 Orange and its contributors
+# SPDX-License-Identifier: Apache-2.0
+
+# This software is distributed under the 'Apache License 2.0',
+# the text of which is available at 'http://www.apache.org/licenses/LICENSE-2.0.txt'
+# or see the "LICENSE" file for more details.
+
+
+"""Update API"""
+import hug
+from moon_utilities.auth_functions import api_key_authentication
+from moon_engine.api.wrapper.update_wrapper import UpdateWrapper as UpdateWrapper
+
+
+class WrapperUpdate(object):
+
+ @staticmethod
+ @hug.local()
+ @hug.put("/update", requires=api_key_authentication)
+ def update(body, response, authed_user: hug.directives.user):
+ """Tell the moon_engine wrapper that its own data should be updated
+ It simply reloads the conf file
+
+ :return: 204 status code
+ """
+
+ # todo call wrapper to update its pdp at the cache
+ update_wrapper = UpdateWrapper()
+ response.status = update_wrapper.update_wrapper(data=body, moon_user_id=authed_user)
+
+ @staticmethod
+ @hug.local()
+ @hug.put("/update/pdp/{pdp_id}", requires=api_key_authentication)
+ def update_pdp(body, pdp_id: hug.types.uuid, response, authed_user: hug.directives.user):
+ """Tell the moon_engine wrapper that its cache should be updated
+ body may contain the attributes that the moon_engine should get from the manager
+ if the attributes key is empty, all data should be retrieved
+ body example:
+ {
+ "vim_project_id": "...",
+ "security_pipeline": ["policy_id1", "policy_id2"],
+ "attributes": ["subjects", "subject_assignments", "subject_categories"]
+ }
+ :return: 202 status code
+ """
+
+ # todo call wrapper to update its pdp at the cache
+ update_wrapper = UpdateWrapper()
+ response.status = update_wrapper.update_pdp(pdp_id=str(pdp_id).replace("-", ""), data=body, moon_user_id=authed_user)
+
+ @staticmethod
+ @hug.local()
+ @hug.delete("/update/pdp/{pdp_id}", requires=api_key_authentication)
+ def delete_pdp(pdp_id: hug.types.uuid, response, authed_user: hug.directives.user):
+ """Tell the moon_engine wrapper that its cache should be updated
+ body may contain the attributes that the moon_engine should get from the manager
+ if the attributes key is empty, all data should be retrieved
+ body example:
+ {
+ "vim_project_id": "...",
+ "security_pipeline": ["policy_id1", "policy_id2"],
+ "attributes": ["subjects", "subject_assignments", "subject_categories"]
+ }
+ :return: 202 status code
+ """
+
+ # todo call wrapper to update its pdp at the cache
+ update_wrapper = UpdateWrapper()
+ response.status = update_wrapper.delete_pdp(pdp_id=str(pdp_id).replace("-", ""), moon_user_id=authed_user)
+
+ @staticmethod
+ @hug.local()
+ @hug.put("/update/policy/{policy_id}", requires=api_key_authentication)
+ def update_policy(body, policy_id: hug.types.uuid, response, authed_user: hug.directives.user):
+ update_wrapper = UpdateWrapper()
+ response.status = update_wrapper.update_policy(policy_id=str(policy_id).replace("-", ""), data=body, moon_user_id=authed_user)
+
+ @staticmethod
+ @hug.local()
+ @hug.delete("/update/policy/{policy_id}", requires=api_key_authentication)
+ def delete_policy(policy_id: hug.types.uuid, response, authed_user: hug.directives.user):
+ update_wrapper = UpdateWrapper()
+ response.status = update_wrapper.delete_policy(policy_id=str(policy_id).replace("-", ""), moon_user_id=authed_user)
+
+ @staticmethod
+ @hug.local()
+ @hug.delete("/update/assignment/{policy_id}/{type}/", requires=api_key_authentication)
+ @hug.delete("/update/assignment/{policy_id}/{type}/{perimeter_id}", requires=api_key_authentication)
+ @hug.delete("/update/assignment/{policy_id}/{type}/{perimeter_id}/{category_id}", requires=api_key_authentication)
+ @hug.delete("/update/assignment/{policy_id}/{type}/{perimeter_id}/{category_id}/{data_id}", requires=api_key_authentication)
+ def delete_assignment(response, policy_id: hug.types.uuid, type: hug.types.text,
+ perimeter_id: hug.types.uuid = None, category_id: hug.types.uuid = None,
+ data_id: hug.types.uuid = None, authed_user: hug.directives.user=None):
+ update_wrapper = UpdateWrapper()
+ response.status = update_wrapper.delete_assignment(type=type, policy_id=str(policy_id).replace("-", ""),
+ perimeter_id=str(perimeter_id).replace("-", ""),
+ category_id=str(category_id).replace("-", ""),
+ data_id=data_id, moon_user_id=authed_user)
+
+ @staticmethod
+ @hug.local()
+ @hug.put("/update/perimeter/{perimeter_id}/{policy_id}/{type}", requires=api_key_authentication)
+ def update_perimeter(body, perimeter_id: hug.types.uuid, policy_id: hug.types.uuid,
+ type: hug.types.text, response, authed_user: hug.directives.user):
+ update_wrapper = UpdateWrapper()
+ response.status = update_wrapper.update_perimeter( type=type,
+ perimeter_id=str(perimeter_id).replace("-", ""), data=body,
+ policy_id=str(policy_id).replace("-", ""), moon_user_id=authed_user)
+
+ @staticmethod
+ @hug.local()
+ @hug.delete("/update/perimeter/{perimeter_id}/{policy_id}/{type}", requires=api_key_authentication)
+ def delete_perimeter(perimeter_id: hug.types.uuid, policy_id: hug.types.uuid,
+ type: hug.types.text, response, authed_user: hug.directives.user):
+ update_wrapper = UpdateWrapper()
+ response.status = update_wrapper.delete_perimeter(type=type,
+ perimeter_id=str(perimeter_id).replace("-", ""),
+ policy_id=str(policy_id).replace("-", ""), moon_user_id=authed_user)
+
+ @staticmethod
+ @hug.local()
+ @hug.delete("/update/rule/{policy_id}/{rule_id}", requires=api_key_authentication)
+ def delete_rule(policy_id: hug.types.uuid, rule_id: hug.types.uuid, response, authed_user: hug.directives.user):
+ update_wrapper = UpdateWrapper()
+ response.status = update_wrapper.delete_rule(rule_id=str(rule_id).replace("-", ""), policy_id=str(policy_id).replace("-", ""), moon_user_id=authed_user)
+
+ @staticmethod
+ @hug.local()
+ @hug.put("/update/model/{model_id}", requires=api_key_authentication)
+ def update_model(body, model_id: hug.types.uuid, response, authed_user: hug.directives.user):
+ update_wrapper = UpdateWrapper()
+ response.status = update_wrapper.update_model(model_id=str(model_id).replace("-", ""), data=body, moon_user_id=authed_user)
+
+ @staticmethod
+ @hug.local()
+ @hug.delete("/update/model/{model_id}", requires=api_key_authentication)
+ def delete_model(model_id: hug.types.uuid, response, authed_user: hug.directives.user):
+ update_wrapper = UpdateWrapper()
+ response.status = update_wrapper.delete_model(model_id=str(model_id).replace("-", ""), moon_user_id=authed_user)
+
+ @staticmethod
+ @hug.local()
+ @hug.delete("/update/meta_data/{category_id}/{type}", requires=api_key_authentication)
+ def delete_category(category_id: hug.types.uuid, type: hug.types.text, response, authed_user: hug.directives.user):
+ update_wrapper = UpdateWrapper()
+ response.status = update_wrapper.delete_category(category_id=str(category_id).replace("-", ""), type=type, moon_user_id=authed_user)
+
+ @staticmethod
+ @hug.local()
+ @hug.put("/update/meta_rule/{meta_rule_id}", requires=api_key_authentication)
+ def update_meta_rule(body, meta_rule_id: hug.types.uuid, response, authed_user: hug.directives.user):
+ update_wrapper = UpdateWrapper()
+ response.status = update_wrapper.update_meta_rule(meta_rule_id=str(meta_rule_id).replace("-", ""), data=body, moon_user_id=authed_user)
+
+ @staticmethod
+ @hug.local()
+ @hug.delete("/update/meta_rule/{meta_rule_id}", requires=api_key_authentication)
+ def delete_meta_rule(meta_rule_id: hug.types.uuid, response, authed_user: hug.directives.user):
+ update_wrapper = UpdateWrapper()
+ response.status = update_wrapper.delete_meta_rule(meta_rule_id=str(meta_rule_id).replace("-", ""), moon_user_id=authed_user)
+
+ @staticmethod
+ @hug.local()
+ @hug.delete("/update/data/{data_id}/{type}", requires=api_key_authentication)
+ def delete_data(data_id: hug.types.uuid, type: hug.types.text, response, authed_user: hug.directives.user):
+ update_wrapper = UpdateWrapper()
+ response.status = update_wrapper.delete_data(data_id=str(data_id).replace("-", ""), type=type, moon_user_id=authed_user)
+
+ @staticmethod
+ @hug.local()
+ @hug.delete("/update/attributes/{name}", requires=api_key_authentication)
+ def delete_data(name: str, response, authed_user: hug.directives.user):
+ update_wrapper = UpdateWrapper()
+ response.status = update_wrapper.delete_attributes(name=name, moon_user_id=authed_user)
+
diff --git a/moon_engine/moon_engine/api/wrapper/router.py b/moon_engine/moon_engine/api/wrapper/router.py
new file mode 100644
index 00000000..db6b6e24
--- /dev/null
+++ b/moon_engine/moon_engine/api/wrapper/router.py
@@ -0,0 +1,115 @@
+# Software Name: MOON
+
+# Version: 5.4
+
+# SPDX-FileCopyrightText: Copyright (c) 2018-2020 Orange and its contributors
+# SPDX-License-Identifier: Apache-2.0
+
+# This software is distributed under the 'Apache License 2.0',
+# the text of which is available at 'http://www.apache.org/licenses/LICENSE-2.0.txt'
+# or see the "LICENSE" file for more details.
+
+
+from moon_utilities import exceptions
+from moon_cache.cache import Cache
+from uuid import uuid4
+import logging
+import requests
+from moon_engine.api.configuration import get_configuration
+
+LOGGER = logging.getLogger("moon.engine.wrapper." + __name__)
+
+
+class Router(object):
+ __CACHE = None
+
+ def __init__(self, project_id, subject_name, object_name, action_name):
+
+ if not self.__CACHE:
+ self.__CACHE = Cache.getInstance(manager_url=get_configuration("manager_url"),
+ incremental=get_configuration("incremental_updates"),
+ manager_api_key=get_configuration("api_token"))
+
+ self.pipeline_id = self.__check_pdp_from_cache(project_id)
+
+ self.request_id = uuid4().hex
+
+ self.ctx = {
+ "project_id": project_id,
+ "subject_name": subject_name,
+ "object_name": object_name,
+ "action_name": action_name
+ }
+
+ # ToDo add status of request
+ self.__CACHE.authz_requests[self.request_id] = {}
+
+ pdp_id = self.__CACHE.get_pdp_from_vim_project(project_id)
+ self.__CACHE.update(pipeline=pdp_id)
+ self.pipeline = []
+ if self.pipeline_id in self.__CACHE.pipelines:
+ self.pipeline = self.__CACHE.pipelines[self.pipeline_id]
+
+ if len(self.pipeline) == 0 or not all(
+ k in self.pipeline for k in ("host", "port")):
+ raise exceptions.MoonError('Void container chaining')
+
+ def __enter__(self):
+ return self
+
+ def __exit__(self, exc_type, exc_val, exc_tb):
+ self.__CACHE.authz_requests.pop(self.request_id)
+
+ def auth_request(self):
+ req = None
+ endpoint = self.__CACHE.get_pipeline_url(self.ctx["project_id"])
+
+ try:
+ req = requests.get("{}/authz/{}/{}/{}".format(
+ endpoint,
+ self.ctx["subject_name"],
+ self.ctx["object_name"],
+ self.ctx["action_name"]),
+ timeout=2
+ )
+
+ if req.status_code != 200 and req.status_code != 202 and req.status_code != 204:
+ raise exceptions.AuthzException(
+ "Receive bad response from Authz function (with address - {})"
+ .format(req.status_code))
+
+ except requests.exceptions.ConnectionError:
+ LOGGER.error("Cannot connect to {}".format(
+ "{}/authz".format(endpoint))
+ )
+ except requests.exceptions.ReadTimeout:
+ LOGGER.error("Timeout error")
+ return {"result": False, "message": "Timeout during request for pipeline"}, 400
+ except Exception as e:
+ LOGGER.error("Unexpected error:", e)
+ return {"result": False, "message": e}, 400
+
+ if not req:
+ raise exceptions.AuthzException("Cannot connect to Authz function")
+
+ if req.status_code == 204:
+ return {"result": True, "message": ""}
+ return {"result": False, "message": req.content}, 400
+
+ def __check_pdp_from_cache(self, uuid):
+ """Check if a PDP exist with this ID in the cache of this component
+
+ :param uuid: Keystone Project ID
+ :return: True or False
+ """
+
+ if self.__CACHE.get_pdp_from_vim_project(uuid):
+ return self.__CACHE.get_pipeline_id_from_project_id(uuid)
+
+ self.__CACHE.update()
+
+ if self.__CACHE.get_pdp_from_vim_project(uuid):
+ return self.__CACHE.get_pipeline_id_from_project_id(uuid)
+
+ raise exceptions.MoonError("Unknown Project ID {}".format(uuid))
+
diff --git a/moon_engine/moon_engine/api/wrapper/update_wrapper.py b/moon_engine/moon_engine/api/wrapper/update_wrapper.py
new file mode 100644
index 00000000..bb388472
--- /dev/null
+++ b/moon_engine/moon_engine/api/wrapper/update_wrapper.py
@@ -0,0 +1,233 @@
+# Software Name: MOON
+
+# Version: 5.4
+
+# SPDX-FileCopyrightText: Copyright (c) 2018-2020 Orange and its contributors
+# SPDX-License-Identifier: Apache-2.0
+
+# This software is distributed under the 'Apache License 2.0',
+# the text of which is available at 'http://www.apache.org/licenses/LICENSE-2.0.txt'
+# or see the "LICENSE" file for more details.
+
+
+import logging
+import sys
+
+import hug
+import requests
+from moon_engine import orchestration_driver
+from moon_cache.cache import Cache
+from moon_engine.api.configuration import get_configuration, reload_configuration
+from moon_utilities import exceptions
+
+logger = logging.getLogger("moon.engine.api.wrapper" + __name__)
+
+
+class UpdateWrapper(object):
+ __CACHE = None
+
+ def __init__(self):
+ if not self.__CACHE:
+ self.__CACHE = Cache.getInstance(
+ manager_url=get_configuration("manager_url"),
+ incremental=get_configuration("incremental_updates"),
+ manager_api_key=get_configuration("api_token"))
+
+ def update_wrapper(self, data, moon_user_id=None):
+ reload_configuration()
+ return hug.HTTP_204
+
+ def update_pdp(self, pdp_id, data, moon_user_id=None):
+
+ url_pattern = "update/pdp/{}".format(pdp_id)
+ return self.__process_request(url_pattern, body=data, moon_user_id=moon_user_id, pdp_id=pdp_id)
+
+ def delete_pdp(self, pdp_id, moon_user_id=None):
+
+ url_pattern = "update/pdp/{}".format(pdp_id)
+ return self.__process_request(url_pattern, moon_user_id=moon_user_id, pdp_id=pdp_id, delete=True)
+
+ def delete_policy(self, policy_id, moon_user_id=None):
+ url_pattern = "update/policy/{}".format(policy_id)
+ return self.__process_request(url_pattern, moon_user_id, policy_id=policy_id, delete=True)
+
+ def update_policy(self, policy_id, data=None, moon_user_id=None):
+
+ url_pattern = "update/policy/{}".format(policy_id)
+ return self.__process_request(url_pattern, body=data, moon_user_id=moon_user_id,
+ policy_id=policy_id)
+
+ def delete_assignment(self, type, policy_id, perimeter_id=None, category_id=None, data_id=None,
+ moon_user_id=None):
+
+ if policy_id and perimeter_id and category_id and data_id:
+ url_pattern = "update/assignment/{}/{}/{}/{}/{}".format(policy_id, type, perimeter_id,
+ category_id,
+ data_id)
+
+ if policy_id and perimeter_id and category_id:
+ url_pattern = "update/assignment/{}/{}/{}/{}".format(policy_id, type, perimeter_id,
+ category_id)
+
+ if policy_id and perimeter_id:
+ url_pattern = "update/assignment/{}/{}/{}".format(policy_id, type, perimeter_id)
+
+ if policy_id:
+ url_pattern = "update/assignment/{}/{}".format(policy_id, type)
+
+ return self.__process_request(url_pattern, moon_user_id, policy_id=policy_id, delete=True)
+
+ def update_perimeter(self, type, perimeter_id, data=None, policy_id=None, moon_user_id=None):
+ url_pattern = "update/perimeter/{}/{}/{}".format(perimeter_id, policy_id, type)
+ return self.__process_request(url_pattern, body=data, moon_user_id=moon_user_id,
+ policy_id=policy_id)
+
+ def delete_perimeter(self, type, perimeter_id, policy_id=None, moon_user_id=None):
+ url_pattern = "update/perimeter/{}/{}/{}".format(perimeter_id, policy_id, type)
+ return self.__process_request(url_pattern, moon_user_id, policy_id=policy_id, delete=True)
+
+ def delete_rule(self, rule_id, policy_id, moon_user_id=None):
+
+ url_pattern = "update/rule/{}/{}".format(policy_id, rule_id)
+ return self.__process_request(url_pattern, moon_user_id=moon_user_id, policy_id=policy_id,
+ delete=True)
+
+ def update_model(self, model_id, data=None, moon_user_id=None):
+
+ url_pattern = "update/model/{}".format(model_id)
+ return self.__process_request(url_pattern, body=data, moon_user_id=moon_user_id)
+
+ def delete_model(self, model_id, moon_user_id=None):
+
+ url_pattern = "update/model/{}".format(model_id)
+ return self.__process_request(url_pattern, moon_user_id=moon_user_id, delete=True)
+
+ def delete_category(self, category_id, type, moon_user_id=None):
+
+ url_pattern = "update/meta_data/{}/{}".format(category_id, type)
+ return self.__process_request(url_pattern, moon_user_id=moon_user_id, delete=True)
+
+ def update_meta_rule(self, meta_rule_id, data=None, moon_user_id=None):
+
+ url_pattern = "update/meta_rule/{}".format(meta_rule_id, type)
+ return self.__process_request(url_pattern, body=data, moon_user_id=moon_user_id)
+
+ def delete_meta_rule(self, meta_rule_id, moon_user_id=None):
+
+ url_pattern = "update/meta_rule/{}".format(meta_rule_id, type)
+ return self.__process_request(url_pattern, moon_user_id=moon_user_id, delete=True)
+
+ def delete_data(self, data_id, type, moon_user_id=None):
+
+ url_pattern = "update/data/{}/{}".format(data_id, type)
+ return self.__process_request(url_pattern, moon_user_id=moon_user_id, delete=True)
+
+ def delete_attributes(self, name, moon_user_id=None):
+
+ url_pattern = "update/attributes/{}".format(name)
+ return self.__process_request(url_pattern, moon_user_id=moon_user_id, delete=True)
+
+ def __process_request(self, url_pattern, body=None, moon_user_id=None, policy_id=None,
+ pdp_id=None, delete=False):
+ if policy_id:
+ endpoint = self.__CACHE.get_pipeline_url(pipeline_id=policy_id)
+ cached_api_key = self.__CACHE.get_api_key(pipeline_id=policy_id)
+ if orchestration_driver.PipelineManager:
+ _pdp_id = self.__CACHE.get_pdp_id_from_policy_id(policy_id=policy_id)
+ api_key = orchestration_driver.PipelineManager.get_pipeline_api_key(moon_user_id=moon_user_id, pipeline_id=_pdp_id)
+ if not api_key:
+ api_key = cached_api_key
+
+ if not endpoint:
+ return hug.HTTP_208
+ if delete:
+ return self.__execute_delete_request(endpoint, url_pattern, api_key)
+ else:
+ return self.__execute_put_request(endpoint, url_pattern, api_key, body)
+
+ elif pdp_id:
+ endpoint = self.__CACHE.get_pipeline_url(pdp_id=pdp_id)
+ cached_api_key = self.__CACHE.get_api_key(pdp_id=pdp_id)
+ if orchestration_driver.PipelineManager:
+ api_key = orchestration_driver.PipelineManager.get_pipeline_api_key(moon_user_id=moon_user_id, pipeline_id=pdp_id)
+ if not api_key:
+ api_key = cached_api_key
+
+ if not endpoint:
+ return hug.HTTP_208
+ if delete:
+ return self.__execute_delete_request(endpoint, url_pattern, api_key)
+ else:
+ return self.__execute_put_request(endpoint, url_pattern, api_key, body)
+
+ else:
+ pdps = self.__CACHE.pdp
+ for _pdp_id in pdps:
+ vim_project_id = pdps.get(_pdp_id, {}).get("vim_project_id")
+ if vim_project_id:
+ cached_api_key = self.__CACHE.get_api_key(project_id=vim_project_id)
+ if orchestration_driver.PipelineManager:
+ api_key = orchestration_driver.PipelineManager.get_pipeline_api_key(moon_user_id=moon_user_id, pipeline_id=_pdp_id)
+ if not api_key:
+ api_key = cached_api_key
+
+
+ endpoint = self.__CACHE.get_pipeline_url(project_id=vim_project_id)
+
+ if delete:
+ return self.__execute_delete_request(endpoint, url_pattern, api_key)
+ else:
+ return self.__execute_put_request(endpoint, url_pattern, api_key, body)
+ return hug.HTTP_206
+
+ @staticmethod
+ def __execute_put_request(endpoint, url_pattern, api_key, body):
+ logger.info(f"Sending a PUT request on {endpoint}/{url_pattern}")
+ try:
+ req = requests.put("{}/{}".format(
+ endpoint, url_pattern), headers={"X-Api-Key": api_key}, json=body)
+ logger.info(req)
+ if req.status_code == 200:
+ return hug.HTTP_200
+ if req.status_code == 202:
+ return hug.HTTP_202
+ if req.status_code == 208:
+ return hug.HTTP_208
+
+ else:
+ raise exceptions.AuthzException(
+ "Receive bad response from Authz function "
+ "(with address - {})".format(req.status_code))
+
+ except requests.exceptions.ConnectionError:
+ logger.error("Cannot connect to {}".format(
+ "{}/authz/{}".format(endpoint, url_pattern))
+ )
+ except Exception as e:
+ logger.exception("Unexpected error:", e)
+
+ @staticmethod
+ def __execute_delete_request(endpoint, url_pattern, api_key):
+ logger.info(f"Sending a DELETE request on {endpoint}/{url_pattern}")
+ try:
+ req = requests.delete("{}/{}".format(
+ endpoint, url_pattern), headers={"X-Api-Key": api_key})
+
+ if req.status_code == 200:
+ return hug.HTTP_200
+ if req.status_code == 202:
+ return hug.HTTP_202
+ if req.status_code == 208:
+ return hug.HTTP_208
+
+ else:
+ raise exceptions.AuthzException(
+ "Receive bad response from Authz function "
+ "(with address - {})".format(req.status_code))
+
+ except requests.exceptions.ConnectionError:
+ logger.error("Cannot connect to {}".format(
+ "{}/authz/{}".format(endpoint, url_pattern))
+ )
+ except Exception as e:
+ logger.exception("Unexpected error:", e)