migrate moonclient from github to opnfv 36/936/1
authorWuKong <rebirthmonkey@gmail.com>
Wed, 1 Jul 2015 07:01:11 +0000 (09:01 +0200)
committerWuKong <rebirthmonkey@gmail.com>
Wed, 1 Jul 2015 07:01:11 +0000 (09:01 +0200)
Change-Id: I024ad1136f50d1c2898d30e05be48131d02b6932
Signed-off-by: WuKong <rebirthmonkey@gmail.com>
35 files changed:
moonclient/Changelog [new file with mode: 0644]
moonclient/MANIFEST.in [new file with mode: 0644]
moonclient/README.rst [new file with mode: 0644]
moonclient/moonclient/__init__.py [new file with mode: 0644]
moonclient/moonclient/action_assignments.py [new file with mode: 0644]
moonclient/moonclient/action_categories.py [new file with mode: 0644]
moonclient/moonclient/action_category_scope.py [new file with mode: 0644]
moonclient/moonclient/actions.py [new file with mode: 0644]
moonclient/moonclient/authz_policies.py [new file with mode: 0644]
moonclient/moonclient/intraextension.py [new file with mode: 0644]
moonclient/moonclient/logs.py [new file with mode: 0644]
moonclient/moonclient/metarules.py [new file with mode: 0644]
moonclient/moonclient/object_assignments.py [new file with mode: 0644]
moonclient/moonclient/object_categories.py [new file with mode: 0644]
moonclient/moonclient/object_category_scope.py [new file with mode: 0644]
moonclient/moonclient/objects.py [new file with mode: 0644]
moonclient/moonclient/rules.py [new file with mode: 0644]
moonclient/moonclient/shell.py [new file with mode: 0644]
moonclient/moonclient/subject_assignments.py [new file with mode: 0644]
moonclient/moonclient/subject_categories.py [new file with mode: 0644]
moonclient/moonclient/subject_category_scope.py [new file with mode: 0644]
moonclient/moonclient/subjects.py [new file with mode: 0644]
moonclient/moonclient/tests/functional_tests.sh [new file with mode: 0644]
moonclient/python_moonclient.egg-info/PKG-INFO [new file with mode: 0644]
moonclient/python_moonclient.egg-info/SOURCES.txt [new file with mode: 0644]
moonclient/python_moonclient.egg-info/dependency_links.txt [new file with mode: 0644]
moonclient/python_moonclient.egg-info/entry_points.txt [new file with mode: 0644]
moonclient/python_moonclient.egg-info/namespace_packages.txt [new file with mode: 0644]
moonclient/python_moonclient.egg-info/not-zip-safe [new file with mode: 0644]
moonclient/python_moonclient.egg-info/pbr.json [new file with mode: 0644]
moonclient/python_moonclient.egg-info/requires.txt [new file with mode: 0644]
moonclient/python_moonclient.egg-info/top_level.txt [new file with mode: 0644]
moonclient/requirements.txt [new file with mode: 0644]
moonclient/setup.cfg [new file with mode: 0644]
moonclient/setup.py [new file with mode: 0644]

