From 7343cf25ad890e18b2f5b8d35c6acfc821dfd5ec Mon Sep 17 00:00:00 2001 From: "francois.cellier" Date: Tue, 27 Feb 2018 13:51:25 +0100 Subject: Add import and export pdps Change-Id: I2c9b1f2b86af862887df4b890cd8b11db7c308ee --- python_moonclient/Changelog | 15 ++ python_moonclient/python_moonclient/__init__.py | 2 +- python_moonclient/python_moonclient/cli/export.py | 32 ++++ python_moonclient/python_moonclient/cli/import.py | 29 ++++ python_moonclient/python_moonclient/cli/models.py | 161 +++++++++++++++++++++ python_moonclient/python_moonclient/cli/parser.py | 12 ++ .../python_moonclient/cli/policies.py | 161 ++++++++++++++++++++- .../python_moonclient/core/json_export.py | 26 ++++ .../python_moonclient/core/json_import.py | 29 ++++ python_moonclient/python_moonclient/core/models.py | 20 ++- .../python_moonclient/core/policies.py | 23 ++- python_moonclient/python_moonclient/moon.py | 13 ++ python_moonclient/setup.py | 14 +- 13 files changed, 523 insertions(+), 14 deletions(-) create mode 100644 python_moonclient/python_moonclient/cli/export.py create mode 100644 python_moonclient/python_moonclient/cli/import.py create mode 100644 python_moonclient/python_moonclient/cli/models.py create mode 100644 python_moonclient/python_moonclient/core/json_export.py create mode 100644 python_moonclient/python_moonclient/core/json_import.py (limited to 'python_moonclient') diff --git a/python_moonclient/Changelog b/python_moonclient/Changelog index 927663ec..9a2971cb 100644 --- a/python_moonclient/Changelog +++ b/python_moonclient/Changelog @@ -53,3 +53,18 @@ CHANGES - moon slave delete - moon slave list - moon slave set + +1.4.0 +----- +- Add some commands: + - moon import + - moon export + - moon subject category create + - moon subject category list + - moon object category list + - moon action category list + - moon subject data create + - moon subject data list + - moon object data list + - moon action data list + - moon metarule list diff --git a/python_moonclient/python_moonclient/__init__.py b/python_moonclient/python_moonclient/__init__.py index 6e5782ce..8b353f9f 100644 --- a/python_moonclient/python_moonclient/__init__.py +++ b/python_moonclient/python_moonclient/__init__.py @@ -3,4 +3,4 @@ # license which can be found in the file 'LICENSE' in this package distribution # or at 'http://www.apache.org/licenses/LICENSE-2.0'. -__version__ = "1.3.0" +__version__ = "1.4.0" diff --git a/python_moonclient/python_moonclient/cli/export.py b/python_moonclient/python_moonclient/cli/export.py new file mode 100644 index 00000000..a16928de --- /dev/null +++ b/python_moonclient/python_moonclient/cli/export.py @@ -0,0 +1,32 @@ +import json + +from python_moonclient.core import models, policies, pdp, json_export +from python_moonclient.cli.parser import Parser + +from cliff.command import Command + + +class Export(Command): + """dump the complete moon database into a json file""" + def get_parser(self, prog_name): + parser = super().get_parser(prog_name) + Parser.add_filename_argument(parser) + Parser.add_common_options(parser) + return parser + + def take_action(self, parsed_args): + consul_host = parsed_args.consul_host + consul_port = parsed_args.consul_port + + models.init(consul_host, consul_port) + policies.init(consul_host, consul_port) + pdp.init(consul_host, consul_port) + json_export.init(consul_host, consul_port) + res = json_export.export_to_json() + if "content" in res: + json_file = open(parsed_args.filename, "w") + json.dump(res["content"], json_file) + return "Export ok!" + else: + return "Unexpected results : the returned json does not have the correct syntax" + diff --git a/python_moonclient/python_moonclient/cli/import.py b/python_moonclient/python_moonclient/cli/import.py new file mode 100644 index 00000000..c6c43439 --- /dev/null +++ b/python_moonclient/python_moonclient/cli/import.py @@ -0,0 +1,29 @@ + +from python_moonclient.core import models, policies, pdp, json_import +from python_moonclient.cli.parser import Parser +from python_moonclient.cli.projects import ProjectsUtils + +from cliff.command import Command + + +class Import(Command): + """import a json file describing pdps """ + def get_parser(self, prog_name): + parser = super().get_parser(prog_name) + Parser.add_common_options(parser) + Parser.add_filename_argument(parser) + return parser + + def take_action(self, parsed_args): + consul_host = parsed_args.consul_host + consul_port = parsed_args.consul_port + + models.init(consul_host, consul_port) + policies.init(consul_host, consul_port) + pdp.init(consul_host, consul_port) + json_import.init(consul_host, consul_port) + res = json_import.import_json(parsed_args.filename) + if "message" in res: + return res["message"] + return res + diff --git a/python_moonclient/python_moonclient/cli/models.py b/python_moonclient/python_moonclient/cli/models.py new file mode 100644 index 00000000..922a1830 --- /dev/null +++ b/python_moonclient/python_moonclient/cli/models.py @@ -0,0 +1,161 @@ +import logging +from cliff.lister import Lister +from cliff.command import Command +from importlib.machinery import SourceFileLoader + +from python_moonclient.core import models, policies, pdp +from python_moonclient.cli.parser import Parser +from python_moonclient.cli.projects import ProjectsUtils + +logger = logging.getLogger("moonclient.cli.pdps") + + +class ModelUtils: + def __init__(self): + pass + + @staticmethod + def get_model_id(model, parsed_id, parsed_name): + modelz = models.check_model() + for _model_key, _model_value in modelz["models"].items(): + if _model_key == parsed_id or _model_value['name'] == parsed_name: + # logger.info("Found pdp : [key='{}' , name='{}']".format(_pdp_key, _pdp_value['name'])) + return _model_key + return None + + @staticmethod + def get_model_name(pdp, parsed_id, parsed_name): + modelz = models.check_model() + for _model_key, _model_value in modelz["models"].items(): + if _model_key == parsed_id or _model_value['name'] == parsed_name: + # logger.info("Found pdp : [key='{}' , name='{}']".format(_pdp_key, _pdp_value['name'])) + return _model_value['name'] + return None + + +class Models(Lister): + """show the list of existing pdps """ + + def get_parser(self, prog_name): + parser = super().get_parser(prog_name) + Parser.add_common_options(parser) + return parser + + def take_action(self, parsed_args): + consul_host = parsed_args.consul_host + consul_port = parsed_args.consul_port + + models.init(consul_host, consul_port) + policies.init(consul_host, consul_port) + pdp.init(consul_host, consul_port) + + modelz = models.check_model() + + return (('Key', 'Name'), + ((_model_key, _model_value['name']) for _model_key, _model_value in + modelz["models"].items()) + ) + + +class SubjectCategories(Lister): + """show the list of existing categories """ + + def get_parser(self, prog_name): + parser = super().get_parser(prog_name) + Parser.add_common_options(parser) + + return parser + + def take_action(self, parsed_args): + consul_host = parsed_args.consul_host + consul_port = parsed_args.consul_port + + models.init(consul_host, consul_port) + policies.init(consul_host, consul_port) + pdp.init(consul_host, consul_port) + + subject_categories = models.check_subject_category() + print(subject_categories) + return (('Key', 'Name'), + ((_model_key, _model_value['name']) for _model_key, _model_value in + subject_categories["subject_categories"].items()) + ) + + +class ObjectCategories(Lister): + """show the list of existing categories """ + + def get_parser(self, prog_name): + parser = super().get_parser(prog_name) + Parser.add_common_options(parser) + + return parser + + def take_action(self, parsed_args): + consul_host = parsed_args.consul_host + consul_port = parsed_args.consul_port + + models.init(consul_host, consul_port) + policies.init(consul_host, consul_port) + pdp.init(consul_host, consul_port) + + object_categories = models.check_object_category() + print(object_categories) + return (('Key', 'Name'), + ((_model_key, _model_value['name']) for _model_key, _model_value in + object_categories["object_categories"].items()) + ) + + +class ActionCategories(Lister): + """show the list of existing categories """ + + def get_parser(self, prog_name): + parser = super().get_parser(prog_name) + Parser.add_common_options(parser) + + return parser + + def take_action(self, parsed_args): + consul_host = parsed_args.consul_host + consul_port = parsed_args.consul_port + + models.init(consul_host, consul_port) + policies.init(consul_host, consul_port) + pdp.init(consul_host, consul_port) + + action_categories = models.check_action_category() + print(action_categories) + return (('Key', 'Name'), + ((_model_key, _model_value['name']) for _model_key, _model_value in + action_categories["action_categories"].items()) + ) + + +class SubjectCategoryAdd(Command): + """show the list of existing categories """ + + def get_parser(self, prog_name): + parser = super().get_parser(prog_name) + Parser.add_common_options(parser) + Parser.add_name_argument(parser) + + return parser + + def take_action(self, parsed_args): + consul_host = parsed_args.consul_host + consul_port = parsed_args.consul_port + + models.init(consul_host, consul_port) + policies.init(consul_host, consul_port) + pdp.init(consul_host, consul_port) + + subject_category_id = models.add_subject_category(parsed_args.name) + if subject_category_id is not None: + print("Subject category created with id {}".format(subject_category_id)) + else: + print("Error while creating subject category") + # subject_categories = models.check_subject_category(subject_category_id) + + + diff --git a/python_moonclient/python_moonclient/cli/parser.py b/python_moonclient/python_moonclient/cli/parser.py index f32a5484..edd18a25 100644 --- a/python_moonclient/python_moonclient/cli/parser.py +++ b/python_moonclient/python_moonclient/cli/parser.py @@ -16,6 +16,18 @@ class Parser: def add_name_argument(parser): Parser._add_name_argument(parser) + @staticmethod + def add_policy_argument(parser): + group = parser.add_mutually_exclusive_group(required=True) + group.add_argument('--policy-name', help='name of the policy') + group.add_argument('--policy-id', help='id of the policy') + + @staticmethod + def add_category_argument(parser): + group = parser.add_mutually_exclusive_group(required=True) + group.add_argument('--category-name', help='name of the category') + group.add_argument('--category-id', help='id of the category') + @staticmethod def add_id_or_name_argument(parser): group = parser.add_mutually_exclusive_group(required=True) diff --git a/python_moonclient/python_moonclient/cli/policies.py b/python_moonclient/python_moonclient/cli/policies.py index a528ea8d..94d13db1 100644 --- a/python_moonclient/python_moonclient/cli/policies.py +++ b/python_moonclient/python_moonclient/cli/policies.py @@ -31,7 +31,6 @@ class PoliciesUtils: return _policy_value['name'] return None - class Policies(Lister): """show the list of existing policies""" def get_parser(self, prog_name): @@ -53,6 +52,30 @@ class Policies(Lister): ) +class Subjects(Lister): + def get_parser(self, prog_name): + parser = super().get_parser(prog_name) + Parser.add_common_options(parser) + Parser.add_id_or_name_argument(parser) + Parser.add_policy_argument(parser) + return parser + + def take_action(self, parsed_args): + consul_host = parsed_args.consul_host + consul_port = parsed_args.consul_port + + models.init(consul_host, consul_port) + policies.init(consul_host, consul_port) + pdp.init(consul_host, consul_port) + + _policies = policies.check_subject(parsed_args.id, parsed_args.policy_id) + + return (('Key' , 'Name'), + ((_policy_key, _policy_value['name']) for _policy_key, _policy_value in _policies["policies"].items()) + ) + + + class DeletePolicy(Command): """delete an existing policy""" def get_parser(self, prog_name): @@ -85,3 +108,139 @@ class DeletePolicy(Command): return (('Key', 'Value'), ((_policy_key, _policy_value) for _policy_key, _policy_value in _policies["policies"].items()) ) + + + +class SubjectDatas(Lister): + """list the subject data """ + def get_parser(self, prog_name): + parser = super().get_parser(prog_name) + Parser.add_common_options(parser) + Parser.add_policy_argument(parser) + Parser.add_category_argument(parser) + return parser + + def take_action(self, parsed_args): + consul_host = parsed_args.consul_host + consul_port = parsed_args.consul_port + + models.init(consul_host, consul_port) + policies.init(consul_host, consul_port) + pdp.init(consul_host, consul_port) + + subject_data = policies.check_subject_data(parsed_args.policy_id, None, parsed_args.category_id) + if len(subject_data["subject_data"]) == 0: + return (('Key', 'Name'),()) + + return (('Key', 'Name'), + ((_subject_key, subject_data["subject_data"][0]["data"][_subject_key]['name']) for _subject_key in subject_data["subject_data"][0]["data"].keys()) + ) + + +class ObjectDatas(Lister): + """list the object data""" + def get_parser(self, prog_name): + parser = super().get_parser(prog_name) + Parser.add_common_options(parser) + Parser.add_policy_argument(parser) + Parser.add_category_argument(parser) + return parser + + def take_action(self, parsed_args): + consul_host = parsed_args.consul_host + consul_port = parsed_args.consul_port + + models.init(consul_host, consul_port) + policies.init(consul_host, consul_port) + pdp.init(consul_host, consul_port) + + object_datas = policies.check_object_data(parsed_args.policy_id, None, parsed_args.category_id) + + if len(object_datas["object_data"]) == 0: + return (('Key', 'Name'),()) + object_data = object_datas["object_data"][0]["data"] + res = (('Key', 'Name'), + ((_object_key, object_data[_object_key]["value"]['name']) for _object_key in list(object_data)) + ) + return res + + +class ActionDatas(Lister): + """list the action data""" + def get_parser(self, prog_name): + parser = super().get_parser(prog_name) + Parser.add_common_options(parser) + Parser.add_policy_argument(parser) + Parser.add_category_argument(parser) + return parser + + def take_action(self, parsed_args): + consul_host = parsed_args.consul_host + consul_port = parsed_args.consul_port + + models.init(consul_host, consul_port) + policies.init(consul_host, consul_port) + pdp.init(consul_host, consul_port) + + action_datas = policies.check_action_data(parsed_args.policy_id, None, parsed_args.category_id) + + if len(action_datas["action_data"]) == 0: + return (('Key', 'Name'),()) + action_data = action_datas["action_data"][0]["data"] + res = (('Key', 'Name'), + ((_action_key, action_data[_action_key]["value"]['name']) for _action_key in list(action_data)) + ) + return res + + +class MetaRules(Lister): + """list the meta rules""" + def get_parser(self, prog_name): + parser = super().get_parser(prog_name) + Parser.add_common_options(parser) + return parser + + def take_action(self, parsed_args): + consul_host = parsed_args.consul_host + consul_port = parsed_args.consul_port + + models.init(consul_host, consul_port) + policies.init(consul_host, consul_port) + pdp.init(consul_host, consul_port) + + metarule_datas = policies.check_meta_rule() + + if len(metarule_datas["meta_rules"]) == 0: + return (('Key', 'Name'),()) + + metarule_data = metarule_datas["meta_rules"] + res = (('Key', 'Name'), + ((_key, metarule_data[_key]['name']) for _key in list(metarule_data)) + ) + return res + +class CreateSubjectData(Command): + """create a subject data according to a policy and a category""" + def get_parser(self, prog_name): + parser = super().get_parser(prog_name) + Parser.add_common_options(parser) + Parser.add_policy_argument(parser) + Parser.add_category_argument(parser) + Parser.add_name_argument(parser) + return parser + + def take_action(self, parsed_args): + consul_host = parsed_args.consul_host + consul_port = parsed_args.consul_port + + models.init(consul_host, consul_port) + policies.init(consul_host, consul_port) + pdp.init(consul_host, consul_port) + + subject_data_id = policies.add_subject_data(parsed_args.policy_id, parsed_args.category_id, parsed_args.name) + if subject_data_id is not None: + print("Subject category created with id {}".format(subject_data_id)) + else: + print("Error while creating subject category") + subject_data = policies.check_subject_data(parsed_args.policy_id, None, parsed_args.category_id) + # subject_categories = models.check_subject_category(subject_category_id) diff --git a/python_moonclient/python_moonclient/core/json_export.py b/python_moonclient/python_moonclient/core/json_export.py new file mode 100644 index 00000000..53c1b1f0 --- /dev/null +++ b/python_moonclient/python_moonclient/core/json_export.py @@ -0,0 +1,26 @@ +import logging +import requests +import copy +from python_moonclient.core import config + + +logger = logging.getLogger("moonclient.core.export_json") + +URL = None +HEADERS = None + +def init(consul_host, consul_port): + conf_data = config.get_config_data(consul_host, consul_port) + global URL, HEADERS + URL = "http://{}:{}".format( + conf_data['manager_host'], + conf_data['manager_port']) + URL = URL + "{}" + HEADERS = {"content-type": "application/json"} + + +def export_to_json(): + req = requests.get(URL.format("/export")) + req.raise_for_status() + result = req.json() + return result \ No newline at end of file diff --git a/python_moonclient/python_moonclient/core/json_import.py b/python_moonclient/python_moonclient/core/json_import.py new file mode 100644 index 00000000..a724476b --- /dev/null +++ b/python_moonclient/python_moonclient/core/json_import.py @@ -0,0 +1,29 @@ +import logging +import requests +import copy +from python_moonclient.core import config + + +logger = logging.getLogger("moonclient.core.import_json") + +URL = None +HEADERS = None + +def init(consul_host, consul_port): + conf_data = config.get_config_data(consul_host, consul_port) + global URL, HEADERS + URL = "http://{}:{}".format( + conf_data['manager_host'], + conf_data['manager_port']) + URL = URL + "{}" + HEADERS = {"content-type": "application/json"} + + +def import_json(file_name): + files = {'file': open(file_name, 'rb')} + req = requests.post(URL.format("/import"), files=files) + result = req.json() + if isinstance(result,dict) and "message" in result: + req.reason = result["message"] + req.raise_for_status() + return result \ No newline at end of file diff --git a/python_moonclient/python_moonclient/core/models.py b/python_moonclient/python_moonclient/core/models.py index ba6c9a92..709b4a7a 100644 --- a/python_moonclient/python_moonclient/core/models.py +++ b/python_moonclient/python_moonclient/core/models.py @@ -81,14 +81,16 @@ def add_subject_category(name="subject_cat_1"): return category_id -def check_subject_category(category_id): +def check_subject_category(category_id=None): req = requests.get(URL.format("/subject_categories")) req.raise_for_status() result = req.json() check_subject_category_in_result(result) check_optionnal_result(result) - check_subject_categories_name(category_template["name"], category_id, result) + if category_id is not None: + check_subject_categories_name(category_template["name"], category_id, result) + return result def delete_subject_category(category_id): @@ -110,13 +112,15 @@ def add_object_category(name="object_cat_1"): return category_id -def check_object_category(category_id): +def check_object_category(category_id=None): req = requests.get(URL.format("/object_categories")) req.raise_for_status() result = req.json() check_object_category_in_result(result) check_optionnal_result(result) - check_object_categories_name(category_template["name"], category_id, result) + if category_id is not None: + check_object_categories_name(category_template["name"], category_id, result) + return result def delete_object_category(category_id): @@ -138,13 +142,16 @@ def add_action_category(name="action_cat_1"): return category_id -def check_action_category(category_id): +def check_action_category(category_id=None): req = requests.get(URL.format("/action_categories")) req.raise_for_status() result = req.json() + print(result) check_action_category_in_result(result) check_optionnal_result(result) - check_action_categories_name(category_template["name"], category_id, result) + if category_id is not None: + check_action_categories_name(category_template["name"], category_id, result) + return result def delete_action_category(category_id): @@ -207,6 +214,7 @@ def check_meta_rule(meta_rule_id, scat_id=None, ocat_id=None, acat_id=None): check_ocat_id_in_dict(ocat_id, result['meta_rules'][meta_rule_id]["object_categories"]) if acat_id: check_acat_id_in_dict(acat_id, result['meta_rules'][meta_rule_id]["action_categories"]) + return result def delete_meta_rule(meta_rule_id): diff --git a/python_moonclient/python_moonclient/core/policies.py b/python_moonclient/python_moonclient/core/policies.py index 01067a98..46d918aa 100644 --- a/python_moonclient/python_moonclient/core/policies.py +++ b/python_moonclient/python_moonclient/core/policies.py @@ -302,8 +302,11 @@ def check_subject_data(policy_id, data_id, category_id): req = requests.get(URL.format("/policies/{}/subject_data/{}".format(policy_id, category_id))) req.raise_for_status() result = req.json() - check_id_in_subject_data_data(data_id, result) + print(result) + if data_id is not None: + check_id_in_subject_data_data(data_id, result) check_category_id_in_subject_data_data(category_id, result) + return result def delete_subject_data(policy_id, category_id, data_id): @@ -332,9 +335,10 @@ def check_object_data(policy_id, data_id, category_id): req = requests.get(URL.format("/policies/{}/object_data/{}".format(policy_id, category_id))) req.raise_for_status() result = req.json() - check_id_in_object_data_data(data_id, result) + if data_id is not None: + check_id_in_object_data_data(data_id, result) check_category_id_in_object_data_data(category_id, result) - + return result def delete_object_data(policy_id, category_id, data_id): req = requests.delete(URL.format("/policies/{}/object_data/{}/{}".format(policy_id, category_id, data_id)), @@ -362,9 +366,11 @@ def check_action_data(policy_id, data_id, category_id): req = requests.get(URL.format("/policies/{}/action_data/{}".format(policy_id, category_id))) req.raise_for_status() result = req.json() - check_id_in_action_data_data(data_id, result) + print(result) + if data_id is not None: + check_id_in_action_data_data(data_id, result) check_category_id_in_action_data_data(category_id, result) - + return result def delete_action_data(policy_id, category_id, data_id): req = requests.delete(URL.format("/policies/{}/action_data/{}/{}".format(policy_id, category_id, data_id)), @@ -526,6 +532,13 @@ def delete_rule(policy_id, rule_id): check_rule_id_not_in_list(rule_id, result["rules"]["rules"]) +def check_meta_rule(): + req = requests.get(URL.format("/meta_rules/")) + req.raise_for_status() + result = req.json() + print(result) + return result + def create_policy(scenario, model_id, meta_rule_list): logger.info("Creating policy {}".format(scenario.policy_name)) _policies = check_policy() diff --git a/python_moonclient/python_moonclient/moon.py b/python_moonclient/python_moonclient/moon.py index cbf62681..f8cf027d 100644 --- a/python_moonclient/python_moonclient/moon.py +++ b/python_moonclient/python_moonclient/moon.py @@ -22,6 +22,19 @@ def main(argv=sys.argv[1:]): if __name__ == '__main__': + #import python_moonclient.python_moonclient.core.import_json + #import python_moonclient.python_moonclient.core.models + #import python_moonclient.core.policies.init as init_policy + #import python_moonclient.core.pdp.init as init_pdp + #consul_host = "consul" + #consul_port = "8005" + + #init_model(consul_host, consul_port) + #init_policy.init(consul_host, consul_port) + #init_pdp.init(consul_host, consul_port) + #import_json('/home/fcellier/moon/tests/functional/scenario_available/rbac.json') + + sys.exit(Moon(sys.argv[1:])) diff --git a/python_moonclient/setup.py b/python_moonclient/setup.py index 847f62e7..4a3a8233 100644 --- a/python_moonclient/setup.py +++ b/python_moonclient/setup.py @@ -56,7 +56,19 @@ setup( 'slave_list = python_moonclient.cli.slaves:Slaves', 'slave_set = python_moonclient.cli.slaves:SetSlave', 'slave_delete = python_moonclient.cli.slaves:DeleteSlave', - 'authz_send = python_moonclient.cli.authz:SendAuthz' + 'authz_send = python_moonclient.cli.authz:SendAuthz', + 'import = python_moonclient.cli.import:Import', + 'export = python_moonclient.cli.export:Export', + 'model_list = python_moonclient.cli.models:Models', + 'subject_data_list = python_moonclient.cli.policies:SubjectDatas', + 'object_data_list = python_moonclient.cli.policies:ObjectDatas', + 'action_data_list = python_moonclient.cli.policies:ActionDatas', + 'subject_category_list = python_moonclient.cli.models:SubjectCategories', + 'object_category_list = python_moonclient.cli.models:ObjectCategories', + 'action_category_list = python_moonclient.cli.models:ActionCategories', + 'subject_category_create = python_moonclient.cli.models:SubjectCategoryAdd', + 'subject_data_create = python_moonclient.cli.policies:CreateSubjectData', + 'metarule_list = python_moonclient.cli.policies:MetaRules' ], } -- cgit 1.2.3-korg