aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--keystone-moon/keystone/contrib/moon/backends/sql.py31
-rw-r--r--keystone-moon/keystone/contrib/moon/core.py3
-rw-r--r--keystone-moon/keystone/contrib/moon/migrate_repo/versions/001_moon.py10
-rw-r--r--moonclient/moonclient/metarules.py157
-rw-r--r--moonclient/moonclient/tests/tests_submetarules.json289
-rw-r--r--moonclient/setup.py7
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',