diff --git a/moonclient/Changelog b/moonclient/Changelog
new file mode 100644 (file)
index 0000000..f867b64
--- /dev/null
@@ -0,0 +1,13 @@
+# 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'.
+
+
+CHANGES
+=======
+
+0.1.0
+-----
+
+* Initialization of Moon Client
\ No newline at end of file
diff --git a/moonclient/MANIFEST.in b/moonclient/MANIFEST.in
new file mode 100644 (file)
index 0000000..278893e
--- /dev/null
@@ -0,0 +1,2 @@
+include README.rst
+include moonclient/tests/functional_tests.sh
\ No newline at end of file
diff --git a/moonclient/README.rst b/moonclient/README.rst
new file mode 100644 (file)
index 0000000..2fabcaa
--- /dev/null
@@ -0,0 +1,8 @@
+# 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'.
+
+
+Moon Client
+
diff --git a/moonclient/moonclient/__init__.py b/moonclient/moonclient/__init__.py
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/moonclient/moonclient/action_assignments.py b/moonclient/moonclient/action_assignments.py
new file mode 100644 (file)
index 0000000..141bfa7
--- /dev/null
@@ -0,0 +1,125 @@
+# 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'.
+
+import logging
+
+from cliff.lister import Lister
+from cliff.command import Command
+
+
+class ActionAssignmentsList(Lister):
+    """List all Intra_Extensions."""
+
+    log = logging.getLogger(__name__)
+
+    def get_parser(self, prog_name):
+        parser = super(ActionAssignmentsList, 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/{}/action_assignments".format(parsed_args.intraextension),
+                                authtoken=True)
+        if "action_assignments" not in data:
+            raise Exception("Error in command {}: {}".format("ActionAssignmentsList", data))
+        return (
+            ("category", "value"),
+            ((_cat, str(_val)) for _cat, _val in data["action_assignments"].items())
+        )
+
+
+class ActionAssignmentsAdd(Command):
+    """List all Intra_Extensions."""
+
+    log = logging.getLogger(__name__)
+
+    def get_parser(self, prog_name):
+        parser = super(ActionAssignmentsAdd, self).get_parser(prog_name)
+        parser.add_argument(
+            'action_id',
+            metavar='<action-uuid>',
+            help='Action UUID',
+        )
+        parser.add_argument(
+            'action_category',
+            metavar='<action_category>',
+            help='Action Category',
+        )
+        parser.add_argument(
+            'action_category_scope',
+            metavar='<action_category_scope>',
+            help='Action Category Scope',
+        )
+        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/{}/action_assignments".format(parsed_args.intraextension),
+                                post_data={
+                                    "action_id": parsed_args.action_id,
+                                    "action_category": parsed_args.action_category,
+                                    "action_category_scope": parsed_args.action_category_scope
+                                },
+                                authtoken=True)
+        if "action_assignments" not in data:
+            raise Exception("Error in command {}".format(data))
+        return (
+            ("category", "value"),
+            ((_cat, str(_val)) for _cat, _val in data["action_assignments"].items())
+        )
+
+
+class ActionAssignmentsDelete(Command):
+    """List all Intra_Extensions."""
+
+    log = logging.getLogger(__name__)
+
+    def get_parser(self, prog_name):
+        parser = super(ActionAssignmentsDelete, self).get_parser(prog_name)
+        parser.add_argument(
+            'action_id',
+            metavar='<action-uuid>',
+            help='Action UUID',
+        )
+        parser.add_argument(
+            'action_category',
+            metavar='<action_category>',
+            help='Action Category',
+        )
+        parser.add_argument(
+            'action_category_scope',
+            metavar='<action_category_scope>',
+            help='Action Category Scope',
+        )
+        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
+        self.app.get_url("/v3/OS-MOON/intra_extensions/{}/action_assignments/{}/{}/{}".format(
+            parsed_args.intraextension,
+            parsed_args.action_category,
+            parsed_args.action_id,
+            parsed_args.action_category_scope
+        ),
+            method="DELETE",
+            authtoken=True)
\ No newline at end of file
diff --git a/moonclient/moonclient/action_categories.py b/moonclient/moonclient/action_categories.py
new file mode 100644 (file)
index 0000000..33875f5
--- /dev/null
@@ -0,0 +1,99 @@
+# 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'.
+
+import logging
+
+from cliff.lister import Lister
+from cliff.command import Command
+
+
+class ActionCategoriesList(Lister):
+    """List all Intra_Extensions."""
+
+    log = logging.getLogger(__name__)
+
+    def get_parser(self, prog_name):
+        parser = super(ActionCategoriesList, 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/{}/action_categories".format(parsed_args.intraextension),
+                                authtoken=True)
+        if "action_categories" not in data:
+            raise Exception("Error in command {}: {}".format("ActionCategoriesList", data))
+        return (
+            ("action_categories",),
+            ((_uuid, ) for _uuid in data["action_categories"])
+        )
+
+
+class ActionCategoriesAdd(Command):
+    """List all Intra_Extensions."""
+
+    log = logging.getLogger(__name__)
+
+    def get_parser(self, prog_name):
+        parser = super(ActionCategoriesAdd, self).get_parser(prog_name)
+        parser.add_argument(
+            'action_category',
+            metavar='<action_category-uuid>',
+            help='Action UUID',
+        )
+        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/{}/action_categories".format(parsed_args.intraextension),
+                                post_data={"action_category_id": parsed_args.action_category},
+                                authtoken=True)
+        if "action_categories" not in data:
+            raise Exception("Error in command {}".format(data))
+        return (
+            ("action_categories",),
+            ((_uuid, ) for _uuid in data["action_categories"])
+        )
+
+
+class ActionCategoriesDelete(Command):
+    """List all Intra_Extensions."""
+
+    log = logging.getLogger(__name__)
+
+    def get_parser(self, prog_name):
+        parser = super(ActionCategoriesDelete, self).get_parser(prog_name)
+        parser.add_argument(
+            'action_category',
+            metavar='<action_category-uuid>',
+            help='Action UUID',
+        )
+        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
+        self.app.get_url("/v3/OS-MOON/intra_extensions/{}/action_categories/{}".format(
+            parsed_args.intraextension,
+            parsed_args.action_category
+        ),
+            method="DELETE",
+            authtoken=True)
\ No newline at end of file
diff --git a/moonclient/moonclient/action_category_scope.py b/moonclient/moonclient/action_category_scope.py
new file mode 100644 (file)
index 0000000..7eab8a1
--- /dev/null
@@ -0,0 +1,113 @@
+# 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'.
+
+import logging
+
+from cliff.lister import Lister
+from cliff.command import Command
+
+
+class ActionCategoryScopeList(Lister):
+    """List all Intra_Extensions."""
+
+    log = logging.getLogger(__name__)
+
+    def get_parser(self, prog_name):
+        parser = super(ActionCategoryScopeList, 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/{}/action_category_scope".format(parsed_args.intraextension),
+                                authtoken=True)
+        if "action_category_scope" not in data:
+            raise Exception("Error in command {}: {}".format("ActionCategoryScopeList", data))
+        return (
+            ("action_category", "action_category_scope",),
+            ((_val1, str(_val2)) for _val1, _val2 in data["action_category_scope"].items())
+        )
+
+
+class ActionCategoryScopeAdd(Command):
+    """List all Intra_Extensions."""
+
+    log = logging.getLogger(__name__)
+
+    def get_parser(self, prog_name):
+        parser = super(ActionCategoryScopeAdd, self).get_parser(prog_name)
+        parser.add_argument(
+            'action_category',
+            metavar='<action_category-uuid>',
+            help='Action UUID',
+        )
+        parser.add_argument(
+            'action_category_scope',
+            metavar='<action_category_scope-uuid>',
+            help='Action UUID',
+        )
+        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/{}/action_category_scope".format(parsed_args.intraextension),
+                                post_data={
+                                    "action_category_id": parsed_args.action_category,
+                                    "action_category_scope_id": parsed_args.action_category_scope,
+                                },
+                                authtoken=True)
+        if "action_category_scope" not in data:
+            raise Exception("Error in command {}".format(data))
+        return (
+            ("action_category", "action_category_scope",),
+            ((_val1, str(_val2)) for _val1, _val2 in data["action_category_scope"].items())
+        )
+
+
+class ActionCategoryScopeDelete(Command):
+    """List all Intra_Extensions."""
+
+    log = logging.getLogger(__name__)
+
+    def get_parser(self, prog_name):
+        parser = super(ActionCategoryScopeDelete, self).get_parser(prog_name)
+        parser.add_argument(
+            'action_category',
+            metavar='<action_category-uuid>',
+            help='Action UUID',
+        )
+        parser.add_argument(
+            'action_category_scope',
+            metavar='<action_category_scope-uuid>',
+            help='Action UUID',
+        )
+        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
+        self.app.get_url("/v3/OS-MOON/intra_extensions/{}/action_category_scope/{}/{}".format(
+            parsed_args.intraextension,
+            parsed_args.action_category,
+            parsed_args.action_category_scope
+        ),
+            method="DELETE",
+            authtoken=True)
\ No newline at end of file
diff --git a/moonclient/moonclient/actions.py b/moonclient/moonclient/actions.py
new file mode 100644 (file)
index 0000000..a35b694
--- /dev/null
@@ -0,0 +1,99 @@
+# 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'.
+
+import logging
+
+from cliff.lister import Lister
+from cliff.command import Command
+
+
+class ActionsList(Lister):
+    """List all Intra_Extensions."""
+
+    log = logging.getLogger(__name__)
+
+    def get_parser(self, prog_name):
+        parser = super(ActionsList, 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/{}/actions".format(parsed_args.intraextension),
+                                authtoken=True)
+        if "actions" not in data:
+            raise Exception("Error in command {}: {}".format("ActionsList", data))
+        return (
+            ("actions",),
+            ((_uuid, ) for _uuid in data["actions"])
+        )
+
+
+class ActionsAdd(Command):
+    """List all Intra_Extensions."""
+
+    log = logging.getLogger(__name__)
+
+    def get_parser(self, prog_name):
+        parser = super(ActionsAdd, self).get_parser(prog_name)
+        parser.add_argument(
+            'action',
+            metavar='<action-uuid>',
+            help='Action UUID',
+        )
+        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/{}/actions".format(parsed_args.intraextension),
+                                post_data={"action_id": parsed_args.action},
+                                authtoken=True)
+        if "actions" not in data:
+            raise Exception("Error in command {}".format(data))
+        return (
+            ("actions",),
+            ((_uuid, ) for _uuid in data["actions"])
+        )
+
+
+class ActionsDelete(Command):
+    """List all Intra_Extensions."""
+
+    log = logging.getLogger(__name__)
+
+    def get_parser(self, prog_name):
+        parser = super(ActionsDelete, self).get_parser(prog_name)
+        parser.add_argument(
+            'action',
+            metavar='<action-uuid>',
+            help='Action UUID',
+        )
+        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
+        self.app.get_url("/v3/OS-MOON/intra_extensions/{}/actions/{}".format(
+            parsed_args.intraextension,
+            parsed_args.action
+        ),
+            method="DELETE",
+            authtoken=True)
\ No newline at end of file
diff --git a/moonclient/moonclient/authz_policies.py b/moonclient/moonclient/authz_policies.py
new file mode 100644 (file)
index 0000000..66ab39c
--- /dev/null
@@ -0,0 +1,25 @@
+# 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'.
+
+import logging
+
+from cliff.lister import Lister
+
+
+class AuthzPolicies(Lister):
+    """List all Intra_Extensions."""
+
+    log = logging.getLogger(__name__)
+
+    def get_parser(self, prog_name):
+        parser = super(AuthzPolicies, self).get_parser(prog_name)
+        return parser
+
+    def take_action(self, parsed_args):
+        policies = self.app.get_url("/v3/OS-MOON/authz_policies", authtoken=True)["authz_policies"]
+        return (
+            ("name",),
+            ((_name, ) for _name in policies)
+        )
diff --git a/moonclient/moonclient/intraextension.py b/moonclient/moonclient/intraextension.py
new file mode 100644 (file)
index 0000000..c46927c
--- /dev/null
@@ -0,0 +1,156 @@
+# 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'.
+
+import logging
+
+from cliff.command import Command
+from cliff.lister import Lister
+from cliff.show import ShowOne
+
+
+class IntraExtensionCreate(Command):
+    """Create a new Intra_Extension."""
+
+    log = logging.getLogger(__name__)
+
+    def get_parser(self, prog_name):
+        parser = super(IntraExtensionCreate, self).get_parser(prog_name)
+        parser.add_argument(
+            'name',
+            metavar='<intraextension-name>',
+            help='New IntraExtension name',
+        )
+        parser.add_argument(
+            '--policy_model',
+            metavar='<policymodel-name>',
+            help='Policy model name (Template for the new IntraExtension)',
+        )
+        parser.add_argument(
+            '--description',
+            metavar='<intraextension-description>',
+            help='New IntraExtension description',
+            default=""
+        )
+        return parser
+
+    def take_action(self, parsed_args):
+        post_data = {
+            "name": parsed_args.name,
+            "policymodel": parsed_args.policy_model,
+            "description": parsed_args.description
+        }
+        ie = self.app.get_url("/v3/OS-MOON/intra_extensions", post_data=post_data, authtoken=True)
+        if "id" not in ie:
+            raise Exception("Error in command {}".format(ie))
+        self.app.stdout.write("IntraExtension created: {}\n".format(ie["id"]))
+        return
+
+
+class IntraExtensionList(Lister):
+    """List all Intra_Extensions."""
+
+    log = logging.getLogger(__name__)
+
+    def get_parser(self, prog_name):
+        parser = super(IntraExtensionList, self).get_parser(prog_name)
+        return parser
+
+    def take_action(self, parsed_args):
+        ie = self.app.get_url("/v3/OS-MOON/intra_extensions", authtoken=True)
+        if "intra_extensions" not in ie:
+            raise Exception("Error in command {}".format(ie))
+        return (
+            ("id",),
+            ((_id, ) for _id in ie["intra_extensions"])
+        )
+
+
+class IntraExtensionDelete(Command):
+    """Delete an Intra_Extension."""
+
+    log = logging.getLogger(__name__)
+
+    def get_parser(self, prog_name):
+        parser = super(IntraExtensionDelete, self).get_parser(prog_name)
+        parser.add_argument(
+            'uuid',
+            metavar='<intraextension-uuid>',
+            help='IntraExtension UUID',
+        )
+        return parser
+
+    def take_action(self, parsed_args):
+        ie = self.app.get_url("/v3/OS-MOON/intra_extensions/{}".format(parsed_args.uuid),
+                              method="DELETE",
+                              authtoken=True)
+        return
+
+
+class IntraExtensionShow(ShowOne):
+    """Show detail about one Intra_Extension."""
+
+    log = logging.getLogger(__name__)
+
+    def get_parser(self, prog_name):
+        parser = super(IntraExtensionShow, self).get_parser(prog_name)
+        parser.add_argument(
+            'uuid',
+            metavar='<intraextension-uuid>',
+            help='IntraExtension UUID',
+        )
+        return parser
+
+    def take_action(self, parsed_args):
+        ie = self.app.get_url("/v3/OS-MOON/intra_extensions/{}".format(parsed_args.uuid), authtoken=True)
+        if "intra_extensions" not in ie:
+            raise Exception("Error in command {}".format(ie))
+        try:
+            columns = (
+                "id",
+                "name",
+                "description",
+                "tenant",
+                "enabled",
+                "model",
+                "genre"
+            )
+            data = (
+                ie["intra_extensions"]["id"],
+                ie["intra_extensions"]["name"],
+                ie["intra_extensions"]["description"],
+                ie["intra_extensions"]["tenant"],
+                ie["intra_extensions"]["enabled"],
+                ie["intra_extensions"]["model"],
+                ie["intra_extensions"]["genre"]
+            )
+            return columns, data
+        except Exception as e:
+            self.app.stdout.write(str(e))
+
+
+class TenantSet(Command):
+    """Set the tenant for a intra_extension."""
+
+    log = logging.getLogger(__name__)
+
+    def get_parser(self, prog_name):
+        parser = super(TenantSet, self).get_parser(prog_name)
+        parser.add_argument(
+            'intraextension_uuid',
+            metavar='<intraextension-uuid>',
+            help='IntraExtension UUID',
+        )
+        parser.add_argument(
+            'tenant_name',
+            metavar='<tenant-name>',
+            help='Tenant Name',
+        )
+        return parser
+
+    def take_action(self, parsed_args):
+        self.app.get_url("/v3/OS-MOON/intra_extensions/{}/tenant".format(parsed_args.intraextension_uuid),
+                         post_data={"tenant_id": parsed_args.tenant_name},
+                         authtoken=True)
+
diff --git a/moonclient/moonclient/logs.py b/moonclient/moonclient/logs.py
new file mode 100644 (file)
index 0000000..03c1612
--- /dev/null
@@ -0,0 +1,67 @@
+# 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'.
+
+import logging
+
+from cliff.lister import Lister
+from cliff.command import Command
+from cliff.show import ShowOne
+
+
+class LogsList(Lister):
+    """List all aggregation algorithms."""
+
+    log = logging.getLogger(__name__)
+
+    def get_parser(self, prog_name):
+        parser = super(LogsList, self).get_parser(prog_name)
+        parser.add_argument(
+            '--filter',
+            metavar='<filter-str>',
+            help='Filter strings (example: "OK" or "authz")',
+        )
+        parser.add_argument(
+            '--fromdate',
+            metavar='<from-date-str>',
+            help='Filter logs by date (example: "2015-04-15-13:45:20")',
+        )
+        parser.add_argument(
+            '--todate',
+            metavar='<to-date-str>',
+            help='Filter logs by date (example: "2015-04-15-13:45:20")',
+        )
+        parser.add_argument(
+            '--number',
+            metavar='<number-int>',
+            help='Show only <number-int> logs',
+        )
+        return parser
+
+    def take_action(self, parsed_args):
+        filter_str = parsed_args.filter
+        from_date = parsed_args.fromdate
+        to_date = parsed_args.todate
+        number = parsed_args.number
+        options = list()
+        if filter_str:
+            options.append("filter={}".format(filter_str))
+        if from_date:
+            options.append("from={}".format(from_date))
+        if to_date:
+            options.append("to={}".format(to_date))
+        if number:
+            options.append("event_number={}".format(number))
+        if len(options) > 0:
+            url = "/v3/OS-MOON/logs/{}".format(",".join(options))
+        else:
+            url = "/v3/OS-MOON/logs"
+        data = self.app.get_url(url, authtoken=True)
+        if "logs" not in data:
+            raise Exception("Error in command {}: {}".format("LogsList", data))
+        return (
+            ("Logs",),
+            ((log, ) for log in data["logs"])
+        )
+
diff --git a/moonclient/moonclient/metarules.py b/moonclient/moonclient/metarules.py
new file mode 100644 (file)
index 0000000..74473d1
--- /dev/null
@@ -0,0 +1,210 @@
+# 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'.
+
+import logging
+
+from cliff.lister import Lister
+from cliff.command import Command
+from cliff.show import ShowOne
+
+
+class AggregationAlgorithmsList(Lister):
+    """List all aggregation algorithms."""
+
+    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_parser(self, prog_name):
+        parser = super(AggregationAlgorithmShow, 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_algorithm".format(
+            parsed_args.intraextension),
+            authtoken=True)
+        if "aggregation_algorithm" not in data:
+            raise Exception("Error in command {}: {}".format("AggregationAlgorithmList", data))
+        return (
+            ("aggregation_algorithm",),
+            (data["aggregation_algorithm"],)
+        )
+
+
+class AggregationAlgorithmSet(ShowOne):
+    """Set the current aggregation algorithm."""
+
+    log = logging.getLogger(__name__)
+
+    def get_parser(self, prog_name):
+        parser = super(AggregationAlgorithmSet, self).get_parser(prog_name)
+        parser.add_argument(
+            'aggregation_algorithm',
+            metavar='<aggregation_algorithm-uuid>',
+            help='Aggregation algorithm UUID',
+        )
+        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_algorithm".format(
+            parsed_args.intraextension),
+            post_data={"aggregation_algorithm": parsed_args.aggregation_algorithm},
+            authtoken=True)
+        if "aggregation_algorithm" not in data:
+            raise Exception("Error in command {}: {}".format("AggregationAlgorithmSet", data))
+        return (
+            ("aggregation_algorithm",),
+            (data["aggregation_algorithm"],)
+        )
+
+
+class SubMetaRuleShow(Lister):
+    """Show the current sub meta rule."""
+
+    log = logging.getLogger(__name__)
+
+    def get_parser(self, prog_name):
+        parser = super(SubMetaRuleShow, 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/{}/sub_meta_rule".format(parsed_args.intraextension),
+                                authtoken=True)
+        if "sub_meta_rule" not in data:
+            raise Exception("Error in command {}".format(data))
+        return (
+            ("relation", "values"),
+            ((key, value) for key, value in data["sub_meta_rule"].items())
+        )
+
+
+class SubMetaRuleSet(Command):
+    """Set the current sub meta rule."""
+
+    log = logging.getLogger(__name__)
+
+    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")',
+        )
+        parser.add_argument(
+            'subject_categories',
+            metavar='<subject_categories-uuid>',
+            help='subject_categories UUID (example: "role,")',
+        )
+        parser.add_argument(
+            'action_categories',
+            metavar='<action_categories-uuid>',
+            help='action_categories UUID (example: "compute_action,network_action")',
+        )
+        parser.add_argument(
+            'object_categories',
+            metavar='<object_categories-uuid>',
+            help='object_categories UUID (example: "id,")',
+        )
+        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
+        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",
+                         authtoken=True)
+
+
+class SubMetaRuleRelationList(Lister):
+    """List all sub meta rule relations."""
+
+    log = logging.getLogger(__name__)
+
+    def get_parser(self, prog_name):
+        parser = super(SubMetaRuleRelationList, 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/{}/sub_meta_rule_relations".format(
+            parsed_args.intraextension),
+            authtoken=True)
+        if "sub_meta_rule_relations" not in data:
+            raise Exception("Error in command {}: {}".format("AggregationAlgorithmList", data))
+        return (
+            ("sub_meta_rule_relations",),
+            ((_uuid, ) for _uuid in data["sub_meta_rule_relations"])
+        )
+
+
diff --git a/moonclient/moonclient/object_assignments.py b/moonclient/moonclient/object_assignments.py
new file mode 100644 (file)
index 0000000..81305d6
--- /dev/null
@@ -0,0 +1,125 @@
+# 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'.
+
+import logging
+
+from cliff.lister import Lister
+from cliff.command import Command
+
+
+class ObjectAssignmentsList(Lister):
+    """List all Intra_Extensions."""
+
+    log = logging.getLogger(__name__)
+
+    def get_parser(self, prog_name):
+        parser = super(ObjectAssignmentsList, 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/{}/object_assignments".format(parsed_args.intraextension),
+                                authtoken=True)
+        if "object_assignments" not in data:
+            raise Exception("Error in command {}: {}".format("ObjectAssignmentsList", data))
+        return (
+            ("category", "value"),
+            ((_cat, str(_val)) for _cat, _val in data["object_assignments"].items())
+        )
+
+
+class ObjectAssignmentsAdd(Command):
+    """List all Intra_Extensions."""
+
+    log = logging.getLogger(__name__)
+
+    def get_parser(self, prog_name):
+        parser = super(ObjectAssignmentsAdd, self).get_parser(prog_name)
+        parser.add_argument(
+            'object_id',
+            metavar='<action-uuid>',
+            help='Object UUID',
+        )
+        parser.add_argument(
+            'object_category',
+            metavar='<object_category>',
+            help='Object Category',
+        )
+        parser.add_argument(
+            'object_category_scope',
+            metavar='<object_category_scope>',
+            help='Object Category Scope',
+        )
+        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/{}/object_assignments".format(parsed_args.intraextension),
+                                post_data={
+                                    "object_id": parsed_args.object_id,
+                                    "object_category": parsed_args.object_category,
+                                    "object_category_scope": parsed_args.object_category_scope
+                                },
+                                authtoken=True)
+        if "object_assignments" not in data:
+            raise Exception("Error in command {}".format(data))
+        return (
+            ("category", "value"),
+            ((_cat, str(_val)) for _cat, _val in data["object_assignments"].items())
+        )
+
+
+class ObjectAssignmentsDelete(Command):
+    """List all Intra_Extensions."""
+
+    log = logging.getLogger(__name__)
+
+    def get_parser(self, prog_name):
+        parser = super(ObjectAssignmentsDelete, self).get_parser(prog_name)
+        parser.add_argument(
+            'object_id',
+            metavar='<action-uuid>',
+            help='Object UUID',
+        )
+        parser.add_argument(
+            'object_category',
+            metavar='<object_category>',
+            help='Object Category',
+        )
+        parser.add_argument(
+            'object_category_scope',
+            metavar='<object_category_scope>',
+            help='Object Category Scope',
+        )
+        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
+        self.app.get_url("/v3/OS-MOON/intra_extensions/{}/object_assignments/{}/{}/{}".format(
+            parsed_args.intraextension,
+            parsed_args.object_category,
+            parsed_args.object_id,
+            parsed_args.object_category_scope
+        ),
+            method="DELETE",
+            authtoken=True)
\ No newline at end of file
diff --git a/moonclient/moonclient/object_categories.py b/moonclient/moonclient/object_categories.py
new file mode 100644 (file)
index 0000000..caae13c
--- /dev/null
@@ -0,0 +1,99 @@
+# 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'.
+
+import logging
+
+from cliff.lister import Lister
+from cliff.command import Command
+
+
+class ObjectCategoriesList(Lister):
+    """List all Intra_Extensions."""
+
+    log = logging.getLogger(__name__)
+
+    def get_parser(self, prog_name):
+        parser = super(ObjectCategoriesList, 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/{}/object_categories".format(parsed_args.intraextension),
+                                authtoken=True)
+        if "object_categories" not in data:
+            raise Exception("Error in command {}: {}".format("ObjectCategoriesList", data))
+        return (
+            ("object_categories",),
+            ((_uuid, ) for _uuid in data["object_categories"])
+        )
+
+
+class ObjectCategoriesAdd(Command):
+    """List all Intra_Extensions."""
+
+    log = logging.getLogger(__name__)
+
+    def get_parser(self, prog_name):
+        parser = super(ObjectCategoriesAdd, self).get_parser(prog_name)
+        parser.add_argument(
+            'object_category',
+            metavar='<object_category-uuid>',
+            help='Object UUID',
+        )
+        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/{}/object_categories".format(parsed_args.intraextension),
+                                post_data={"object_category_id": parsed_args.object_category},
+                                authtoken=True)
+        if "object_categories" not in data:
+            raise Exception("Error in command {}".format(data))
+        return (
+            ("object_categories",),
+            ((_uuid, ) for _uuid in data["object_categories"])
+        )
+
+
+class ObjectCategoriesDelete(Command):
+    """List all Intra_Extensions."""
+
+    log = logging.getLogger(__name__)
+
+    def get_parser(self, prog_name):
+        parser = super(ObjectCategoriesDelete, self).get_parser(prog_name)
+        parser.add_argument(
+            'object_category',
+            metavar='<object_category-uuid>',
+            help='Object UUID',
+        )
+        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
+        self.app.get_url("/v3/OS-MOON/intra_extensions/{}/object_categories/{}".format(
+            parsed_args.intraextension,
+            parsed_args.object_category
+        ),
+            method="DELETE",
+            authtoken=True)
\ No newline at end of file
diff --git a/moonclient/moonclient/object_category_scope.py b/moonclient/moonclient/object_category_scope.py
new file mode 100644 (file)
index 0000000..c404bdd
--- /dev/null
@@ -0,0 +1,113 @@
+# 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'.
+
+import logging
+
+from cliff.lister import Lister
+from cliff.command import Command
+
+
+class ObjectCategoryScopeList(Lister):
+    """List all Intra_Extensions."""
+
+    log = logging.getLogger(__name__)
+
+    def get_parser(self, prog_name):
+        parser = super(ObjectCategoryScopeList, 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/{}/object_category_scope".format(parsed_args.intraextension),
+                                authtoken=True)
+        if "object_category_scope" not in data:
+            raise Exception("Error in command {}: {}".format("ObjectCategoryScopeList", data))
+        return (
+            ("object_category", "object_category_scope",),
+            ((_val1, str(_val2)) for _val1, _val2 in data["object_category_scope"].items())
+        )
+
+
+class ObjectCategoryScopeAdd(Command):
+    """List all Intra_Extensions."""
+
+    log = logging.getLogger(__name__)
+
+    def get_parser(self, prog_name):
+        parser = super(ObjectCategoryScopeAdd, self).get_parser(prog_name)
+        parser.add_argument(
+            'object_category',
+            metavar='<object_category-uuid>',
+            help='Object UUID',
+        )
+        parser.add_argument(
+            'object_category_scope',
+            metavar='<object_category_scope-uuid>',
+            help='Object Scope UUID',
+        )
+        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/{}/object_category_scope".format(parsed_args.intraextension),
+                                post_data={
+                                    "object_category_id": parsed_args.object_category,
+                                    "object_category_scope_id": parsed_args.object_category_scope,
+                                },
+                                authtoken=True)
+        if "object_category_scope" not in data:
+            raise Exception("Error in command {}".format(data))
+        return (
+            ("object_category", "object_category_scope",),
+            ((_val1, str(_val2)) for _val1, _val2 in data["object_category_scope"].items())
+        )
+
+
+class ObjectCategoryScopeDelete(Command):
+    """List all Intra_Extensions."""
+
+    log = logging.getLogger(__name__)
+
+    def get_parser(self, prog_name):
+        parser = super(ObjectCategoryScopeDelete, self).get_parser(prog_name)
+        parser.add_argument(
+            'object_category',
+            metavar='<object_category-uuid>',
+            help='Object UUID',
+        )
+        parser.add_argument(
+            'object_category_scope',
+            metavar='<object_category_scope-uuid>',
+            help='Object Scope UUID',
+        )
+        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
+        self.app.get_url("/v3/OS-MOON/intra_extensions/{}/object_category_scope/{}/{}".format(
+            parsed_args.intraextension,
+            parsed_args.object_category,
+            parsed_args.object_category_scope
+        ),
+            method="DELETE",
+            authtoken=True)
\ No newline at end of file
diff --git a/moonclient/moonclient/objects.py b/moonclient/moonclient/objects.py
new file mode 100644 (file)
index 0000000..6d949e3
--- /dev/null
@@ -0,0 +1,99 @@
+# 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'.
+
+import logging
+
+from cliff.lister import Lister
+from cliff.command import Command
+
+
+class ObjectsList(Lister):
+    """List all Intra_Extensions."""
+
+    log = logging.getLogger(__name__)
+
+    def get_parser(self, prog_name):
+        parser = super(ObjectsList, 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/{}/objects".format(parsed_args.intraextension),
+                                authtoken=True)
+        if "objects" not in data:
+            raise Exception("Error in command {}: {}".format("ObjectsList", data))
+        return (
+            ("objects",),
+            ((_uuid, ) for _uuid in data["objects"])
+        )
+
+
+class ObjectsAdd(Command):
+    """List all Intra_Extensions."""
+
+    log = logging.getLogger(__name__)
+
+    def get_parser(self, prog_name):
+        parser = super(ObjectsAdd, self).get_parser(prog_name)
+        parser.add_argument(
+            'object',
+            metavar='<object-uuid>',
+            help='Object UUID',
+        )
+        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/{}/objects".format(parsed_args.intraextension),
+                                post_data={"object_id": parsed_args.object},
+                                authtoken=True)
+        if "objects" not in data:
+            raise Exception("Error in command {}".format(data))
+        return (
+            ("objects",),
+            ((_uuid, ) for _uuid in data["objects"])
+        )
+
+
+class ObjectsDelete(Command):
+    """List all Intra_Extensions."""
+
+    log = logging.getLogger(__name__)
+
+    def get_parser(self, prog_name):
+        parser = super(ObjectsDelete, self).get_parser(prog_name)
+        parser.add_argument(
+            'object',
+            metavar='<object-uuid>',
+            help='Object UUID',
+        )
+        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
+        self.app.get_url("/v3/OS-MOON/intra_extensions/{}/objects/{}".format(
+            parsed_args.intraextension,
+            parsed_args.object
+        ),
+            method="DELETE",
+            authtoken=True)
\ No newline at end of file
diff --git a/moonclient/moonclient/rules.py b/moonclient/moonclient/rules.py
new file mode 100644 (file)
index 0000000..b1f7e42
--- /dev/null
@@ -0,0 +1,127 @@
+# 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'.
+
+import logging
+
+from cliff.lister import Lister
+from cliff.command import Command
+from cliff.show import ShowOne
+
+
+class RulesList(ShowOne):
+    """List all aggregation algorithms."""
+
+    log = logging.getLogger(__name__)
+
+    def get_parser(self, prog_name):
+        parser = super(RulesList, 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/{}/sub_rules".format(
+            parsed_args.intraextension),
+            authtoken=True)
+        if "sub_rules" not in data:
+            raise Exception("Error in command {}: {}".format("RulesList", data))
+        # TODO (dthom): a better view with a Lister
+        return (
+            ("sub_rules",),
+            (data["sub_rules"],)
+        )
+
+
+class RuleAdd(ShowOne):
+    """List the current aggregation algorithm."""
+
+    log = logging.getLogger(__name__)
+
+    def get_parser(self, prog_name):
+        parser = super(RuleAdd, self).get_parser(prog_name)
+        parser.add_argument(
+            'relation',
+            metavar='<relation-uuid>',
+            help='Relation UUID',
+        )
+        parser.add_argument(
+            'rule',
+            metavar='<argument-list>',
+            help='Rule list (example: admin,vm_admin,servers)',
+        )
+        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
+        rule = parsed_args.rule.split(",")
+        post = {
+            "rule": rule,
+            "relation": parsed_args.relation
+        }
+        data = self.app.get_url("/v3/OS-MOON/intra_extensions/{intraextension}/sub_rules".format(
+            intraextension=parsed_args.intraextension),
+            post_data=post,
+            authtoken=True)
+        if "sub_rules" not in data:
+            raise Exception("Error in command {}: {}".format("RuleAdd", data))
+        return (
+            ("sub_rules",),
+            (data["sub_rules"],)
+        )
+
+
+class RuleDelete(ShowOne):
+    """Set the current aggregation algorithm."""
+
+    log = logging.getLogger(__name__)
+
+    def get_parser(self, prog_name):
+        parser = super(RuleDelete, self).get_parser(prog_name)
+        parser.add_argument(
+            'relation',
+            metavar='<relation-uuid>',
+            help='Relation UUID',
+        )
+        parser.add_argument(
+            'rule',
+            metavar='<argument-list>',
+            help='Rule list (example: admin,vm_admin,servers)',
+        )
+        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
+        rule = "+".join(parsed_args.rule.split(","))
+        data = self.app.get_url(
+            "/v3/OS-MOON/intra_extensions/{intra_extensions_id}/sub_rules/{relation_name}/{rule}".format(
+                intra_extensions_id=parsed_args.intraextension,
+                relation_name=parsed_args.relation,
+                rule=rule,
+            ),
+            method="DELETE",
+            authtoken=True)
+        if "sub_rules" not in data:
+            raise Exception("Error in command {}: {}".format("RuleDelete", data))
+        return (
+            ("sub_rules",),
+            (data["sub_rules"],)
+        )
diff --git a/moonclient/moonclient/shell.py b/moonclient/moonclient/shell.py
new file mode 100644 (file)
index 0000000..406e0a7
--- /dev/null
@@ -0,0 +1,152 @@
+# 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'.
+
+import logging
+import sys
+import json
+import httplib
+import os
+
+from cliff.app import App
+from cliff.commandmanager import CommandManager
+
+
+def get_env_creds(admin_token=False):
+    d = dict()
+    if 'OS_SERVICE_ENDPOINT' in os.environ.keys() or 'OS_USERNAME' in os.environ.keys():
+        if admin_token:
+            d['endpoint'] = os.environ['OS_SERVICE_ENDPOINT']
+            d['token'] = os.environ['OS_SERVICE_TOKEN']
+        else:
+            d['username'] = os.environ['OS_USERNAME']
+            d['password'] = os.environ['OS_PASSWORD']
+            d['auth_url'] = os.environ['OS_AUTH_URL']
+            d['tenant_name'] = os.environ['OS_TENANT_NAME']
+    return d
+
+
+class MoonClient(App):
+
+    log = logging.getLogger(__name__)
+    x_subject_token = None
+    host = "localhost"
+    port = "35357"
+    tenant = None
+    _intraextension = None
+    post = {
+        "auth": {
+            "identity": {
+                "methods": [
+                    "password"
+                ],
+                "password": {
+                    "user": {
+                        "domain": {
+                            "id": "Default"
+                        },
+                        "name": "admin",
+                        "password": "nomoresecrete"
+                    }
+                }
+            },
+            "scope": {
+                "project": {
+                    "domain": {
+                        "id": "Default"
+                    },
+                    "name": "demo"
+                }
+            }
+        }
+    }
+
+    def __init__(self):
+        super(MoonClient, self).__init__(
+            description='Moon Python Client',
+            version='0.1',
+            command_manager=CommandManager('moon.client'),
+            )
+        creds = get_env_creds()
+        self.post["auth"]["identity"]["password"]["user"]["password"] = creds["password"]
+        self.post["auth"]["identity"]["password"]["user"]["name"] = creds["username"]
+        self.post["auth"]["scope"]["project"]["name"] = creds["tenant_name"]
+        self.host = creds["auth_url"].replace("https://", "").replace("http://", "").split("/")[0].split(":")[0]
+        self.port = creds["auth_url"].replace("https://", "").replace("http://", "").split("/")[0].split(":")[1]
+        self.tenant = creds["tenant_name"]
+
+    @property
+    def intraextension(self):
+        if not self._intraextension:
+            project = self.get_url("/v3/projects?name={}".format(self.tenant), authtoken=True)["projects"][0]["id"]
+            self.log.debug("project={}".format(project))
+            data = self.get_url("/v3/OS-MOON/intra_extensions", authtoken=True)
+            for uuid in data["intra_extensions"]:
+                ie = self.get_url("/v3/OS-MOON/intra_extensions/{}".format(uuid), authtoken=True)
+                if ie["intra_extensions"]["tenant"] == project:
+                    self._intraextension = uuid
+                    self.tenant = project
+                    break
+        return self._intraextension
+
+    def get_url(self, url, post_data=None, delete_data=None, method="GET", authtoken=None):
+        if post_data:
+            method = "POST"
+        if delete_data:
+            method = "DELETE"
+        self.log.debug("\033[32m{} {}\033[m".format(method, url))
+        conn = httplib.HTTPConnection(self.host, self.port)
+        headers = {
+            "Content-type": "application/x-www-form-urlencoded",
+            "Accept": "text/plain,text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8",
+        }
+        if authtoken:
+            if self.x_subject_token:
+                headers["X-Auth-Token"] = self.x_subject_token
+        if post_data:
+            method = "POST"
+            headers["Content-type"] = "application/json"
+            post_data = json.dumps(post_data)
+            conn.request(method, url, post_data, headers=headers)
+        elif delete_data:
+            method = "DELETE"
+            conn.request(method, url, json.dumps(delete_data), headers=headers)
+        else:
+            conn.request(method, url, headers=headers)
+        resp = conn.getresponse()
+        headers = resp.getheaders()
+        try:
+            self.x_subject_token = dict(headers)["x-subject-token"]
+        except KeyError:
+            pass
+        content = resp.read()
+        conn.close()
+        try:
+            return json.loads(content)
+        except ValueError:
+            return {"content": content}
+
+    def initialize_app(self, argv):
+        self.log.debug('initialize_app: {}'.format(argv))
+        # TODO: get credentials from OS env
+        data = self.get_url("/v3/auth/tokens", post_data=self.post)
+        if "token" not in data:
+            raise Exception("Authentication problem ({})".format(data))
+
+    def prepare_to_run_command(self, cmd):
+        self.log.debug('prepare_to_run_command %s', cmd.__class__.__name__)
+
+    def clean_up(self, cmd, result, err):
+        self.log.debug('clean_up %s', cmd.__class__.__name__)
+        if err:
+            self.log.debug('got an error: %s', err)
+
+
+def main(argv=sys.argv[1:]):
+    myapp = MoonClient()
+    return myapp.run(argv)
+
+
+if __name__ == '__main__':
+    sys.exit(main(sys.argv[1:]))
diff --git a/moonclient/moonclient/subject_assignments.py b/moonclient/moonclient/subject_assignments.py
new file mode 100644 (file)
index 0000000..0b3e605
--- /dev/null
@@ -0,0 +1,125 @@
+# 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'.
+
+import logging
+
+from cliff.lister import Lister
+from cliff.command import Command
+
+
+class SubjectAssignmentsList(Lister):
+    """List all Intra_Extensions."""
+
+    log = logging.getLogger(__name__)
+
+    def get_parser(self, prog_name):
+        parser = super(SubjectAssignmentsList, 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/{}/subject_assignments".format(parsed_args.intraextension),
+                                authtoken=True)
+        if "subject_assignments" not in data:
+            raise Exception("Error in command {}: {}".format("SubjectAssignmentsList", data))
+        return (
+            ("category", "value"),
+            ((_cat, str(_val)) for _cat, _val in data["subject_assignments"].items())
+        )
+
+
+class SubjectAssignmentsAdd(Command):
+    """List all Intra_Extensions."""
+
+    log = logging.getLogger(__name__)
+
+    def get_parser(self, prog_name):
+        parser = super(SubjectAssignmentsAdd, self).get_parser(prog_name)
+        parser.add_argument(
+            'subject_id',
+            metavar='<subject-uuid>',
+            help='Subject UUID',
+        )
+        parser.add_argument(
+            'subject_category',
+            metavar='<subject_category>',
+            help='Subject Category',
+        )
+        parser.add_argument(
+            'subject_category_scope',
+            metavar='<subject_category_scope>',
+            help='Subject Category Scope',
+        )
+        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/{}/subject_assignments".format(parsed_args.intraextension),
+                                post_data={
+                                    "subject_id": parsed_args.subject_id,
+                                    "subject_category": parsed_args.subject_category,
+                                    "subject_category_scope": parsed_args.subject_category_scope
+                                },
+                                authtoken=True)
+        if "subject_assignments" not in data:
+            raise Exception("Error in command {}".format(data))
+        return (
+            ("category", "value"),
+            ((_cat, str(_val)) for _cat, _val in data["subject_assignments"].items())
+        )
+
+
+class SubjectAssignmentsDelete(Command):
+    """List all Intra_Extensions."""
+
+    log = logging.getLogger(__name__)
+
+    def get_parser(self, prog_name):
+        parser = super(SubjectAssignmentsDelete, self).get_parser(prog_name)
+        parser.add_argument(
+            'subject_id',
+            metavar='<subject-uuid>',
+            help='Subject UUID',
+        )
+        parser.add_argument(
+            'subject_category',
+            metavar='<subject_category>',
+            help='Subject Category',
+        )
+        parser.add_argument(
+            'subject_category_scope',
+            metavar='<subject_category_scope>',
+            help='Subject Category Scope',
+        )
+        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
+        self.app.get_url("/v3/OS-MOON/intra_extensions/{}/subject_assignments/{}/{}/{}".format(
+            parsed_args.intraextension,
+            parsed_args.subject_id,
+            parsed_args.subject_category,
+            parsed_args.subject_category_scope
+        ),
+            method="DELETE",
+            authtoken=True)
\ No newline at end of file
diff --git a/moonclient/moonclient/subject_categories.py b/moonclient/moonclient/subject_categories.py
new file mode 100644 (file)
index 0000000..93f56bd
--- /dev/null
@@ -0,0 +1,99 @@
+# 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'.
+
+import logging
+
+from cliff.lister import Lister
+from cliff.command import Command
+
+
+class SubjectCategoriesList(Lister):
+    """List all Intra_Extensions."""
+
+    log = logging.getLogger(__name__)
+
+    def get_parser(self, prog_name):
+        parser = super(SubjectCategoriesList, 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/{}/subject_categories".format(parsed_args.intraextension),
+                                authtoken=True)
+        if "subject_categories" not in data:
+            raise Exception("Error in command {}: {}".format("SubjectCategoriesList", data))
+        return (
+            ("subject_categories",),
+            ((_uuid, ) for _uuid in data["subject_categories"])
+        )
+
+
+class SubjectCategoriesAdd(Command):
+    """List all Intra_Extensions."""
+
+    log = logging.getLogger(__name__)
+
+    def get_parser(self, prog_name):
+        parser = super(SubjectCategoriesAdd, self).get_parser(prog_name)
+        parser.add_argument(
+            'subject_category',
+            metavar='<subject_category-uuid>',
+            help='Subject UUID',
+        )
+        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/{}/subject_categories".format(parsed_args.intraextension),
+                                post_data={"subject_category_id": parsed_args.subject_category},
+                                authtoken=True)
+        if "subject_categories" not in data:
+            raise Exception("Error in command {}".format(data))
+        return (
+            ("subject_categories",),
+            ((_uuid, ) for _uuid in data["subject_categories"])
+        )
+
+
+class SubjectCategoriesDelete(Command):
+    """List all Intra_Extensions."""
+
+    log = logging.getLogger(__name__)
+
+    def get_parser(self, prog_name):
+        parser = super(SubjectCategoriesDelete, self).get_parser(prog_name)
+        parser.add_argument(
+            'subject_category',
+            metavar='<subject_category-uuid>',
+            help='Subject UUID',
+        )
+        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
+        self.app.get_url("/v3/OS-MOON/intra_extensions/{}/subject_categories/{}".format(
+            parsed_args.intraextension,
+            parsed_args.subject_category
+        ),
+            method="DELETE",
+            authtoken=True)
\ No newline at end of file
diff --git a/moonclient/moonclient/subject_category_scope.py b/moonclient/moonclient/subject_category_scope.py
new file mode 100644 (file)
index 0000000..6f99a33
--- /dev/null
@@ -0,0 +1,113 @@
+# 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'.
+
+import logging
+
+from cliff.lister import Lister
+from cliff.command import Command
+
+
+class SubjectCategoryScopeList(Lister):
+    """List all Intra_Extensions."""
+
+    log = logging.getLogger(__name__)
+
+    def get_parser(self, prog_name):
+        parser = super(SubjectCategoryScopeList, 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/{}/subject_category_scope".format(parsed_args.intraextension),
+                                authtoken=True)
+        if "subject_category_scope" not in data:
+            raise Exception("Error in command {}: {}".format("SubjectCategoryScopeList", data))
+        return (
+            ("subject_category", "subject_category_scope",),
+            ((_val1, str(_val2)) for _val1, _val2 in data["subject_category_scope"].items())
+        )
+
+
+class SubjectCategoryScopeAdd(Command):
+    """List all Intra_Extensions."""
+
+    log = logging.getLogger(__name__)
+
+    def get_parser(self, prog_name):
+        parser = super(SubjectCategoryScopeAdd, self).get_parser(prog_name)
+        parser.add_argument(
+            'subject_category',
+            metavar='<subject_category-uuid>',
+            help='Subject UUID',
+        )
+        parser.add_argument(
+            'subject_category_scope',
+            metavar='<subject_category_scope-uuid>',
+            help='Subject UUID',
+        )
+        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/{}/subject_category_scope".format(parsed_args.intraextension),
+                                post_data={
+                                    "subject_category_id": parsed_args.subject_category,
+                                    "subject_category_scope_id": parsed_args.subject_category_scope,
+                                },
+                                authtoken=True)
+        if "subject_category_scope" not in data:
+            raise Exception("Error in command {}".format(data))
+        return (
+            ("subject_category", "subject_category_scope",),
+            ((_val1, str(_val2)) for _val1, _val2 in data["subject_category_scope"].items())
+        )
+
+
+class SubjectCategoryScopeDelete(Command):
+    """List all Intra_Extensions."""
+
+    log = logging.getLogger(__name__)
+
+    def get_parser(self, prog_name):
+        parser = super(SubjectCategoryScopeDelete, self).get_parser(prog_name)
+        parser.add_argument(
+            'subject_category',
+            metavar='<subject_category-uuid>',
+            help='Subject UUID',
+        )
+        parser.add_argument(
+            'subject_category_scope',
+            metavar='<subject_category_scope-uuid>',
+            help='Subject UUID',
+        )
+        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
+        self.app.get_url("/v3/OS-MOON/intra_extensions/{}/subject_category_scope/{}/{}".format(
+            parsed_args.intraextension,
+            parsed_args.subject_category,
+            parsed_args.subject_category_scope
+        ),
+            method="DELETE",
+            authtoken=True)
\ No newline at end of file
diff --git a/moonclient/moonclient/subjects.py b/moonclient/moonclient/subjects.py
new file mode 100644 (file)
index 0000000..2198790
--- /dev/null
@@ -0,0 +1,99 @@
+# 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'.
+
+import logging
+
+from cliff.lister import Lister
+from cliff.command import Command
+
+
+class SubjectsList(Lister):
+    """List all Intra_Extensions."""
+
+    log = logging.getLogger(__name__)
+
+    def get_parser(self, prog_name):
+        parser = super(SubjectsList, 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/{}/subjects".format(parsed_args.intraextension),
+                                authtoken=True)
+        if "subjects" not in data:
+            raise Exception("Error in command {}: {}".format("SubjectsList", data))
+        return (
+            ("subjects",),
+            ((_uuid, ) for _uuid in data["subjects"])
+        )
+
+
+class SubjectsAdd(Command):
+    """List all Intra_Extensions."""
+
+    log = logging.getLogger(__name__)
+
+    def get_parser(self, prog_name):
+        parser = super(SubjectsAdd, self).get_parser(prog_name)
+        parser.add_argument(
+            'subject',
+            metavar='<subject-uuid>',
+            help='Subject UUID',
+        )
+        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/{}/subjects".format(parsed_args.intraextension),
+                                post_data={"subject_id": parsed_args.subject},
+                                authtoken=True)
+        if "subjects" not in data:
+            raise Exception("Error in command {}".format(data))
+        return (
+            ("subjects",),
+            ((_uuid, ) for _uuid in data["subjects"])
+        )
+
+
+class SubjectsDelete(Command):
+    """List all Intra_Extensions."""
+
+    log = logging.getLogger(__name__)
+
+    def get_parser(self, prog_name):
+        parser = super(SubjectsDelete, self).get_parser(prog_name)
+        parser.add_argument(
+            'subject',
+            metavar='<subject-uuid>',
+            help='Subject UUID',
+        )
+        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
+        self.app.get_url("/v3/OS-MOON/intra_extensions/{}/subjects/{}".format(
+            parsed_args.intraextension,
+            parsed_args.subject
+        ),
+            method="DELETE",
+            authtoken=True)
\ No newline at end of file
diff --git a/moonclient/moonclient/tests/functional_tests.sh b/moonclient/moonclient/tests/functional_tests.sh
new file mode 100644 (file)
index 0000000..789b916
--- /dev/null
@@ -0,0 +1,131 @@
+#!/bin/sh
+
+# 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'.
+
+
+PROG=moon
+OS_TENANT_NAME=demo
+DEMO_USER=$(keystone user-list | awk '/ demo / {print $2}')
+
+# must be authenticated with Keystone
+# ie. : "cd ~/devstack; . openrc admin"
+
+function test_cmd {
+    echo -e "\033[33m$PROG $1\033[m"
+    $PROG $1 | tee /tmp/_
+    if [ $? != 0 ]; then
+        echo -e "\033[31mError for test \"$1\" \033[m"
+        exit 1
+    fi
+}
+
+test_cmd "intraextension list"
+test_cmd "intraextension create --policy_model policy_rbac func_test"
+uuid=$(cat /tmp/_ | cut -d " " -f 3)
+test_cmd "intraextension tenant set $uuid $OS_TENANT_NAME"
+test_cmd "intraextension show $uuid"
+
+test_cmd "subjects list"
+test_cmd "subjects add $DEMO_USER"
+test_cmd "subjects list"
+
+test_cmd "objects list"
+test_cmd "objects add my_obj"
+test_cmd "objects list"
+
+test_cmd "actions list"
+test_cmd "actions add my_action"
+test_cmd "actions list"
+
+# Category
+
+test_cmd "subject categories list"
+test_cmd "subject categories add my_cat"
+test_cmd "subject categories list"
+
+test_cmd "object categories list"
+test_cmd "object categories add my_cat"
+test_cmd "object categories list"
+
+test_cmd "action categories list"
+test_cmd "action categories add my_cat"
+test_cmd "action categories list"
+
+# Category scope
+
+test_cmd "subject category scope list"
+test_cmd "subject category scope add my_cat my_scope"
+test_cmd "subject category scope list"
+
+test_cmd "object category scope list"
+test_cmd "object category scope add my_cat my_scope"
+test_cmd "object category scope list"
+
+test_cmd "action category scope list"
+test_cmd "action category scope add my_cat my_scope"
+test_cmd "action category scope list"
+
+# Assignments
+
+test_cmd "subject assignments list"
+test_cmd "subject assignments add $DEMO_USER my_cat my_scope"
+test_cmd "subject assignments list"
+
+test_cmd "object assignments list"
+test_cmd "object assignments add my_obj my_cat my_scope"
+test_cmd "object assignments list"
+
+test_cmd "action assignments list"
+test_cmd "action assignments add my_action my_cat my_scope"
+test_cmd "action assignments list"
+
+# Sub meta rules
+
+test_cmd "aggregation algorithms list"
+test_cmd "aggregation algorithm show"
+test_cmd "aggregation algorithm set test_aggregation"
+test_cmd "aggregation algorithm show"
+test_cmd "submetarule show"
+test_cmd "submetarule set relation_super subject_security_level,my_cat computing_action,my_cat object_security_level,my_cat"
+test_cmd "submetarule show"
+test_cmd "submetarule relation list"
+
+# Rules
+
+test_cmd "rules list"
+test_cmd "rules add relation_super high,my_scope,vm_access,my_scope,high,my_scope"
+test_cmd "rules delete relation_super high,my_scope,vm_access,my_scope,high,my_scope"
+
+#Delete all
+test_cmd "subject assignments delete $DEMO_USER my_cat my_scope"
+test_cmd "subject assignments list"
+test_cmd "object assignments delete my_obj my_cat my_scope"
+test_cmd "object assignments list"
+test_cmd "action assignments delete my_action my_cat my_scope"
+test_cmd "action assignments list"
+
+test_cmd "subject category scope delete my_cat my_scope"
+test_cmd "subject category scope list"
+test_cmd "object category scope delete my_cat my_scope"
+test_cmd "object category scope list"
+test_cmd "action category scope delete my_cat my_scope"
+test_cmd "action category scope list"
+
+test_cmd "subjects delete $DEMO_USER"
+test_cmd "subjects list"
+test_cmd "objects delete my_obj"
+test_cmd "objects list"
+test_cmd "actions delete my_action"
+test_cmd "actions list"
+test_cmd "subject categories delete my_cat"
+test_cmd "subject categories list"
+test_cmd "object categories delete my_cat"
+test_cmd "object categories list"
+test_cmd "action categories delete my_cat"
+test_cmd "action categories list"
+
+
+test_cmd "intraextension delete $uuid"
\ No newline at end of file
diff --git a/moonclient/python_moonclient.egg-info/PKG-INFO b/moonclient/python_moonclient.egg-info/PKG-INFO
new file mode 100644 (file)
index 0000000..271dc83
--- /dev/null
@@ -0,0 +1,22 @@
+Metadata-Version: 1.1
+Name: python-moonclient
+Version: 0.1
+Summary: Python Moon client
+Home-page: https://github.com/...
+Author: Thomas Duval
+Author-email: thomas.duval@orange.com
+License: UNKNOWN
+Download-URL: https://github.com/.../tarball/master
+Description: Moon Client
+        
+        
+Platform: Any
+Classifier: Development Status :: 3 - Alpha
+Classifier: License :: OSI Approved :: Apache Software License
+Classifier: Programming Language :: Python
+Classifier: Programming Language :: Python :: 2
+Classifier: Programming Language :: Python :: 2.7
+Classifier: Programming Language :: Python :: 3
+Classifier: Programming Language :: Python :: 3.2
+Classifier: Intended Audience :: Developers
+Classifier: Environment :: Console
diff --git a/moonclient/python_moonclient.egg-info/SOURCES.txt b/moonclient/python_moonclient.egg-info/SOURCES.txt
new file mode 100644 (file)
index 0000000..4b0096d
--- /dev/null
@@ -0,0 +1,33 @@
+MANIFEST.in
+README.rst
+setup.cfg
+setup.py
+moonclient/__init__.py
+moonclient/action_assignments.py
+moonclient/action_categories.py
+moonclient/action_category_scope.py
+moonclient/actions.py
+moonclient/authz_policies.py
+moonclient/intraextension.py
+moonclient/logs.py
+moonclient/metarules.py
+moonclient/object_assignments.py
+moonclient/object_categories.py
+moonclient/object_category_scope.py
+moonclient/objects.py
+moonclient/rules.py
+moonclient/shell.py
+moonclient/subject_assignments.py
+moonclient/subject_categories.py
+moonclient/subject_category_scope.py
+moonclient/subjects.py
+moonclient/tests/functional_tests.sh
+python_moonclient.egg-info/PKG-INFO
+python_moonclient.egg-info/SOURCES.txt
+python_moonclient.egg-info/dependency_links.txt
+python_moonclient.egg-info/entry_points.txt
+python_moonclient.egg-info/namespace_packages.txt
+python_moonclient.egg-info/not-zip-safe
+python_moonclient.egg-info/pbr.json
+python_moonclient.egg-info/requires.txt
+python_moonclient.egg-info/top_level.txt
\ No newline at end of file
diff --git a/moonclient/python_moonclient.egg-info/dependency_links.txt b/moonclient/python_moonclient.egg-info/dependency_links.txt
new file mode 100644 (file)
index 0000000..8b13789
--- /dev/null
@@ -0,0 +1 @@
+
diff --git a/moonclient/python_moonclient.egg-info/entry_points.txt b/moonclient/python_moonclient.egg-info/entry_points.txt
new file mode 100644 (file)
index 0000000..2075f10
--- /dev/null
@@ -0,0 +1,57 @@
+[moon.client]
+actions_list = moonclient.actions:ActionsList
+subject_categories_delete = moonclient.subject_categories:SubjectCategoriesDelete
+objects_delete = moonclient.objects:ObjectsDelete
+submetarule_show = moonclient.metarules:SubMetaRuleShow
+actions_add = moonclient.actions:ActionsAdd
+subjects_add = moonclient.subjects:SubjectsAdd
+subject_category_scope_add = moonclient.subject_category_scope:SubjectCategoryScopeAdd
+intraextension_show = moonclient.intraextension:IntraExtensionShow
+rules_add = moonclient.rules:RuleAdd
+subject_categories_list = moonclient.subject_categories:SubjectCategoriesList
+action_categories_delete = moonclient.action_categories:ActionCategoriesDelete
+subjects_delete = moonclient.subjects:SubjectsDelete
+action_category_scope_list = moonclient.action_category_scope:ActionCategoryScopeList
+subject_category_scope_delete = moonclient.subject_category_scope:SubjectCategoryScopeDelete
+subjects_list = moonclient.subjects:SubjectsList
+object_assignments_delete = moonclient.object_assignments:ObjectAssignmentsDelete
+subject_category_scope_list = moonclient.subject_category_scope:SubjectCategoryScopeList
+intraextension_delete = moonclient.intraextension:IntraExtensionDelete
+rules_list = moonclient.rules:RulesList
+logs = moonclient.logs:LogsList
+actions_delete = moonclient.actions:ActionsDelete
+object_assignments_list = moonclient.object_assignments:ObjectAssignmentsList
+object_category_scope_delete = moonclient.object_category_scope:ObjectCategoryScopeDelete
+policies_list = moonclient.authz_policies:AuthzPolicies
+subject_categories_add = moonclient.subject_categories:SubjectCategoriesAdd
+intraextension_tenant_set = moonclient.intraextension:TenantSet
+subject_assignments_add = moonclient.subject_assignments:SubjectAssignmentsAdd
+object_categories_delete = moonclient.object_categories:ObjectCategoriesDelete
+intraextension_create = moonclient.intraextension:IntraExtensionCreate
+object_category_scope_add = moonclient.object_category_scope:ObjectCategoryScopeAdd
+intraextension_list = moonclient.intraextension:IntraExtensionList
+action_assignments_list = moonclient.action_assignments:ActionAssignmentsList
+action_assignments_delete = moonclient.action_assignments:ActionAssignmentsDelete
+aggregation_algorithms_list = moonclient.metarules:AggregationAlgorithmsList
+action_assignments_add = moonclient.action_assignments:ActionAssignmentsAdd
+submetarule_set = moonclient.metarules:SubMetaRuleSet
+action_categories_list = moonclient.action_categories:ActionCategoriesList
+objects_add = moonclient.objects:ObjectsAdd
+object_assignments_add = moonclient.object_assignments:ObjectAssignmentsAdd
+action_categories_add = moonclient.action_categories:ActionCategoriesAdd
+object_categories_add = moonclient.object_categories:ObjectCategoriesAdd
+aggregation_algorithm_set = moonclient.metarules:AggregationAlgorithmSet
+subject_assignments_delete = moonclient.subject_assignments:SubjectAssignmentsDelete
+submetarule_relation_list = moonclient.metarules:SubMetaRuleRelationList
+action_category_scope_delete = moonclient.action_category_scope:ActionCategoryScopeDelete
+action_category_scope_add = moonclient.action_category_scope:ActionCategoryScopeAdd
+rules_delete = moonclient.rules:RuleDelete
+subject_assignments_list = moonclient.subject_assignments:SubjectAssignmentsList
+aggregation_algorithm_show = moonclient.metarules:AggregationAlgorithmShow
+object_categories_list = moonclient.object_categories:ObjectCategoriesList
+objects_list = moonclient.objects:ObjectsList
+object_category_scope_list = moonclient.object_category_scope:ObjectCategoryScopeList
+
+[console_scripts]
+moon = moonclient.shell:main
+
diff --git a/moonclient/python_moonclient.egg-info/namespace_packages.txt b/moonclient/python_moonclient.egg-info/namespace_packages.txt
new file mode 100644 (file)
index 0000000..8b13789
--- /dev/null
@@ -0,0 +1 @@
+
diff --git a/moonclient/python_moonclient.egg-info/not-zip-safe b/moonclient/python_moonclient.egg-info/not-zip-safe
new file mode 100644 (file)
index 0000000..8b13789
--- /dev/null
@@ -0,0 +1 @@
+
diff --git a/moonclient/python_moonclient.egg-info/pbr.json b/moonclient/python_moonclient.egg-info/pbr.json
new file mode 100644 (file)
index 0000000..b5537aa
--- /dev/null
@@ -0,0 +1 @@
+{"is_release": false, "git_version": "ab3fa18"}
\ No newline at end of file
diff --git a/moonclient/python_moonclient.egg-info/requires.txt b/moonclient/python_moonclient.egg-info/requires.txt
new file mode 100644 (file)
index 0000000..4ba1219
--- /dev/null
@@ -0,0 +1 @@
+cliff
\ No newline at end of file
diff --git a/moonclient/python_moonclient.egg-info/top_level.txt b/moonclient/python_moonclient.egg-info/top_level.txt
new file mode 100644 (file)
index 0000000..aeaf609
--- /dev/null
@@ -0,0 +1 @@
+moonclient
diff --git a/moonclient/requirements.txt b/moonclient/requirements.txt
new file mode 100644 (file)
index 0000000..298dfec
--- /dev/null
@@ -0,0 +1,3 @@
+pbr>=0.6,!=0.7,<1.0
+cliff>=1.7.0 # Apache-2.0
+cliff-tablib>=1.0
diff --git a/moonclient/setup.cfg b/moonclient/setup.cfg
new file mode 100644 (file)
index 0000000..f2b8f4f
--- /dev/null
@@ -0,0 +1,60 @@
+[metadata]
+name = moonclient
+summary = Python client for the Moon API
+description-file =
+    README.rst
+author = Orange
+author-email = thomas.duval@orange.com
+home-page = http://orange.com
+classifier =
+    Environment :: OpenStack
+    Intended Audience :: Information Technology
+    Intended Audience :: System Administrators
+    License :: OSI Approved :: Apache Software License
+    Operating System :: POSIX :: Linux
+    Programming Language :: Python
+    Programming Language :: Python :: 2
+    Programming Language :: Python :: 2.7
+    Programming Language :: Python :: 2.6
+    Programming Language :: Python :: 3
+    Programming Language :: Python :: 3.3
+
+[files]
+packages =
+    moonclient
+
+[global]
+setup-hooks =
+    pbr.hooks.setup_hook
+
+[entry_points]
+console_scripts =
+    openstack = moonclient.shell:main
+
+openstack.cli.base =
+    intraextension = moonclient.intraextension:IntraExtension
+
+;[build_sphinx]
+;source-dir = doc/source
+;build-dir = doc/build
+;all_files = 1
+;
+;[upload_sphinx]
+;upload-dir = doc/build/html
+;
+;[compile_catalog]
+;directory = moonclient/locale
+;domain = moonclient
+;
+;[update_catalog]
+;domain = moonclient
+;output_dir = moonclient/locale
+;input_file = moonclient/locale/moonclient.pot
+;
+;[extract_messages]
+;keywords = _ gettext ngettext l_ lazy_gettext
+;mapping_file = babel.cfg
+;output_file = moonclient/locale/moonclient.pot
+;
+[wheel]
+universal = 1
diff --git a/moonclient/setup.py b/moonclient/setup.py
new file mode 100644 (file)
index 0000000..e88d3a0
--- /dev/null
@@ -0,0 +1,117 @@
+#!/usr/bin/env python
+
+
+# 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'.
+
+PROJECT = 'python-moonclient'
+
+# Change docs/sphinx/conf.py too!
+VERSION = '0.1'
+
+from setuptools import setup, find_packages
+
+try:
+    long_description = open('README.rst', 'rt').read()
+except IOError:
+    long_description = ''
+
+setup(
+    name=PROJECT,
+    version=VERSION,
+
+    description='Python Moon client',
+    long_description=long_description,
+
+    author='Thomas Duval',
+    author_email='thomas.duval@orange.com',
+
+    url='https://github.com/...',
+    download_url='https://github.com/.../tarball/master',
+
+    classifiers=['Development Status :: 3 - Alpha',
+                 'License :: OSI Approved :: Apache Software License',
+                 'Programming Language :: Python',
+                 'Programming Language :: Python :: 2',
+                 'Programming Language :: Python :: 2.7',
+                 'Programming Language :: Python :: 3',
+                 'Programming Language :: Python :: 3.2',
+                 'Intended Audience :: Developers',
+                 'Environment :: Console',
+                 ],
+
+    platforms=['Any'],
+
+    scripts=[],
+
+    provides=[],
+    install_requires=['cliff'],
+
+    namespace_packages=[],
+    packages=find_packages(),
+    include_package_data=True,
+
+    entry_points={
+        'console_scripts': [
+            'moon = moonclient.shell:main'
+        ],
+        'moon.client': [
+            'policy_list = moonclient.authz_policy:AuthzPolicies',
+            'intraextension_tenant_set = moonclient.intraextension:TenantSet',
+            'intraextension_create = moonclient.intraextension:IntraExtensionCreate',
+            'intraextension_list = moonclient.intraextension:IntraExtensionList',
+            'intraextension_delete = moonclient.intraextension:IntraExtensionDelete',
+            'intraextension_show = moonclient.intraextension:IntraExtensionShow',
+            'subject_list = moonclient.subjects:SubjectsList',
+            'subject_add = moonclient.subjects:SubjectsAdd',
+            'subject_delete = moonclient.subjects:SubjectsDelete',
+            'object_list = moonclient.objects:ObjectsList',
+            'object_add = moonclient.objects:ObjectsAdd',
+            'object_delete = moonclient.objects:ObjectsDelete',
+            'action_list = moonclient.actions:ActionsList',
+            'action_add = moonclient.actions:ActionsAdd',
+            'action_delete = moonclient.actions:ActionsDelete',
+            'action_assignment_list = moonclient.action_assignments:ActionAssignmentsList',
+            'action_assignment_add = moonclient.action_assignments:ActionAssignmentsAdd',
+            'action_assignment_delete = moonclient.action_assignments:ActionAssignmentsDelete',
+            'object_assignment_list = moonclient.object_assignments:ObjectAssignmentsList',
+            'object_assignment_add = moonclient.object_assignments:ObjectAssignmentsAdd',
+            'object_assignment_delete = moonclient.object_assignments:ObjectAssignmentsDelete',
+            'subject_assignment_list = moonclient.subject_assignments:SubjectAssignmentsList',
+            'subject_assignment_add = moonclient.subject_assignments:SubjectAssignmentsAdd',
+            'subject_assignment_delete = moonclient.subject_assignments:SubjectAssignmentsDelete',
+            'subject_category_list = moonclient.subject_categories:SubjectCategoriesList',
+            'subject_category_add = moonclient.subject_categories:SubjectCategoriesAdd',
+            'subject_category_delete = moonclient.subject_categories:SubjectCategoriesDelete',
+            'object_category_list = moonclient.object_categories:ObjectCategoriesList',
+            'object_category_add = moonclient.object_categories:ObjectCategoriesAdd',
+            'object_category_delete = moonclient.object_categories:ObjectCategoriesDelete',
+            'action_category_list = moonclient.action_categories:ActionCategoriesList',
+            'action_category_add = moonclient.action_categories:ActionCategoriesAdd',
+            'action_category_delete = moonclient.action_categories:ActionCategoriesDelete',
+            'subject_category_scope_list = moonclient.subject_category_scope:SubjectCategoryScopeList',
+            'subject_category_scope_add = moonclient.subject_category_scope:SubjectCategoryScopeAdd',
+            'subject_category_scope_delete = moonclient.subject_category_scope:SubjectCategoryScopeDelete',
+            'object_category_scope_list = moonclient.object_category_scope:ObjectCategoryScopeList',
+            'object_category_scope_add = moonclient.object_category_scope:ObjectCategoryScopeAdd',
+            'object_category_scope_delete = moonclient.object_category_scope:ObjectCategoryScopeDelete',
+            'action_category_scope_list = moonclient.action_category_scope:ActionCategoryScopeList',
+            'action_category_scope_add = moonclient.action_category_scope:ActionCategoryScopeAdd',
+            'action_category_scope_delete = moonclient.action_category_scope:ActionCategoryScopeDelete',
+            'aggregation_algorithm_list = moonclient.metarules:AggregationAlgorithmsList',
+            'aggregation_algorithm_show = moonclient.metarules:AggregationAlgorithmShow',
+            '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',
+        ],
+    },
+
+    zip_safe=False,
+)
\ No newline at end of file