diff options
Diffstat (limited to 'moon_manager/moon_manager/api/assignments.py')
-rw-r--r-- | moon_manager/moon_manager/api/assignments.py | 764 |
1 files changed, 580 insertions, 184 deletions
diff --git a/moon_manager/moon_manager/api/assignments.py b/moon_manager/moon_manager/api/assignments.py index 0b2cd20b..742a043b 100644 --- a/moon_manager/moon_manager/api/assignments.py +++ b/moon_manager/moon_manager/api/assignments.py @@ -1,46 +1,57 @@ -# 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'. +# 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. + """ Assignments allow to connect data with elements of perimeter """ - -from flask import request -from flask_restful import Resource +import hug import logging -from python_moonutilities.security_functions import check_auth -from python_moondb.core import PolicyManager +import requests +from moon_manager import db_driver as driver +from moon_utilities.security_functions import validate_input +from moon_manager.api import slave as slave_class +from moon_manager.api import configuration +from moon_manager.api import policy +from moon_manager.api import perimeter +from moon_manager.api import meta_data +from moon_manager.api import data +from moon_utilities.auth_functions import api_key_authentication, connect_from_env +from moon_utilities.invalided_functions import invalidate_assignment_in_slaves -__version__ = "4.3.2" +# from moon_manager.server import handle_exception, handle_custom_exceptions -logger = logging.getLogger("moon.manager.api." + __name__) +LOGGER = logging.getLogger("moon.manager.api." + __name__) -class SubjectAssignments(Resource): +class SubjectAssignments(object): """ Endpoint for subject assignment requests """ - __urls__ = ( - "/policies/<string:uuid>/subject_assignments", - "/policies/<string:uuid>/subject_assignments/", - "/policies/<string:uuid>/subject_assignments/<string:perimeter_id>", - "/policies/<string:uuid>/subject_assignments/<string:perimeter_id>/<string:category_id>", - "/policies/<string:uuid>/subject_assignments/<string:perimeter_id>/<string:category_id>/<string:data_id>", - ) - - @check_auth - def get(self, uuid=None, perimeter_id=None, category_id=None, - data_id=None, user_id=None): + @staticmethod + @hug.local() + @hug.get("/policies/{uuid}/subject_assignments", requires=api_key_authentication) + @hug.get("/policies/{uuid}/subject_assignments/{perimeter_id}", + requires=api_key_authentication) + @hug.get("/policies/{uuid}/subject_assignments/{perimeter_id}/{category_id}", + requires=api_key_authentication) + def get(uuid: hug.types.text, perimeter_id: hug.types.text = None, + category_id: hug.types.text = None, authed_user: hug.directives.user = None): """Retrieve all subject assignments or a specific one for a given policy :param uuid: uuid of the policy :param perimeter_id: uuid of the subject :param category_id: uuid of the subject category - :param data_id: uuid of the subject scope - :param user_id: user ID who do the request + :param authed_user: user ID who do the request :return: { "subject_data_id": { "policy_id": "ID of the policy", @@ -51,106 +62,104 @@ class SubjectAssignments(Resource): } :internal_api: get_subject_assignments """ - try: - data = PolicyManager.get_subject_assignments( - user_id=user_id, policy_id=uuid, - subject_id=perimeter_id, category_id=category_id) - except Exception as e: - logger.error(e, exc_info=True) - return {"result": False, - "error": str(e)}, 500 + + data = driver.PolicyManager.get_subject_assignments( + moon_user_id=authed_user, policy_id=uuid, + subject_id=perimeter_id, category_id=category_id) + return {"subject_assignments": data} - @check_auth - def post(self, uuid=None, perimeter_id=None, category_id=None, - data_id=None, user_id=None): + @staticmethod + @hug.local() + @hug.post("/policies/{uuid}/subject_assignments", requires=api_key_authentication) + def post(body: validate_input("id", "category_id", "data_id"), uuid: hug.types.text, + authed_user: hug.directives.user = None): """Create a subject assignment. + :param body: body of the request :param uuid: uuid of the policy - :param perimeter_id: uuid of the subject (not used here) - :param category_id: uuid of the subject category (not used here) - :param data_id: uuid of the subject scope (not used here) - :param user_id: user ID who do the request + :param authed_user: user ID who do the request :request body: { - "id": "UUID of the subject", - "category_id": "UUID of the category" - "data_id": "UUID of the scope" + "id": "UUID of the subject (mandatory)", + "category_id": "UUID of the category (mandatory)" + "data_id": "UUID of the scope (mandatory)" } :return: { "subject_data_id": { "policy_id": "ID of the policy", - "subject_id": "ID of the subject", - "category_id": "ID of the category", + "subject_id": "ID of the subject (mandatory)", + "category_id": "ID of the category (mandatory)", "assignments": "Assignments list (list of data_id)", } } :internal_api: update_subject_assignment """ - try: - data_id = request.json.get("data_id") - category_id = request.json.get("category_id") - perimeter_id = request.json.get("id") - data = PolicyManager.add_subject_assignment( - user_id=user_id, policy_id=uuid, - subject_id=perimeter_id, category_id=category_id, - data_id=data_id) - except Exception as e: - logger.error(e, exc_info=True) - return {"result": False, - "error": str(e)}, 500 + data_id = body.get("data_id") + category_id = body.get("category_id") + perimeter_id = body.get("id") + + data = driver.PolicyManager.add_subject_assignment( + moon_user_id=authed_user, policy_id=uuid, + subject_id=perimeter_id, category_id=category_id, data_id=data_id) + return {"subject_assignments": data} - @check_auth - def delete(self, uuid=None, perimeter_id=None, category_id=None, - data_id=None, user_id=None): + @staticmethod + @hug.local() + @hug.delete("/policies/{uuid}/subject_assignments", requires=api_key_authentication) + @hug.delete("/policies/{uuid}/subject_assignments/{perimeter_id}", + requires=api_key_authentication) + @hug.delete("/policies/{uuid}/subject_assignments/{perimeter_id}/{category_id}", + requires=api_key_authentication) + @hug.delete("/policies/{uuid}/subject_assignments/{perimeter_id}/{category_id}/{data_id}", + requires=api_key_authentication) + def delete(uuid: hug.types.text, perimeter_id: hug.types.text = None, + category_id: hug.types.text = None, data_id: hug.types.text = None, + authed_user: hug.directives.user = None): """Delete a subject assignment for a given policy :param uuid: uuid of the policy :param perimeter_id: uuid of the subject :param category_id: uuid of the subject category :param data_id: uuid of the subject scope - :param user_id: user ID who do the request + :param authed_user: user ID who do the request :return: { "result": "True or False", "message": "optional message" } :internal_api: delete_subject_assignment """ - try: - data = PolicyManager.delete_subject_assignment( - user_id=user_id, policy_id=uuid, - subject_id=perimeter_id, category_id=category_id, - data_id=data_id) - except Exception as e: - logger.error(e, exc_info=True) - return {"result": False, - "error": str(e)}, 500 + + driver.PolicyManager.delete_subject_assignment( + moon_user_id=authed_user, policy_id=uuid, + subject_id=perimeter_id, category_id=category_id, + data_id=data_id) + + slaves = slave_class.Slaves.get().get("slaves") + invalidate_assignment_in_slaves(slaves=slaves, policy_id=uuid, perimeter_id=perimeter_id, + category_id=category_id, data_id=data_id, type="subject") return {"result": True} -class ObjectAssignments(Resource): +class ObjectAssignments(object): """ Endpoint for object assignment requests """ - __urls__ = ( - "/policies/<string:uuid>/object_assignments", - "/policies/<string:uuid>/object_assignments/", - "/policies/<string:uuid>/object_assignments/<string:perimeter_id>", - "/policies/<string:uuid>/object_assignments/<string:perimeter_id>/<string:category_id>", - "/policies/<string:uuid>/object_assignments/<string:perimeter_id>/<string:category_id>/<string:data_id>", - ) - - @check_auth - def get(self, uuid=None, perimeter_id=None, category_id=None, - data_id=None, user_id=None): + @staticmethod + @hug.local() + @hug.get("/policies/{uuid}/object_assignments", requires=api_key_authentication) + @hug.get("/policies/{uuid}/object_assignments/{perimeter_id}", requires=api_key_authentication) + @hug.get("/policies/{uuid}/object_assignments/{perimeter_id}/{category_id}", + requires=api_key_authentication) + def get(uuid: hug.types.text, perimeter_id: hug.types.text = None, + category_id: hug.types.text = None, authed_user: hug.directives.user = None): """Retrieve all object assignment or a specific one for a given policy :param uuid: uuid of the policy :param perimeter_id: uuid of the object :param category_id: uuid of the object category - :param data_id: uuid of the object scope - :param user_id: user ID who do the request + :param authed_user: user ID who do the request :return: { "object_data_id": { "policy_id": "ID of the policy", @@ -161,30 +170,27 @@ class ObjectAssignments(Resource): } :internal_api: get_object_assignments """ - try: - data = PolicyManager.get_object_assignments( - user_id=user_id, policy_id=uuid, - object_id=perimeter_id, category_id=category_id) - except Exception as e: - logger.error(e, exc_info=True) - return {"result": False, - "error": str(e)}, 500 + + data = driver.PolicyManager.get_object_assignments( + moon_user_id=authed_user, policy_id=uuid, + object_id=perimeter_id, category_id=category_id) + return {"object_assignments": data} - @check_auth - def post(self, uuid=None, perimeter_id=None, category_id=None, - data_id=None, user_id=None): + @staticmethod + @hug.local() + @hug.post("/policies/{uuid}/object_assignments", requires=api_key_authentication) + def post(body: validate_input("id", "category_id", "data_id"), uuid, + authed_user: hug.directives.user = None): """Create an object assignment. + :param body: body of the request :param uuid: uuid of the policy - :param perimeter_id: uuid of the object (not used here) - :param category_id: uuid of the object category (not used here) - :param data_id: uuid of the object scope (not used here) - :param user_id: user ID who do the request + :param authed_user: user ID who do the request :request body: { - "id": "UUID of the action", - "category_id": "UUID of the category" - "data_id": "UUID of the scope" + "id": "UUID of the action (mandatory)", + "category_id": "UUID of the category (mandatory)", + "data_id": "UUID of the scope (mandatory)" } :return: { "object_data_id": { @@ -196,71 +202,71 @@ class ObjectAssignments(Resource): } :internal_api: update_object_assignment """ - try: - data_id = request.json.get("data_id") - category_id = request.json.get("category_id") - perimeter_id = request.json.get("id") - data = PolicyManager.add_object_assignment( - user_id=user_id, policy_id=uuid, - object_id=perimeter_id, category_id=category_id, - data_id=data_id) - except Exception as e: - logger.error(e, exc_info=True) - return {"result": False, - "error": str(e)}, 500 + + data_id = body.get("data_id") + category_id = body.get("category_id") + perimeter_id = body.get("id") + data = driver.PolicyManager.add_object_assignment(moon_user_id=authed_user, policy_id=uuid, + object_id=perimeter_id, + category_id=category_id, data_id=data_id) + return {"object_assignments": data} - @check_auth - def delete(self, uuid=None, perimeter_id=None, category_id=None, - data_id=None, user_id=None): + @staticmethod + @hug.local() + @hug.delete("/policies/{uuid}/object_assignments", requires=api_key_authentication) + @hug.delete("/policies/{uuid}/object_assignments/{perimeter_id}", + requires=api_key_authentication) + @hug.delete("/policies/{uuid}/object_assignments/{perimeter_id}/{category_id}", + requires=api_key_authentication) + @hug.delete("/policies/{uuid}/object_assignments/{perimeter_id}/{category_id}/{data_id}", + requires=api_key_authentication) + def delete(uuid: hug.types.text, perimeter_id: hug.types.text = None, + category_id: hug.types.text = None, data_id: hug.types.text = None, + authed_user: hug.directives.user = None): """Delete a object assignment for a given policy :param uuid: uuid of the policy :param perimeter_id: uuid of the object :param category_id: uuid of the object category :param data_id: uuid of the object scope - :param user_id: user ID who do the request + :param authed_user: user ID who do the request :return: { "result": "True or False", "message": "optional message" } :internal_api: delete_object_assignment """ - try: - data = PolicyManager.delete_object_assignment( - user_id=user_id, policy_id=uuid, - object_id=perimeter_id, category_id=category_id, - data_id=data_id) - except Exception as e: - logger.error(e, exc_info=True) - return {"result": False, - "error": str(e)}, 500 + driver.PolicyManager.delete_object_assignment( + moon_user_id=authed_user, policy_id=uuid, object_id=perimeter_id, + category_id=category_id, data_id=data_id) + + slaves = slave_class.Slaves.get().get("slaves") + invalidate_assignment_in_slaves(slaves=slaves, policy_id=uuid, perimeter_id=perimeter_id, + category_id=category_id, data_id=data_id, type="object") + return {"result": True} -class ActionAssignments(Resource): +class ActionAssignments(object): """ Endpoint for action assignment requests """ - __urls__ = ( - "/policies/<string:uuid>/action_assignments", - "/policies/<string:uuid>/action_assignments/", - "/policies/<string:uuid>/action_assignments/<string:perimeter_id>", - "/policies/<string:uuid>/action_assignments/<string:perimeter_id>/<string:category_id>", - "/policies/<string:uuid>/action_assignments/<string:perimeter_id>/<string:category_id>/<string:data_id>", - ) - - @check_auth - def get(self, uuid=None, perimeter_id=None, category_id=None, - data_id=None, user_id=None): + @staticmethod + @hug.local() + @hug.get("/policies/{uuid}/action_assignments", requires=api_key_authentication) + @hug.get("/policies/{uuid}/action_assignments/{perimeter_id}", requires=api_key_authentication) + @hug.get("/policies/{uuid}/action_assignments/{perimeter_id}/{category_id}", + requires=api_key_authentication) + def get(uuid: hug.types.text, perimeter_id: hug.types.text = None, + category_id: hug.types.text = None, authed_user: hug.directives.user = None): """Retrieve all action assignment or a specific one for a given policy :param uuid: uuid of the policy :param perimeter_id: uuid of the action :param category_id: uuid of the action category - :param data_id: uuid of the action scope - :param user_id: user ID who do the request + :param authed_user: user ID who do the request :return: { "action_data_id": { "policy_id": "ID of the policy", @@ -271,30 +277,26 @@ class ActionAssignments(Resource): } :internal_api: get_action_assignments """ - try: - data = PolicyManager.get_action_assignments( - user_id=user_id, policy_id=uuid, - action_id=perimeter_id, category_id=category_id) - except Exception as e: - logger.error(e, exc_info=True) - return {"result": False, - "error": str(e)}, 500 + data = driver.PolicyManager.get_action_assignments( + moon_user_id=authed_user, policy_id=uuid, + action_id=perimeter_id, category_id=category_id) + return {"action_assignments": data} - @check_auth - def post(self, uuid=None, perimeter_id=None, category_id=None, - data_id=None, user_id=None): + @staticmethod + @hug.local() + @hug.post("/policies/{uuid}/action_assignments", requires=api_key_authentication) + def post(body: validate_input("id", "category_id", "data_id"), uuid, + authed_user: hug.directives.user = None): """Create an action assignment. + :param body: body of the request :param uuid: uuid of the policy - :param perimeter_id: uuid of the action (not used here) - :param category_id: uuid of the action category (not used here) - :param data_id: uuid of the action scope (not used here) - :param user_id: user ID who do the request + :param authed_user: user ID who do the request :request body: { - "id": "UUID of the action", - "category_id": "UUID of the category", - "data_id": "UUID of the scope" + "id": "UUID of the action (mandatory)", + "category_id": "UUID of the category (mandatory)", + "data_id": "UUID of the scope (mandatory)" } :return: { "action_data_id": { @@ -306,43 +308,437 @@ class ActionAssignments(Resource): } :internal_api: update_action_assignment """ - try: - data_id = request.json.get("data_id") - category_id = request.json.get("category_id") - perimeter_id = request.json.get("id") - data = PolicyManager.add_action_assignment( - user_id=user_id, policy_id=uuid, - action_id=perimeter_id, category_id=category_id, - data_id=data_id) - except Exception as e: - logger.error(e, exc_info=True) - return {"result": False, - "error": str(e)}, 500 + + data_id = body.get("data_id") + category_id = body.get("category_id") + perimeter_id = body.get("id") + data = driver.PolicyManager.add_action_assignment( + moon_user_id=authed_user, policy_id=uuid, + action_id=perimeter_id, category_id=category_id, data_id=data_id) + return {"action_assignments": data} - @check_auth - def delete(self, uuid=None, perimeter_id=None, category_id=None, - data_id=None, user_id=None): + @staticmethod + @hug.local() + @hug.delete("/policies/{uuid}/action_assignments", requires=api_key_authentication) + @hug.delete("/policies/{uuid}/action_assignments/{perimeter_id}", + requires=api_key_authentication) + @hug.delete("/policies/{uuid}/action_assignments/{perimeter_id}/{category_id}", + requires=api_key_authentication) + @hug.delete("/policies/{uuid}/action_assignments/{perimeter_id}/{category_id}/{data_id}", + requires=api_key_authentication) + def delete(uuid: hug.types.text, perimeter_id: hug.types.text = None, + category_id: hug.types.text = None, data_id: hug.types.text = None, + authed_user: hug.directives.user = None): """Delete a action assignment for a given policy :param uuid: uuid of the policy :param perimeter_id: uuid of the action :param category_id: uuid of the action category :param data_id: uuid of the action scope - :param user_id: user ID who do the request + :param authed_user: user ID who do the request :return: { "result": "True or False", "message": "optional message" } :internal_api: delete_action_assignment """ - try: - data = PolicyManager.delete_action_assignment( - user_id=user_id, policy_id=uuid, - action_id=perimeter_id, category_id=category_id, - data_id=data_id) - except Exception as e: - logger.error(e, exc_info=True) - return {"result": False, - "error": str(e)}, 500 + + driver.PolicyManager.delete_action_assignment( + moon_user_id=authed_user, policy_id=uuid, + action_id=perimeter_id, category_id=category_id, data_id=data_id) + + slaves = slave_class.Slaves.get().get("slaves") + invalidate_assignment_in_slaves(slaves=slaves, policy_id=uuid, perimeter_id=perimeter_id, + category_id=category_id, data_id=data_id, type="action") + return {"result": True} + + +SubjectAssignmentsAPI = hug.API(name='subject_assignments', doc=SubjectAssignments.__doc__) +ObjectAssignmentsAPI = hug.API(name='object_assignments', doc=ObjectAssignments.__doc__) +ActionAssignmentsAPI = hug.API(name='action_assignments', doc=ActionAssignments.__doc__) + + +@hug.object(name='subjects', version='1.0.0', api=SubjectAssignmentsAPI) +class SubjectAssignmentsCLI(object): + """An example of command like calls via an Object""" + + @staticmethod + @hug.object.cli + def list(policy_name_or_id, name_or_id="", human: bool = False): + db_conf = configuration.get_configuration(key='management') + manager_api_key = connect_from_env() + policy_id = list(policy.PoliciesCLI.list(policy_name_or_id).get("policies").keys())[0] + _assignments_req = requests.get("{}/policies/{}/subject_assignments".format( + db_conf.get("url"), policy_id), + headers={"x-api-key": manager_api_key} + ) + _assignment_key = None + if _assignments_req.status_code == 200: + _subject_assignments = _assignments_req.json().get("subject_assignments") + if name_or_id: + _assignments = None + if name_or_id in _subject_assignments: + _assignments = _subject_assignments.get(name_or_id) + _assignment_key = name_or_id + else: + for _key in _subject_assignments: + try: + _subject = perimeter.SubjectsCLI.list(name_or_id).get("subjects")[0] + _subject_key = list(_subject.keys())[0] + except Exception as e: + # FIXME: should upgrade this exception + LOGGER.exception(e) + continue + else: + if _subject_assignments.get(_key).get("subject_id") == _subject_key: + _assignments = _subject_assignments.get(_key) + _assignment_key = _key + break + if not _assignments: + raise Exception("Cannot find Subject Assignments with ID {}".format(name_or_id)) + result = {"subject_assignments": [{_assignment_key: _assignments}]} + else: + result = _assignments_req.json() + + if human: + return SubjectAssignmentsCLI.human_display(result) + else: + return result + LOGGER.error('Cannot list Subject Assignments {}'.format(_assignments_req.status_code)) + + @staticmethod + @hug.object.cli + def add(policy_name_or_id, perimeter_name_or_id, category_name_or_id, data_name_or_id, human: bool = False): + """ + Add subject assignment in database + :return: JSON status output + """ + db_conf = configuration.get_configuration(key='management') + manager_api_key = connect_from_env() + policy_id = list(policy.PoliciesCLI.list(policy_name_or_id).get("policies").keys())[0] + perimeter_id = list(perimeter.SubjectsCLI.list(perimeter_name_or_id).get("subjects")[0].keys())[0] + category_id = list(meta_data.SubjectCategoriesCLI.list(category_name_or_id).get("subject_categories").keys())[0] + data_id = data.SubjectDataCLI.list(policy_id, data_name_or_id).get("subject_data").get("id") + _url = "{}/policies/{}/subject_assignments".format(db_conf.get("url"), policy_id) + + _assignments = requests.post( + _url, + json={ + "id": perimeter_id, + "category_id": category_id, + "data_id": data_id, + }, + headers={ + "x-api-key": manager_api_key, + "Content-Type": "application/json" + } + ) + if _assignments.status_code == 200: + LOGGER.warning('Create {}'.format(_assignments.content)) + if human: + return SubjectAssignmentsCLI.human_display(_assignments.json()) + else: + return _assignments.json() + LOGGER.error('Cannot create assignment for {}/{}/{} ({})'.format( + perimeter_name_or_id, category_name_or_id, data_name_or_id, _assignments.content[:40])) + LOGGER.error("{}/{}/{}".format(perimeter_id, category_id, data_id)) + + @staticmethod + @hug.object.cli + def delete(policy_name_or_id, perimeter_name_or_id, category_name_or_id, data_name_or_id): + db_conf = configuration.get_configuration(key='management') + manager_api_key = connect_from_env() + policy_id = list(policy.PoliciesCLI.list(policy_name_or_id).get("policies").keys())[0] + perimeter_id = list(perimeter.SubjectsCLI.list(perimeter_name_or_id).get("subjects")[0].keys())[0] + category_id = list(meta_data.SubjectCategoriesCLI.list(category_name_or_id).get("subject_categories").keys())[0] + data_id = data.SubjectDataCLI.list(policy_id, data_name_or_id).get("subject_data").get("id") + _url = "{}/policies/{}/subject_assignments/{}/{}/{}".format( + db_conf.get("url"), + policy_id, + perimeter_id, + category_id, + data_id) + req = requests.delete( + _url, + headers={"x-api-key": manager_api_key} + ) + if req.status_code == 200: + LOGGER.warning('Deleted {}-{}-{}-{}'.format( + policy_name_or_id, perimeter_name_or_id, category_name_or_id, data_name_or_id)) + return True + LOGGER.error("Cannot delete Assignment with {}-{}-{}-{}".format( + policy_name_or_id, perimeter_name_or_id, category_name_or_id, data_name_or_id + )) + return False + + @staticmethod + def human_display(subject_assigment_json): + human_result = "Subject Assignments" + for subject_assignment in subject_assigment_json.get("subject_assignments"): + human_result += "\n" + subject_assigment_json.get("subject_assignments").get(subject_assignment).get("id") + "\n" + human_result += "\tid : " + subject_assigment_json.get("subject_assignments").get(subject_assignment).get("id") + "\n" + human_result += "\tpolicy_id : " + subject_assigment_json.get("subject_assignments").get(subject_assignment).get("policy_id") + "\n" + human_result += "\tsubject_id : " + subject_assigment_json.get("subject_assignments").get(subject_assignment).get("subject_id") + "\n" + human_result += "\tcategory_id : " + subject_assigment_json.get("subject_assignments").get(subject_assignment).get("category_id") + "\n" + human_result += "\tassignments : \n" + for assignment in subject_assigment_json.get("subject_assignments").get(subject_assignment).get("assignments"): + human_result += "\t\t" + assignment + "\n" + return human_result + + +@hug.object(name='objects', version='1.0.0', api=ObjectAssignmentsAPI) +class ObjectAssignmentsCLI(object): + """An example of command like calls via an Object""" + + @staticmethod + @hug.object.cli + def list(policy_name_or_id, name_or_id="", human: bool = False): + db_conf = configuration.get_configuration(key='management') + manager_api_key = connect_from_env() + policy_id = list(policy.PoliciesCLI.list(policy_name_or_id).get("policies").keys())[0] + _assignments_req = requests.get("{}/policies/{}/object_assignments".format( + db_conf.get("url"), policy_id), + headers={"x-api-key": manager_api_key} + ) + _assignment_key = None + if _assignments_req.status_code == 200: + _object_assignments = _assignments_req.json().get("object_assignments") + if name_or_id: + _assignments = None + if name_or_id in _object_assignments: + _assignments = _object_assignments.get(name_or_id) + _assignment_key = name_or_id + else: + for _key in _object_assignments: + try: + _object = perimeter.ObjectsCLI.list(name_or_id).get("objects")[0] + _object_key = list(_object.keys())[0] + except Exception as e: + # FIXME: should upgrade this exception + LOGGER.exception(e) + continue + else: + if _object_assignments.get(_key).get("object_id") == _object_key: + _assignments = _object_assignments.get(_key) + _assignment_key = _key + break + if not _assignments: + raise Exception("Cannot find Object Assignments with ID {}".format(name_or_id)) + result = {"object_assignments": [{_assignment_key: _assignments}]} + else: + result = _assignments_req.json() + + if human: + return ObjectAssignmentsCLI.human_display(result) + else: + return result + LOGGER.error('Cannot list Object Assignments {}'.format(_assignments_req.status_code)) + + @staticmethod + @hug.object.cli + def add(policy_name_or_id, perimeter_name_or_id, category_name_or_id, data_name_or_id, human: bool = False): + """ + Add object assignment in database + :return: JSON status output + """ + db_conf = configuration.get_configuration(key='management') + manager_api_key = connect_from_env() + policy_id = list(policy.PoliciesCLI.list(policy_name_or_id).get("policies").keys())[0] + perimeter_id = list(perimeter.ObjectsCLI.list(perimeter_name_or_id).get("objects")[0].keys())[0] + category_id = list(meta_data.ObjectCategoriesCLI.list(category_name_or_id).get("object_categories").keys())[0] + data_id = data.ObjectDataCLI.list(policy_id, data_name_or_id).get("object_data").get("id") + _url = "{}/policies/{}/object_assignments".format(db_conf.get("url"), policy_id) + + _assignments = requests.post( + _url, + json={ + "id": perimeter_id, + "category_id": category_id, + "data_id": data_id, + }, + headers={ + "x-api-key": manager_api_key, + "Content-Type": "application/json" + } + ) + if _assignments.status_code == 200: + LOGGER.warning('Create {}'.format(_assignments.content)) + if human: + return ObjectAssignmentsCLI.human_display(_assignments.json()) + else: + return _assignments.json() + LOGGER.error('Cannot create assignment for {}/{}/{} ({})'.format( + perimeter_name_or_id, category_name_or_id, data_name_or_id, _assignments.content[:40])) + LOGGER.error("{}/{}/{}".format(perimeter_id, category_id, data_id)) + + @staticmethod + @hug.object.cli + def delete(policy_name_or_id, perimeter_name_or_id, category_name_or_id, data_name_or_id): + db_conf = configuration.get_configuration(key='management') + manager_api_key = connect_from_env() + policy_id = list(policy.PoliciesCLI.list(policy_name_or_id).get("policies").keys())[0] + perimeter_id = list(perimeter.ObjectsCLI.list(perimeter_name_or_id).get("objects")[0].keys())[0] + category_id = list(meta_data.ObjectCategoriesCLI.list(category_name_or_id).get("object_categories").keys())[0] + data_id = data.ObjectDataCLI.list(policy_id, data_name_or_id).get("object_data").get("id") + _url = "{}/policies/{}/object_assignments/{}/{}/{}".format( + db_conf.get("url"), + policy_id, + perimeter_id, + category_id, + data_id) + req = requests.delete( + _url, + headers={"x-api-key": manager_api_key} + ) + if req.status_code == 200: + LOGGER.warning('Deleted {}-{}-{}-{}'.format( + policy_name_or_id, perimeter_name_or_id, category_name_or_id, data_name_or_id)) + return True + LOGGER.error("Cannot delete Assignment with {}-{}-{}-{}".format( + policy_name_or_id, perimeter_name_or_id, category_name_or_id, data_name_or_id + )) + return False + + @staticmethod + def human_display(object_assigment_json): + human_result = "Object Assignments" + for object_assignment in object_assigment_json.get("object_assignments"): + human_result += "\n" + object_assigment_json.get("object_assignments").get(object_assignment).get("id") + "\n" + human_result += "\tid : " + object_assigment_json.get("object_assignments").get(object_assignment).get("id") + "\n" + human_result += "\tpolicy_id : " + object_assigment_json.get("object_assignments").get(object_assignment).get("policy_id") + "\n" + human_result += "\tobject_id : " + object_assigment_json.get("object_assignments").get(object_assignment).get("object_id") + "\n" + human_result += "\tcategory_id : " + object_assigment_json.get("object_assignments").get(object_assignment).get("category_id") + "\n" + human_result += "\tassignments : \n" + for assignment in object_assigment_json.get("object_assignments").get(object_assignment).get("assignments"): + human_result += "\t\t" + assignment + "\n" + return human_result + + +@hug.object(name='actions', version='1.0.0', api=ActionAssignmentsAPI) +class ActionAssignmentsCLI(object): + """An example of command like calls via an Action""" + + @staticmethod + @hug.object.cli + def list(policy_name_or_id, name_or_id="", human: bool = False): + db_conf = configuration.get_configuration(key='management') + manager_api_key = connect_from_env() + policy_id = list(policy.PoliciesCLI.list(policy_name_or_id).get("policies").keys())[0] + _assignments_req = requests.get("{}/policies/{}/action_assignments".format( + db_conf.get("url"), policy_id), + headers={"x-api-key": manager_api_key} + ) + _assignment_key = None + if _assignments_req.status_code == 200: + _action_assignments = _assignments_req.json().get("action_assignments") + if name_or_id: + _assignments = None + if name_or_id in _action_assignments: + _assignments = _action_assignments.get(name_or_id) + _assignment_key = name_or_id + else: + for _key in _action_assignments: + try: + _action = perimeter.ActionsCLI.list(name_or_id).get("actions")[0] + _action_key = list(_action.keys())[0] + except Exception as e: + # FIXME: should upgrade this exception + LOGGER.exception(e) + continue + else: + if _action_assignments.get(_key).get("action_id") == _action_key: + _assignments = _action_assignments.get(_key) + _assignment_key = _key + break + if not _assignments: + raise Exception("Cannot find Action Assignments with ID {}".format(name_or_id)) + result = {"action_assignments": [{_assignment_key: _assignments}]} + else: + result = _assignments_req.json() + + if human: + return ActionAssignmentsCLI.human_display(result) + else: + return result + LOGGER.error('Cannot list Action Assignments {}'.format(_assignments_req.status_code)) + + @staticmethod + @hug.object.cli + def add(policy_name_or_id, perimeter_name_or_id, category_name_or_id, data_name_or_id, human: bool = False): + """ + Add action assignment in database + :return: JSON status output + """ + db_conf = configuration.get_configuration(key='management') + manager_api_key = connect_from_env() + policy_id = list(policy.PoliciesCLI.list(policy_name_or_id).get("policies").keys())[0] + perimeter_id = list(perimeter.ActionsCLI.list(perimeter_name_or_id).get("actions")[0].keys())[0] + category_id = list(meta_data.ActionCategoriesCLI.list(category_name_or_id).get("action_categories").keys())[0] + data_id = data.ActionDataCLI.list(policy_id, data_name_or_id).get("action_data").get("id") + _url = "{}/policies/{}/action_assignments".format(db_conf.get("url"), policy_id) + + _assignments = requests.post( + _url, + json={ + "id": perimeter_id, + "category_id": category_id, + "data_id": data_id, + }, + headers={ + "x-api-key": manager_api_key, + "Content-Type": "application/json" + } + ) + if _assignments.status_code == 200: + LOGGER.warning('Create {}'.format(_assignments.content)) + if human: + return ActionAssignmentsCLI.human_display(_assignments.json()) + else: + return _assignments.json() + LOGGER.error('Cannot create assignment for {}/{}/{} ({})'.format( + perimeter_name_or_id, category_name_or_id, data_name_or_id, _assignments.content[:40])) + LOGGER.error("{}/{}/{}".format(perimeter_id, category_id, data_id)) + + @staticmethod + @hug.object.cli + def delete(policy_name_or_id, perimeter_name_or_id, category_name_or_id, data_name_or_id): + db_conf = configuration.get_configuration(key='management') + manager_api_key = connect_from_env() + policy_id = list(policy.PoliciesCLI.list(policy_name_or_id).get("policies").keys())[0] + perimeter_id = list(perimeter.ActionsCLI.list(perimeter_name_or_id).get("actions")[0].keys())[0] + category_id = list(meta_data.ActionCategoriesCLI.list(category_name_or_id).get("action_categories").keys())[0] + data_id = data.ActionDataCLI.list(policy_id, data_name_or_id).get("action_data").get("id") + _url = "{}/policies/{}/action_assignments/{}/{}/{}".format( + db_conf.get("url"), + policy_id, + perimeter_id, + category_id, + data_id) + req = requests.delete( + _url, + headers={"x-api-key": manager_api_key} + ) + if req.status_code == 200: + LOGGER.warning('Deleted {}-{}-{}-{}'.format( + policy_name_or_id, perimeter_name_or_id, category_name_or_id, data_name_or_id)) + return True + LOGGER.error("Cannot delete Assignment with {}-{}-{}-{}".format( + policy_name_or_id, perimeter_name_or_id, category_name_or_id, data_name_or_id + )) + return False + + @staticmethod + def human_display(action_assigment_json): + human_result = "Action Assignments" + for action_assignment in action_assigment_json.get("action_assignments"): + human_result += "\n" + action_assigment_json.get("action_assignments").get(action_assignment).get("id") + "\n" + human_result += "\tid : " + action_assigment_json.get("action_assignments").get(action_assignment).get("id") + "\n" + human_result += "\tpolicy_id : " + action_assigment_json.get("action_assignments").get(action_assignment).get("policy_id") + "\n" + human_result += "\taction_id : " + action_assigment_json.get("action_assignments").get(action_assignment).get("action_id") + "\n" + human_result += "\tcategory_id : " + action_assigment_json.get("action_assignments").get(action_assignment).get("category_id") + "\n" + human_result += "\tassignments : \n" + for assignment in action_assigment_json.get("action_assignments").get(action_assignment).get("assignments"): + human_result += "\t\t" + assignment + "\n" + return human_result |