diff options
-rw-r--r-- | keystone-moon/keystone/contrib/moon/backends/sql.py | 31 | ||||
-rw-r--r-- | keystone-moon/keystone/contrib/moon/core.py | 3 | ||||
-rw-r--r-- | keystone-moon/keystone/contrib/moon/migrate_repo/versions/001_moon.py | 10 | ||||
-rw-r--r-- | moonclient/moonclient/metarules.py | 157 | ||||
-rw-r--r-- | moonclient/moonclient/tests/tests_submetarules.json | 289 | ||||
-rw-r--r-- | moonclient/setup.py | 7 |
6 files changed, 400 insertions, 97 deletions
diff --git a/keystone-moon/keystone/contrib/moon/backends/sql.py b/keystone-moon/keystone/contrib/moon/backends/sql.py index a3418c15..9bc9ee45 100644 --- a/keystone-moon/keystone/contrib/moon/backends/sql.py +++ b/keystone-moon/keystone/contrib/moon/backends/sql.py @@ -15,6 +15,8 @@ from keystone.contrib.moon.exception import * from oslo_serialization import jsonutils from keystone.contrib.moon import IntraExtensionDriver from keystone.contrib.moon import TenantDriver + +from sqlalchemy.orm.exc import UnmappedInstanceError # from keystone.contrib.moon import InterExtensionDriver CONF = config.CONF @@ -256,22 +258,6 @@ class ActionAssignment(sql.ModelBase, sql.DictBase): return dict(six.iteritems(self)) -class AggregationAlgorithm(sql.ModelBase, sql.DictBase): - __tablename__ = 'aggregation_algorithm' - attributes = ['id', 'aggregation_algorithm', 'intra_extension_id'] - id = sql.Column(sql.String(64), primary_key=True) - aggregation_algorithm = sql.Column(sql.JsonBlob(), nullable=True) - intra_extension_id = sql.Column(sql.ForeignKey("intra_extensions.id"), nullable=False) - - @classmethod - def from_dict(cls, d): - new_d = d.copy() - return cls(**new_d) - - def to_dict(self): - return dict(six.iteritems(self)) - - class SubMetaRule(sql.ModelBase, sql.DictBase): __tablename__ = 'sub_meta_rules' attributes = ['id', 'sub_meta_rule', 'intra_extension_id'] @@ -318,7 +304,6 @@ __all_objects__ = ( SubjectAssignment, ObjectAssignment, ActionAssignment, - AggregationAlgorithm, SubMetaRule, Rule, ) @@ -964,10 +949,13 @@ class IntraExtensionConnector(IntraExtensionDriver): def del_aggregation_algorithm(self, intra_extension_id): with sql.transaction() as session: - query = session.query(AggregationAlgorithm) - query = query.filter_by(intra_extension_id=intra_extension_id) + query = session.query(IntraExtension) + query = query.filter_by(id=intra_extension_id) ref = query.first() - session.delete(ref) + intra_extension_dict = dict(ref.intra_extension) + intra_extension_dict["aggregation_algorithm"] = "" + setattr(ref, "intra_extension", intra_extension_dict) + return self.get_aggregation_algorithm_id(intra_extension_id) # Getter and Setter for sub_meta_rule @@ -993,6 +981,9 @@ class IntraExtensionConnector(IntraExtensionDriver): if not ref: session.add(new_ref) else: + _sub_meta_rule_dict = dict(ref.sub_meta_rule) + _sub_meta_rule_dict.update(sub_meta_rule_dict) + setattr(new_ref, "sub_meta_rule", _sub_meta_rule_dict) for attr in SubMetaRule.attributes: if attr != 'id': setattr(ref, attr, getattr(new_ref, attr)) diff --git a/keystone-moon/keystone/contrib/moon/core.py b/keystone-moon/keystone/contrib/moon/core.py index db194911..19c1986e 100644 --- a/keystone-moon/keystone/contrib/moon/core.py +++ b/keystone-moon/keystone/contrib/moon/core.py @@ -1702,6 +1702,9 @@ class IntraExtensionManager(manager.Manager): def set_sub_meta_rule_dict(self, user_id, intra_extension_id, sub_meta_rule_id, sub_meta_rule_dict): if sub_meta_rule_id not in self.driver.get_sub_meta_rules_dict(intra_extension_id): raise SubMetaRuleUnknown() + for attribute in sub_meta_rule_dict.keys(): + if not sub_meta_rule_dict[attribute]: + sub_meta_rule_dict.pop(attribute) return self.driver.set_sub_meta_rule_dict(intra_extension_id, sub_meta_rule_id, sub_meta_rule_dict) # Rule functions diff --git a/keystone-moon/keystone/contrib/moon/migrate_repo/versions/001_moon.py b/keystone-moon/keystone/contrib/moon/migrate_repo/versions/001_moon.py index b9b981cf..bcd334fa 100644 --- a/keystone-moon/keystone/contrib/moon/migrate_repo/versions/001_moon.py +++ b/keystone-moon/keystone/contrib/moon/migrate_repo/versions/001_moon.py @@ -158,16 +158,6 @@ def upgrade(migrate_engine): mysql_charset='utf8') action_assignments_table.create(migrate_engine, checkfirst=True) - aggregation_algorithm_table = sql.Table( - 'aggregation_algorithm', - meta, - sql.Column('id', sql.String(64), primary_key=True), - sql.Column('aggregation_algorithm', k_sql.JsonBlob(), nullable=True), - sql.Column('intra_extension_id', sql.ForeignKey("intra_extensions.id"), nullable=False), - mysql_engine='InnoDB', - mysql_charset='utf8') - aggregation_algorithm_table.create(migrate_engine, checkfirst=True) - sub_meta_rules_table = sql.Table( 'sub_meta_rules', meta, diff --git a/moonclient/moonclient/metarules.py b/moonclient/moonclient/metarules.py index 74473d1c..c922afb5 100644 --- a/moonclient/moonclient/metarules.py +++ b/moonclient/moonclient/metarules.py @@ -15,36 +15,14 @@ class AggregationAlgorithmsList(Lister): log = logging.getLogger(__name__) - def get_parser(self, prog_name): - parser = super(AggregationAlgorithmsList, self).get_parser(prog_name) - parser.add_argument( - '--intraextension', - metavar='<intraextension-uuid>', - help='IntraExtension UUID', - ) - return parser - - def take_action(self, parsed_args): - if not parsed_args.intraextension: - parsed_args.intraextension = self.app.intraextension - data = self.app.get_url("/v3/OS-MOON/intra_extensions/{}/aggregation_algorithms".format( - parsed_args.intraextension), - authtoken=True) - if "aggregation_algorithms" not in data: - raise Exception("Error in command {}: {}".format("AggregationAlgorithmsList", data)) - return ( - ("aggregation_algorithms",), - ((_uuid, ) for _uuid in data["aggregation_algorithms"]) - ) - - -class AggregationAlgorithmShow(ShowOne): - """List the current aggregation algorithm.""" - - log = logging.getLogger(__name__) + def __get_aggregation_algorithm_from_id(self, algorithm_id): + algorithms = self.app.get_url("/v3/OS-MOON/configuration/aggregation_algorithms", authtoken=True) + if algorithm_id in algorithms: + return algorithms[algorithm_id] + return dict() def get_parser(self, prog_name): - parser = super(AggregationAlgorithmShow, self).get_parser(prog_name) + parser = super(AggregationAlgorithmsList, self).get_parser(prog_name) parser.add_argument( '--intraextension', metavar='<intraextension-uuid>', @@ -58,19 +36,24 @@ class AggregationAlgorithmShow(ShowOne): data = self.app.get_url("/v3/OS-MOON/intra_extensions/{}/aggregation_algorithm".format( parsed_args.intraextension), authtoken=True) - if "aggregation_algorithm" not in data: - raise Exception("Error in command {}: {}".format("AggregationAlgorithmList", data)) + algorithm = self.__get_aggregation_algorithm_from_id(data['content']) return ( - ("aggregation_algorithm",), - (data["aggregation_algorithm"],) + ("id", "name", "description"), + ((data['content'], algorithm["name"], algorithm["description"]), ) ) -class AggregationAlgorithmSet(ShowOne): +class AggregationAlgorithmSet(Command): """Set the current aggregation algorithm.""" log = logging.getLogger(__name__) + def __get_aggregation_algorithm_from_id(self, algorithm_id): + algorithms = self.app.get_url("/v3/OS-MOON/configuration/aggregation_algorithms", authtoken=True) + if algorithm_id in algorithms: + return algorithms[algorithm_id] + return dict() + def get_parser(self, prog_name): parser = super(AggregationAlgorithmSet, self).get_parser(prog_name) parser.add_argument( @@ -90,13 +73,12 @@ class AggregationAlgorithmSet(ShowOne): parsed_args.intraextension = self.app.intraextension data = self.app.get_url("/v3/OS-MOON/intra_extensions/{}/aggregation_algorithm".format( parsed_args.intraextension), - post_data={"aggregation_algorithm": parsed_args.aggregation_algorithm}, + post_data={"aggregation_algorithm_id": parsed_args.aggregation_algorithm}, authtoken=True) - if "aggregation_algorithm" not in data: - raise Exception("Error in command {}: {}".format("AggregationAlgorithmSet", data)) + algorithm = self.__get_aggregation_algorithm_from_id(data['content']) return ( - ("aggregation_algorithm",), - (data["aggregation_algorithm"],) + ("id", "name", "description"), + ((data['content'], algorithm["name"], algorithm["description"]), ) ) @@ -114,16 +96,41 @@ class SubMetaRuleShow(Lister): ) return parser + def __get_subject_category_name(self, intraextension, category_id): + data = self.app.get_url("/v3/OS-MOON/intra_extensions/{}/subject_categories".format(intraextension), + authtoken=True) + if category_id in data: + return data[category_id]["name"] + + def __get_object_category_name(self, intraextension, category_id): + data = self.app.get_url("/v3/OS-MOON/intra_extensions/{}/object_categories".format(intraextension), + authtoken=True) + if category_id in data: + return data[category_id]["name"] + + def __get_action_category_name(self, intraextension, category_id): + data = self.app.get_url("/v3/OS-MOON/intra_extensions/{}/action_categories".format(intraextension), + authtoken=True) + if category_id in data: + return data[category_id]["name"] + def take_action(self, parsed_args): if not parsed_args.intraextension: parsed_args.intraextension = self.app.intraextension - data = self.app.get_url("/v3/OS-MOON/intra_extensions/{}/sub_meta_rule".format(parsed_args.intraextension), + data = self.app.get_url("/v3/OS-MOON/intra_extensions/{}/sub_meta_rules".format(parsed_args.intraextension), authtoken=True) - if "sub_meta_rule" not in data: - raise Exception("Error in command {}".format(data)) + import json + self.log.debug(json.dumps(data, indent=4)) return ( - ("relation", "values"), - ((key, value) for key, value in data["sub_meta_rule"].items()) + ("id", "name", "algorithm", "subject categories", "object categories", "action categories"), + (( + key, + value["name"], + value["algorithm"], + ", ".join([self.__get_subject_category_name(parsed_args.intraextension, cat) for cat in value["subject_categories"]]), + ", ".join([self.__get_object_category_name(parsed_args.intraextension, cat) for cat in value["object_categories"]]), + ", ".join([self.__get_action_category_name(parsed_args.intraextension, cat) for cat in value["action_categories"]]), + ) for key, value in data.iteritems()) ) @@ -135,24 +142,34 @@ class SubMetaRuleSet(Command): def get_parser(self, prog_name): parser = super(SubMetaRuleSet, self).get_parser(prog_name) parser.add_argument( - 'relation', - metavar='<relation-uuid>', - help='relation UUID (example: "relation_super")', + 'id', + metavar='<sub_meta_rule-uuid>', + help='Sub Meta Rule UUID (example: "12346")', + ) + parser.add_argument( + '--algorithm', + metavar='<algorithm-str>', + help='algorithm to use (example: "inclusion")', + ) + parser.add_argument( + '--name', + metavar='<name-str>', + help='name to set (example: "my new sub meta rule")', ) parser.add_argument( - 'subject_categories', + '--subject_categories', metavar='<subject_categories-uuid>', - help='subject_categories UUID (example: "role,")', + help='subject_categories UUID (example: "12346,")', ) parser.add_argument( - 'action_categories', + '--action_categories', metavar='<action_categories-uuid>', - help='action_categories UUID (example: "compute_action,network_action")', + help='action_categories UUID (example: "12346,0987654")', ) parser.add_argument( - 'object_categories', + '--object_categories', metavar='<object_categories-uuid>', - help='object_categories UUID (example: "id,")', + help='object_categories UUID (example: "12346")', ) parser.add_argument( '--intraextension', @@ -164,19 +181,29 @@ class SubMetaRuleSet(Command): def take_action(self, parsed_args): if not parsed_args.intraextension: parsed_args.intraextension = self.app.intraextension - subject_categories = map(lambda x: x.strip(), parsed_args.subject_categories.split(',')) - action_categories = map(lambda x: x.strip(), parsed_args.action_categories.split(',')) - object_categories = map(lambda x: x.strip(), parsed_args.object_categories.split(',')) - relation = parsed_args.relation - self.app.get_url("/v3/OS-MOON/intra_extensions/{}/sub_meta_rule".format(parsed_args.intraextension), - post_data={ - relation: { - "subject_categories": subject_categories, - "action_categories": action_categories, - "object_categories": object_categories, - } - }, - method="DELETE", + subject_categories = parsed_args.subject_categories + if not subject_categories: + subject_categories = "" + object_categories = parsed_args.object_categories + if not object_categories: + object_categories = "" + action_categories = parsed_args.action_categories + if not action_categories: + action_categories = "" + self.log.debug("object_categories = {}".format(object_categories)) + subject_categories = map(lambda x: x.strip(), subject_categories.split(',')) + action_categories = map(lambda x: x.strip(), action_categories.split(',')) + object_categories = map(lambda x: x.strip(), object_categories.split(',')) + sub_meta_rule_id = parsed_args.id + post_data = dict() + post_data["sub_meta_rule_name"] = parsed_args.name + post_data["sub_meta_rule_algorithm"] = parsed_args.algorithm + post_data["sub_meta_rule_subject_categories"] = filter(lambda x: x, subject_categories) + post_data["sub_meta_rule_object_categories"] = filter(lambda x: x, object_categories) + post_data["sub_meta_rule_action_categories"] = filter(lambda x: x, action_categories) + self.app.get_url("/v3/OS-MOON/intra_extensions/{}/sub_meta_rules/{}".format(parsed_args.intraextension, sub_meta_rule_id), + post_data=post_data, + method="POST", authtoken=True) diff --git a/moonclient/moonclient/tests/tests_submetarules.json b/moonclient/moonclient/tests/tests_submetarules.json new file mode 100644 index 00000000..093cbcf2 --- /dev/null +++ b/moonclient/moonclient/tests/tests_submetarules.json @@ -0,0 +1,289 @@ +{ + "command_options": "-f value", + "tests_group": { + "authz": [ + { + "name": "list tenant", + "command": "tenant list", + "result": "(?!alt_demo)", + "description": "Check if tenant alt_demo is used." + }, + { + "name": "add tenant alt_demo", + "command": "tenant add alt_demo", + "result": "^$", + "description": "Add a new tenant", + "command_options": "" + }, + { + "name": "check tenant alt_demo", + "command": "tenant list", + "result": "(?P<uuid>\\w+)\\s+alt_demo", + "description": "Check that tenant alt_demo has been correctly added" + }, + { + "name": "create_intraextension_authz", + "command": "intraextension create --policy_model policy_authz authz_test", + "result": "IntraExtension created: (?P<uuid_authz>\\w+)", + "description": "Create an authz intra extension", + "command_options": "" + }, + { + "name": "list_intraextension_authz", + "command": "intraextension list", + "result": "$uuid_authz", + "description": "Check the existence of that authz intra extension" + }, + { + "name": "set_tenant_authz", + "command": "tenant set --authz $uuid_authz $uuid", + "result": "", + "description": "Connect the authz intra extension to the tenant alt_demo", + "command_options": "" + }, + { + "name": "select_authz_ie", + "command": "intraextension select $uuid_authz", + "result": "Select $uuid_authz IntraExtension.", + "description": "Select the authz IntraExtension", + "command_options": "" + }, + { + "name": "check_select_authz_ie", + "command": "intraextension show selected", + "result": "$uuid_authz", + "description": "Check the selected authz IntraExtension", + "command_options": "-c id -f value" + }, + + { + "name": "check_submetarules", + "command": "submetarule show", + "result": "(?P<submetarule_uuid>\\w+)\\s+subject_security_level", + "description": "Get one submetarule ID", + "command_options": "-c id -c \"subject categories\" -f value" + }, + { + "name": "list_subject_categories", + "command": "subject category list", + "result": "(?P<category_domain_uuid>\\w+)\\s+domain", + "description": "Get one subject category.", + "command_options": "-c id -c name -f value" + }, + { + "name": "list_subject_categories", + "command": "subject category list", + "result": "(?P<category_level_uuid>\\w+)\\s+subject_security_level", + "description": "Get one subject category.", + "command_options": "-c id -c name -f value" + }, + { + "name": "set_submetarule", + "command": "submetarule set $submetarule_uuid --subject_categories=\"$category_level_uuid,$category_domain_uuid\"", + "result": "^$", + "description": "Set a new submetarule", + "command_options": "" + }, + { + "name": "check_submetarule", + "command": "submetarule show", + "result": "$submetarule_uuid \\s*subject_security_level,\\s+domain", + "description": "Check the new submetarule", + "command_options": "-c id -c \"subject categories\" -f value" + }, + { + "name": "check_submetarule", + "command": "submetarule show", + "result": "$submetarule_uuid \\s*object_security_level", + "description": "Check the new submetarule", + "command_options": "-c id -c \"object categories\" -f value" + }, + + { + "name": "delete_authz_intra_extension", + "command": "intraextension delete $uuid_authz", + "result": "", + "description": "Delete the authz intra extension", + "command_options": "" + }, + { + "name": "list_intraextension_authz", + "command": "intraextension list", + "result": "(?!$uuid_authz)", + "description": "Check the existence of that authz intra extension" + }, + { + "name": "delete_tenant", + "command": "tenant delete $uuid", + "result": "", + "description": "Delete the tenant alt_demo", + "command_options": "" + }, + { + "name": "list tenant", + "command": "tenant list", + "result": "(?!alt_demo)", + "description": "Check if tenant alt_demo is used." + } + ], + "authz_and_admin": [ + { + "name": "list tenant", + "command": "tenant list", + "result": "(?!alt_demo)", + "description": "Check if tenant alt_demo is used." + }, + { + "name": "add tenant alt_demo", + "command": "tenant add alt_demo", + "result": "^$", + "description": "Add a new tenant", + "command_options": "" + }, + { + "name": "check tenant alt_demo", + "command": "tenant list", + "result": "(?P<uuid>\\w+)\\s+alt_demo", + "description": "Check that tenant alt_demo has been correctly added" + }, + { + "name": "create_intraextension_authz", + "command": "intraextension create --policy_model policy_authz authz_test", + "result": "IntraExtension created: (?P<uuid_authz>\\w+)", + "description": "Create an authz intra extension", + "command_options": "" + }, + { + "name": "list_intraextension_authz", + "command": "intraextension list", + "result": "$uuid_authz", + "description": "Check the existence of that authz intra extension" + }, + { + "name": "create_intraextension_admin", + "command": "intraextension create --policy_model policy_admin admin_test", + "result": "IntraExtension created: (?P<uuid_admin>\\w+)", + "description": "Create an admin intra extension", + "command_options": "" + }, + { + "name": "list_intraextension_admin", + "command": "intraextension list", + "result": "$uuid_admin", + "description": "Check the existence of that admin intra extension" + }, + { + "name": "set_tenant_authz", + "command": "tenant set --authz $uuid_authz $uuid", + "result": "", + "description": "Connect the authz intra extension to the tenant demo", + "command_options": "" + }, + { + "name": "set_tenant_admin", + "command": "tenant set --admin $uuid_admin $uuid", + "result": "", + "description": "Connect the authz intra extension to the tenant alt_demo", + "command_options": "" + }, + { + "name": "check tenant alt_demo and authz ie", + "command": "tenant list", + "result": "alt_demo $uuid_authz", + "description": "Check that authz intra extension has been correctly added to the tenant.", + "command_options": "-c name -c intra_authz_extension_id -f value" + }, + { + "name": "check tenant alt_demo and admin ie", + "command": "tenant list", + "result": "$uuid_admin", + "description": "Check that admin intra extension has been correctly added to the tenant.", + "command_options": "-c intra_admin_extension_id -f value" + }, + { + "name": "select_authz_ie", + "command": "intraextension select $uuid_authz", + "result": "Select $uuid_authz IntraExtension.", + "description": "Select the authz IntraExtension", + "command_options": "" + }, + { + "name": "check_select_authz_ie", + "command": "intraextension show selected", + "result": "$uuid_authz", + "description": "Check the selected authz IntraExtension", + "command_options": "-c id -f value" + }, + + { + "name": "check_submetarules", + "command": "submetarule show", + "result": "(?P<submetarule_uuid>\\w+)\\s+subject_security_level", + "description": "Get one submetarule ID", + "command_options": "-c id -c \"subject categories\" -f value" + }, + { + "name": "list_subject_categories", + "command": "subject category list", + "result": "(?P<category_domain_uuid>\\w+)\\s+domain", + "description": "Get one subject category.", + "command_options": "-c id -c name -f value" + }, + { + "name": "list_subject_categories", + "command": "subject category list", + "result": "(?P<category_level_uuid>\\w+)\\s+subject_security_level", + "description": "Get one subject category.", + "command_options": "-c id -c name -f value" + }, + { + "name": "set_submetarule", + "command": "submetarule set $submetarule_uuid --subject_categories=\"$category_level_uuid,$category_domain_uuid\"", + "result": "^$", + "description": "Set a new submetarule", + "command_options": "" + }, + { + "name": "check_submetarule", + "command": "submetarule show", + "result": "$submetarule_uuid \\s*subject_security_level,\\s+domain", + "description": "Check the new submetarule", + "command_options": "-c id -c \"subject categories\" -f value" + }, + { + "name": "check_submetarule", + "command": "submetarule show", + "result": "$submetarule_uuid \\s*object_security_level", + "description": "Check the new submetarule", + "command_options": "-c id -c \"object categories\" -f value" + }, + + { + "name": "delete_authz_intra_extension", + "command": "intraextension delete $uuid_authz", + "result": "", + "description": "Delete the authz intra extension", + "command_options": "" + }, + { + "name": "list_intraextension_authz", + "command": "intraextension list", + "result": "(?!$uuid_authz)", + "description": "Check the existence of that authz intra extension" + }, + { + "name": "delete_tenant", + "command": "tenant delete $uuid", + "result": "", + "description": "Delete the tenant alt_demo", + "command_options": "" + }, + { + "name": "list tenant", + "command": "tenant list", + "result": "(?!alt_demo)", + "description": "Check if tenant alt_demo is used." + } + ] + } +}
\ No newline at end of file diff --git a/moonclient/setup.py b/moonclient/setup.py index bdc8842a..b2bf612b 100644 --- a/moonclient/setup.py +++ b/moonclient/setup.py @@ -110,15 +110,18 @@ setup( 'action_scope_list = moonclient.action_category_scope:ActionCategoryScopeList', 'action_scope_add = moonclient.action_category_scope:ActionCategoryScopeAdd', 'action_scope_delete = moonclient.action_category_scope:ActionCategoryScopeDelete', - 'aggregation_algorithm_list = moonclient.metarules:AggregationAlgorithmsList', - 'aggregation_algorithm_show = moonclient.metarules:AggregationAlgorithmShow', + + 'aggregation_algorithm_show = moonclient.metarules:AggregationAlgorithmsList', 'aggregation_algorithm_set = moonclient.metarules:AggregationAlgorithmSet', + 'submetarule_show = moonclient.metarules:SubMetaRuleShow', 'submetarule_set = moonclient.metarules:SubMetaRuleSet', 'submetarule_relation_list = moonclient.metarules:SubMetaRuleRelationList', + 'rule_list = moonclient.rules:RulesList', 'rule_add = moonclient.rules:RuleAdd', 'rule_delete = moonclient.rules:RuleDelete', + 'log = moonclient.logs:LogsList', 'tests = moonclient.tests:TestsLaunch', |