aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--INFO13
-rw-r--r--Jenkinsfile2
-rw-r--r--README.md19
-rw-r--r--external_policy_checker/Changelog13
-rw-r--r--external_policy_checker/Dockerfile8
-rw-r--r--external_policy_checker/README.md46
-rw-r--r--external_policy_checker/conf/templates/cinder.policy.json99
-rw-r--r--external_policy_checker/conf/templates/glance.policy.json61
-rw-r--r--external_policy_checker/conf/templates/keystone.policy.json250
-rw-r--r--external_policy_checker/conf/templates/neutron.policy.json235
-rw-r--r--external_policy_checker/conf/templates/nova.policy.json488
-rw-r--r--external_policy_checker/external_policy_checker/__init__.py1
-rw-r--r--external_policy_checker/external_policy_checker/__main__.py9
-rw-r--r--external_policy_checker/external_policy_checker/conf_installer.py83
-rw-r--r--external_policy_checker/external_policy_checker/server.py135
-rw-r--r--external_policy_checker/requirements.txt1
-rw-r--r--external_policy_checker/setup.cfg2
-rw-r--r--external_policy_checker/setup.py47
-rw-r--r--moon_authz/Changelog30
-rw-r--r--moon_authz/Dockerfile11
-rw-r--r--moon_authz/moon_authz/__init__.py2
-rw-r--r--moon_authz/moon_authz/http_server.py5
-rw-r--r--moon_authz/tests/unit_python/mock_pods.py10
-rw-r--r--moon_dashboard/.gitignore1
-rw-r--r--moon_dashboard/.gitlab-ci.yml64
-rw-r--r--moon_dashboard/Dockerfile34
-rw-r--r--moon_dashboard/LICENSE (renamed from moon_manager/tests/unit_python/api/__init__.py)0
-rw-r--r--moon_dashboard/MANIFEST.in3
-rw-r--r--moon_dashboard/README.md40
-rw-r--r--moon_dashboard/README.rst39
-rw-r--r--moon_dashboard/babel-django.cfg5
-rw-r--r--moon_dashboard/babel-djangojs.cfg14
-rw-r--r--moon_dashboard/moon/__init__.py0
-rw-r--r--moon_dashboard/moon/dashboard.py13
-rw-r--r--moon_dashboard/moon/enabled/_32000_moon.py19
-rw-r--r--moon_dashboard/moon/model/__init__.py0
-rw-r--r--moon_dashboard/moon/model/panel.py23
-rw-r--r--moon_dashboard/moon/model/templates/model/index.html16
-rw-r--r--moon_dashboard/moon/model/tests.py19
-rw-r--r--moon_dashboard/moon/model/urls.py20
-rw-r--r--moon_dashboard/moon/model/views.py22
-rw-r--r--moon_dashboard/moon/pdp/__init__.py0
-rw-r--r--moon_dashboard/moon/pdp/panel.py23
-rw-r--r--moon_dashboard/moon/pdp/templates/pdp/index.html16
-rw-r--r--moon_dashboard/moon/pdp/tests.py19
-rw-r--r--moon_dashboard/moon/pdp/urls.py20
-rw-r--r--moon_dashboard/moon/pdp/views.py22
-rw-r--r--moon_dashboard/moon/policy/__init__.py0
-rw-r--r--moon_dashboard/moon/policy/panel.py23
-rw-r--r--moon_dashboard/moon/policy/templates/policy/index.html16
-rw-r--r--moon_dashboard/moon/policy/tests.py19
-rw-r--r--moon_dashboard/moon/policy/urls.py20
-rw-r--r--moon_dashboard/moon/policy/views.py22
-rw-r--r--moon_dashboard/moon/static/moon/js/angular-resource.js863
-rwxr-xr-xmoon_dashboard/moon/static/moon/js/import.service.js27
-rwxr-xr-xmoon_dashboard/moon/static/moon/js/moon.module.js29
-rwxr-xr-xmoon_dashboard/moon/static/moon/js/util.service.js136
-rwxr-xr-xmoon_dashboard/moon/static/moon/js/util.service.spec.js86
-rw-r--r--moon_dashboard/moon/static/moon/model/model.controller.js244
-rw-r--r--moon_dashboard/moon/static/moon/model/model.html143
-rwxr-xr-xmoon_dashboard/moon/static/moon/model/model.service.js286
-rwxr-xr-xmoon_dashboard/moon/static/moon/model/model.service.spec.js288
-rw-r--r--moon_dashboard/moon/static/moon/pdp/pdp.controller.js121
-rw-r--r--moon_dashboard/moon/static/moon/pdp/pdp.html41
-rwxr-xr-xmoon_dashboard/moon/static/moon/pdp/pdp.service.js123
-rwxr-xr-xmoon_dashboard/moon/static/moon/pdp/pdp.service.spec.js143
-rw-r--r--moon_dashboard/moon/static/moon/policy/policy.controller.js295
-rw-r--r--moon_dashboard/moon/static/moon/policy/policy.html158
-rwxr-xr-xmoon_dashboard/moon/static/moon/policy/policy.service.js330
-rwxr-xr-xmoon_dashboard/moon/static/moon/policy/policy.service.spec.js336
-rw-r--r--moon_dashboard/moon/static/moon/scss/moon.scss54
-rw-r--r--moon_dashboard/moon/templates/moon/base.html11
-rw-r--r--moon_dashboard/run.sh26
-rw-r--r--moon_dashboard/setup.cfg24
-rw-r--r--moon_dashboard/setup.py14
-rw-r--r--moon_forming/Changelog11
-rw-r--r--moon_forming/Dockerfile12
-rw-r--r--moon_forming/conf2consul.py2
-rw-r--r--moon_forming/switch.sh19
-rw-r--r--moon_gui/package.json2
-rw-r--r--moon_interface/Changelog32
-rw-r--r--moon_interface/Dockerfile11
-rw-r--r--moon_interface/moon_interface/__init__.py2
-rw-r--r--moon_interface/moon_interface/authz_requests.py1
-rw-r--r--moon_interface/moon_interface/http_server.py2
-rw-r--r--moon_interface/tests/unit_python/api/test_authz.py6
-rw-r--r--moon_interface/tests/unit_python/conftest.py14
-rw-r--r--moon_manager/Changelog42
-rw-r--r--moon_manager/Dockerfile11
-rw-r--r--moon_manager/MANIFEST.in2
-rw-r--r--moon_manager/moon_manager/__init__.py2
-rw-r--r--moon_manager/moon_manager/api/assignments.py197
-rw-r--r--moon_manager/moon_manager/api/base_exception.py18
-rw-r--r--moon_manager/moon_manager/api/data.py184
-rw-r--r--moon_manager/moon_manager/api/json_export.py238
-rw-r--r--moon_manager/moon_manager/api/json_import.py524
-rw-r--r--moon_manager/moon_manager/api/json_utils.py255
-rw-r--r--moon_manager/moon_manager/api/meta_data.py135
-rw-r--r--moon_manager/moon_manager/api/meta_rules.py66
-rw-r--r--moon_manager/moon_manager/api/models.py58
-rw-r--r--moon_manager/moon_manager/api/pdp.py112
-rw-r--r--moon_manager/moon_manager/api/perimeter.py336
-rw-r--r--moon_manager/moon_manager/api/policies.py82
-rw-r--r--moon_manager/moon_manager/api/rules.py51
-rw-r--r--moon_manager/moon_manager/api/slaves.py12
-rw-r--r--moon_manager/moon_manager/http_server.py45
-rw-r--r--moon_manager/moon_manager/server.py1
-rw-r--r--moon_manager/tests/functional_pod/json/mls.json89
-rw-r--r--moon_manager/tests/functional_pod/json/rbac.json85
-rw-r--r--moon_manager/tests/functional_pod/run_functional_tests.sh7
-rw-r--r--moon_manager/tests/functional_pod/test_manager.py39
-rw-r--r--moon_manager/tests/functional_pod/test_models.py5
-rw-r--r--moon_manager/tests/unit_python/api/import_export_utilities.py196
-rw-r--r--moon_manager/tests/unit_python/api/meta_data_test.py44
-rw-r--r--moon_manager/tests/unit_python/api/meta_rules_test.py93
-rw-r--r--moon_manager/tests/unit_python/api/test_assignemnt.py210
-rw-r--r--moon_manager/tests/unit_python/api/test_data.py139
-rw-r--r--moon_manager/tests/unit_python/api/test_export.py282
-rw-r--r--moon_manager/tests/unit_python/api/test_import.py498
-rw-r--r--moon_manager/tests/unit_python/api/test_meta_data.py235
-rw-r--r--moon_manager/tests/unit_python/api/test_meta_rules.py175
-rw-r--r--moon_manager/tests/unit_python/api/test_models.py67
-rw-r--r--moon_manager/tests/unit_python/api/test_pdp.py143
-rw-r--r--moon_manager/tests/unit_python/api/test_perimeter.py292
-rw-r--r--moon_manager/tests/unit_python/api/test_policies.py28
-rw-r--r--moon_manager/tests/unit_python/api/test_rules.py114
-rw-r--r--moon_manager/tests/unit_python/api/test_unit_models.py186
-rw-r--r--moon_manager/tests/unit_python/api/utilities.py22
-rw-r--r--moon_manager/tests/unit_python/conftest.py12
-rw-r--r--moon_manager/tests/unit_python/helpers/__init__.py0
-rw-r--r--moon_manager/tests/unit_python/helpers/assignment_helper.py49
-rw-r--r--moon_manager/tests/unit_python/helpers/category_helper.py40
-rw-r--r--moon_manager/tests/unit_python/helpers/data_builder.py209
-rw-r--r--moon_manager/tests/unit_python/helpers/data_helper.py99
-rw-r--r--moon_manager/tests/unit_python/helpers/meta_rule_helper.py49
-rw-r--r--moon_manager/tests/unit_python/helpers/model_helper.py51
-rw-r--r--moon_manager/tests/unit_python/helpers/pdp_helper.py23
-rw-r--r--moon_manager/tests/unit_python/helpers/policy_helper.py61
-rw-r--r--moon_manager/tests/unit_python/requirements.txt2
-rw-r--r--moon_orchestrator/Changelog4
-rw-r--r--moon_orchestrator/Dockerfile11
-rw-r--r--moon_orchestrator/moon_orchestrator/__init__.py2
-rw-r--r--moon_orchestrator/moon_orchestrator/api/pods.py38
-rw-r--r--moon_orchestrator/moon_orchestrator/drivers.py28
-rw-r--r--moon_orchestrator/moon_orchestrator/http_server.py2
-rw-r--r--moon_orchestrator/tests/unit_python/mock_pods.py13
-rw-r--r--moon_orchestrator/tests/unit_python/test_pods.py154
-rw-r--r--moon_pythonfunctest/Dockerfile9
-rw-r--r--moon_pythonfunctest/README.md8
-rwxr-xr-xmoon_pythonfunctest/run_func_test.sh15
-rw-r--r--moon_pythonunittest/requirements.txt3
-rw-r--r--moon_pythonunittest/run_tests.sh8
-rw-r--r--moon_wrapper/Changelog28
-rw-r--r--moon_wrapper/Dockerfile11
-rw-r--r--moon_wrapper/moon_wrapper/__init__.py2
-rw-r--r--moon_wrapper/moon_wrapper/api/oslowrapper.py16
-rw-r--r--moon_wrapper/moon_wrapper/http_server.py11
-rw-r--r--moon_wrapper/tests/unit_python/api/test_wrapper.py3
-rw-r--r--moon_wrapper/tests/unit_python/conftest.py14
-rw-r--r--python_moonclient/Changelog37
-rw-r--r--python_moonclient/python_moonclient/__init__.py2
-rw-r--r--python_moonclient/python_moonclient/cli/__init__.py0
-rw-r--r--python_moonclient/python_moonclient/cli/authz.py53
-rw-r--r--python_moonclient/python_moonclient/cli/export.py32
-rw-r--r--python_moonclient/python_moonclient/cli/import.py29
-rw-r--r--python_moonclient/python_moonclient/cli/models.py161
-rw-r--r--python_moonclient/python_moonclient/cli/parser.py95
-rw-r--r--python_moonclient/python_moonclient/cli/pdps.py180
-rw-r--r--python_moonclient/python_moonclient/cli/policies.py246
-rw-r--r--python_moonclient/python_moonclient/cli/projects.py56
-rw-r--r--python_moonclient/python_moonclient/cli/slaves.py120
-rw-r--r--python_moonclient/python_moonclient/core/__init__.py0
-rw-r--r--python_moonclient/python_moonclient/core/authz.py (renamed from python_moonclient/python_moonclient/authz.py)2
-rw-r--r--python_moonclient/python_moonclient/core/check_tools.py411
-rw-r--r--python_moonclient/python_moonclient/core/cli_exceptions.py7
-rw-r--r--python_moonclient/python_moonclient/core/config.py (renamed from python_moonclient/python_moonclient/config.py)4
-rw-r--r--python_moonclient/python_moonclient/core/json_export.py26
-rw-r--r--python_moonclient/python_moonclient/core/json_import.py29
-rw-r--r--python_moonclient/python_moonclient/core/models.py (renamed from python_moonclient/python_moonclient/models.py)193
-rw-r--r--python_moonclient/python_moonclient/core/pdp.py (renamed from python_moonclient/python_moonclient/pdp.py)72
-rw-r--r--python_moonclient/python_moonclient/core/policies.py (renamed from python_moonclient/python_moonclient/policies.py)407
-rw-r--r--python_moonclient/python_moonclient/core/slaves.py (renamed from python_moonclient/python_moonclient/slaves.py)27
-rw-r--r--python_moonclient/python_moonclient/moon.py41
-rw-r--r--python_moonclient/python_moonclient/parse.py81
-rw-r--r--python_moonclient/python_moonclient/scripts.py235
-rw-r--r--python_moonclient/requirements.txt3
-rw-r--r--python_moonclient/setup.py37
-rw-r--r--python_moonclient/tests/unit_python/conf/conf_action_assignments.py51
-rw-r--r--python_moonclient/tests/unit_python/conf/conf_action_categories.py32
-rw-r--r--python_moonclient/tests/unit_python/conf/conf_action_data.py66
-rw-r--r--python_moonclient/tests/unit_python/conf/conf_actions.py111
-rw-r--r--python_moonclient/tests/unit_python/conf/conf_all.py1
-rw-r--r--python_moonclient/tests/unit_python/conf/conf_meta_rules.py44
-rw-r--r--python_moonclient/tests/unit_python/conf/conf_models.py94
-rw-r--r--python_moonclient/tests/unit_python/conf/conf_object_assignments.py51
-rw-r--r--python_moonclient/tests/unit_python/conf/conf_object_categories.py31
-rw-r--r--python_moonclient/tests/unit_python/conf/conf_object_data.py67
-rw-r--r--python_moonclient/tests/unit_python/conf/conf_objects.py112
-rw-r--r--python_moonclient/tests/unit_python/conf/conf_pdps.py95
-rw-r--r--python_moonclient/tests/unit_python/conf/conf_policies.py78
-rw-r--r--python_moonclient/tests/unit_python/conf/conf_projects.py44
-rw-r--r--python_moonclient/tests/unit_python/conf/conf_rules.py46
-rw-r--r--python_moonclient/tests/unit_python/conf/conf_subject_assignments.py51
-rw-r--r--python_moonclient/tests/unit_python/conf/conf_subject_categories.py30
-rw-r--r--python_moonclient/tests/unit_python/conf/conf_subject_data.py67
-rw-r--r--python_moonclient/tests/unit_python/conf/conf_subjects.py112
-rw-r--r--python_moonclient/tests/unit_python/conftest.py40
-rw-r--r--python_moonclient/tests/unit_python/mock_config.py29
-rw-r--r--python_moonclient/tests/unit_python/test_config.py8
-rw-r--r--python_moonclient/tests/unit_python/test_models.py3
-rw-r--r--python_moonclient/tests/unit_python/test_pdp.py7
-rw-r--r--python_moonclient/tests/unit_python/test_policies.py10
-rw-r--r--python_moondb/Changelog49
-rw-r--r--python_moondb/MANIFEST.in2
-rw-r--r--python_moondb/python_moondb/__init__.py3
-rw-r--r--python_moondb/python_moondb/api/model.py79
-rw-r--r--python_moondb/python_moondb/api/pdp.py8
-rw-r--r--python_moondb/python_moondb/api/policy.py75
-rw-r--r--python_moondb/python_moondb/backends/sql.py847
-rw-r--r--python_moondb/python_moondb/migrate_repo/versions/001_moon.py75
-rw-r--r--python_moondb/tests/unit_python/helpers/__init__.py0
-rw-r--r--python_moondb/tests/unit_python/helpers/assignment_helper.py49
-rw-r--r--python_moondb/tests/unit_python/helpers/category_helper.py54
-rw-r--r--python_moondb/tests/unit_python/helpers/data_helper.py98
-rw-r--r--python_moondb/tests/unit_python/helpers/meta_rule_helper.py48
-rw-r--r--python_moondb/tests/unit_python/helpers/mock_data.py144
-rw-r--r--python_moondb/tests/unit_python/helpers/model_helper.py50
-rw-r--r--python_moondb/tests/unit_python/helpers/pdp_helper.py23
-rw-r--r--python_moondb/tests/unit_python/helpers/policy_helper.py61
-rw-r--r--python_moondb/tests/unit_python/models/test_categories.py79
-rw-r--r--python_moondb/tests/unit_python/models/test_meta_rules.py161
-rw-r--r--python_moondb/tests/unit_python/models/test_models.py400
-rw-r--r--python_moondb/tests/unit_python/policies/mock_data.py55
-rwxr-xr-xpython_moondb/tests/unit_python/policies/test_assignments.py302
-rwxr-xr-xpython_moondb/tests/unit_python/policies/test_data.py574
-rwxr-xr-xpython_moondb/tests/unit_python/policies/test_policies.py236
-rw-r--r--python_moondb/tests/unit_python/requirements.txt1
-rwxr-xr-xpython_moondb/tests/unit_python/test_pdp.py115
-rw-r--r--python_moonutilities/Changelog16
-rw-r--r--python_moonutilities/Jenkinsfile10
-rw-r--r--python_moonutilities/python_moonutilities/__init__.py2
-rw-r--r--python_moonutilities/python_moonutilities/auth.py76
-rw-r--r--python_moonutilities/python_moonutilities/cache.py25
-rw-r--r--python_moonutilities/python_moonutilities/context.py91
-rw-r--r--python_moonutilities/python_moonutilities/exceptions.py96
-rw-r--r--python_moonutilities/python_moonutilities/security_functions.py111
-rw-r--r--python_moonutilities/tests/unit_python/test_validated_input.py191
-rwxr-xr-x[-rw-r--r--]tests/functional/run_tests.sh11
-rw-r--r--tests/functional/run_tests_for_component.sh4
-rw-r--r--tests/python_unit/run_tests.sh9
-rw-r--r--tools/moon_kubernetes/README.md26
-rw-r--r--tools/moon_kubernetes/conf/moon.conf12
-rw-r--r--tools/moon_kubernetes/init_k8s.sh33
-rw-r--r--tools/moon_kubernetes/init_k8s_moon.sh280
-rw-r--r--tools/moon_kubernetes/start_moon.sh38
-rw-r--r--tools/moon_kubernetes/templates/db.yaml2
-rw-r--r--tools/moon_kubernetes/templates/moon_forming.yaml2
-rw-r--r--tools/moon_kubernetes/templates/moon_functest.yaml (renamed from tools/moon_kubernetes/templates/moon_forming_functest.yaml)7
-rw-r--r--tools/moon_kubernetes/templates/moon_gui.yaml2
-rw-r--r--tools/moon_kubernetes/templates/moon_manager.yaml4
-rw-r--r--tools/moon_kubernetes/templates/moon_orchestrator.yaml2
-rw-r--r--tools/policies/generate_opst_policy.py167
-rw-r--r--tools/policies/policy.json.d/cinder.policy.json104
-rw-r--r--tools/policies/policy.json.d/glance.policy.json63
-rw-r--r--tools/policies/policy.json.d/keystone.policy.json260
-rw-r--r--tools/policies/policy.json.d/neutron.policy.json235
-rw-r--r--tools/policies/policy.json.d/nova.policy.json485
267 files changed, 18721 insertions, 3386 deletions
diff --git a/INFO b/INFO
index 965671d3..d0886418 100644
--- a/INFO
+++ b/INFO
@@ -2,8 +2,8 @@ Project: Security Management Module (Moon)
Project Creation Date: 07 Mai 2015
Project Category: Collaborative Development
Lifecycle State: Incubation
-Primary Contact: ruan.he@orange.com
-Project Lead: ruan.he@orange.com
+Primary Contact: thomas.duval@orange.com
+Project Lead: thomas.duval@orange.com
Jira Project Name: Security Management Module
Jira Project Prefix: MOON
Mailing list tag: [moon]
@@ -11,18 +11,21 @@ IRC: #opnfv-moon
Repository: moon
Contributors:
-ruan.he@orange.com
+rebirthmonkey@gmail.com
jamil.chawki@orange.com
thomas.duval@orange.com
loic.lagadec@ensta-bretagne.fr
ad5939@att.com
marcel.winandy@huawei.com
pyegani@juniper.net
+jonathan.gourdin@orange.com
+rhanafy.ext@orange.com
+rfawzy.ext@orange.com
+mmagraby.ext@orange.com
+francois.cellier@orange.com
Committers:
-ruan (Linux Foundation ID) ruan.he@orange.com
asteroide (Linux Foundation ID) thomas.duval@orange.com: nomination July 3rd 2015
-WuKong (Linux Foundation ID) rebirthmonkey@gmail.com: nomination July 3rd 2015
Link to TSC approval of the project: http://meetbot.opnfv.org/meetings/opnfv-meeting/2015/opnfv-meeting.2015-05-12-13.59.html
Link(s) to approval of additional committers:
diff --git a/Jenkinsfile b/Jenkinsfile
index 42756ece..6bcb8014 100644
--- a/Jenkinsfile
+++ b/Jenkinsfile
@@ -3,7 +3,7 @@ properties([
])
node {
checkout scm
- def packages = ["python_moonutilities","python_moondb","python_moonclient"]
+ def packages = ["python_moonutilities","python_moondb","python_moonclient","moon_manager","moon_wrapper","moon_authz","moon_interface","moon_orchestrator"]
def subtests = [:]
for (x in packages) {
def pkg = x
diff --git a/README.md b/README.md
index 23061d7d..51e5077f 100644
--- a/README.md
+++ b/README.md
@@ -46,7 +46,7 @@ curl http://$MOON_HOST:30001/policies
The Moon platform is fully installed and configured when you have no error with the `moon_get_keystone_projects`:
```bash
sudo pip install python_moonclient --upgrade
-moon_get_keystone_projects
+moon project list
```
### moon_wrapper
@@ -54,21 +54,30 @@ The moon_wrapper component is used to connect OpenStack to the Moon platform.
You need to load one wrapper before connecting OpenStack to Moon.
First of all, get the names of all available slaves:
```bash
-moon_get_slaves
+moon slave list
```
Select the slave you want to configure:
```bash
-moon_set_slave <name_of_the_slave>
+moon slave set <name_of_the_slave>
```
If you don't put a name here, by default, the script will use `kubernetes-admin@kubernetes`
which is the master.
If you need to unload the slave, use the following command:
```bash
-moon_delete_slave <name_of_the_slave>
+moon slave delete <name_of_the_slave>
```
If you don't put a name here, by default, the script will use `kubernetes-admin@kubernetes`.
+### inport/export of the moon database
+Using the moon python client, it is possible to export and import the content of the moon database. The format of the file must be json. Examples of files that can be imported are found in the moon_manager package (rbac.json and mls.json)
+
+The relations between different elements of the json in made using their names. Therefore, the name acts, for now, as a unique identifier in the json files. Importing several times the same json file can lead to unexpected behavior. It is advised to import json file in an empty database.
+
+Two particular entries in the json description are used to specify the way of performing the import:
+ - "mandatory": it can be true or false. This field is only valid for policies description. The policy having this field set to true, will be automatically added to the other elements of the json file that have an empty "policy" field (subject data for instance) or that have a "policies" field which does not already contain the mandatory policy name (such as subjects).
+ - "override" : it can be true or false. This field is only valid for policies and models. If set to true and a policy/model with an identical name already exists in the database, it will be overwritten.
+
## Tests
- [Python Unit Test](tests/python_unit/README.md)
@@ -106,4 +115,4 @@ curl -i \
curl --header "X-Auth-Token: <token_retrieve_from_keystone>" http://moon_hostname:30001
curl --header "X-Auth-Token: <token_retrieve_from_keystone>" http://moon_hostname:30001/pdp
curl --header "X-Auth-Token: <token_retrieve_from_keystone>" http://moon_hostname:30001/policies
-``` \ No newline at end of file
+```
diff --git a/external_policy_checker/Changelog b/external_policy_checker/Changelog
new file mode 100644
index 00000000..cd4ffb7e
--- /dev/null
+++ b/external_policy_checker/Changelog
@@ -0,0 +1,13 @@
+# Copyright 2018 Orange
+# 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
+=======
+
+1.0.0
+-----
+- First version of the external_policy_checker
+
diff --git a/external_policy_checker/Dockerfile b/external_policy_checker/Dockerfile
new file mode 100644
index 00000000..ed013935
--- /dev/null
+++ b/external_policy_checker/Dockerfile
@@ -0,0 +1,8 @@
+FROM python:3
+
+ADD . /root
+RUN pip install -r /root/requirements.txt --upgrade
+WORKDIR /root
+RUN pip install .
+
+CMD ["python", "-m", "moon_bouchon"] \ No newline at end of file
diff --git a/external_policy_checker/README.md b/external_policy_checker/README.md
new file mode 100644
index 00000000..ac44af0e
--- /dev/null
+++ b/external_policy_checker/README.md
@@ -0,0 +1,46 @@
+#External Policy Checker
+
+OpenStack component (like Nova, Glance, Cinder, ...) must populate 3 attributes to allow computing an authorization.
+Those 3 attributes are:
+- target
+- credentials
+- rule
+In all those attributes, we must find the following information:
+- In the 'credentials' attribute:
+ - the user ID: this is given in general by Keystone
+ - the project ID: this is given in general by Keystone
+ - as a proposal, the domain ID: this is given in general by Keystone
+- In the 'target' attribute:
+ - the resource ID (ie nova virtual machine ID, Glance image ID, ...): this must come from the component source of the request (Nova, Glance, …)
+- In the 'rule' attribute:
+ - the action name: this must come from the component source of the request (Nova, Glance, )
+
+This server must be used to verify that all information given from OpenStack components can be retrieved in those attributes.
+
+
+## Usage:
+
+### server
+
+To start the server locally:
+
+ cd external_policy_checker
+ python3 server.py
+
+To start the server as a docker container:
+
+ docker run -ti -p 8080:8080 moon_platform/external_policy_checker:latest
+
+### API
+
+Here are the API, you can request:
+
+ POST /policy_checker
+ POST /authz/grant
+ POST /authz/deny
+
+The `/policy_checker` allows to check if all information can be retrieve.
+The `/authz/grant` will always send a "True" response.
+The `/authz/deny` will always send a "False" response.
+
+
diff --git a/external_policy_checker/conf/templates/cinder.policy.json b/external_policy_checker/conf/templates/cinder.policy.json
new file mode 100644
index 00000000..7716e00b
--- /dev/null
+++ b/external_policy_checker/conf/templates/cinder.policy.json
@@ -0,0 +1,99 @@
+{
+
+ "volume:create": "{{wrapper}}",
+ "volume:delete": "{{wrapper}}",
+ "volume:get": "{{wrapper}}",
+ "volume:get_all": "{{wrapper}}",
+ "volume:get_volume_metadata": "{{wrapper}}",
+ "volume:delete_volume_metadata": "{{wrapper}}",
+ "volume:update_volume_metadata": "{{wrapper}}",
+ "volume:get_volume_admin_metadata": "{{wrapper}}",
+ "volume:update_volume_admin_metadata": "{{wrapper}}",
+ "volume:get_snapshot": "{{wrapper}}",
+ "volume:get_all_snapshots": "{{wrapper}}",
+ "volume:create_snapshot": "{{wrapper}}",
+ "volume:delete_snapshot": "{{wrapper}}",
+ "volume:update_snapshot": "{{wrapper}}",
+ "volume:extend": "{{wrapper}}",
+ "volume:update_readonly_flag": "{{wrapper}}",
+ "volume:retype": "{{wrapper}}",
+ "volume:update": "{{wrapper}}",
+
+ "volume_extension:types_manage": "{{wrapper}}",
+ "volume_extension:types_extra_specs": "{{wrapper}}",
+ "volume_extension:access_types_qos_specs_id": "{{wrapper}}",
+ "volume_extension:access_types_extra_specs": "{{wrapper}}",
+ "volume_extension:volume_type_access": "{{wrapper}}",
+ "volume_extension:volume_type_access:addProjectAccess": "{{wrapper}}",
+ "volume_extension:volume_type_access:removeProjectAccess": "{{wrapper}}",
+ "volume_extension:volume_type_encryption": "{{wrapper}}",
+ "volume_extension:volume_encryption_metadata": "{{wrapper}}",
+ "volume_extension:extended_snapshot_attributes": "{{wrapper}}",
+ "volume_extension:volume_image_metadata": "{{wrapper}}",
+
+ "volume_extension:quotas:show": "{{wrapper}}",
+ "volume_extension:quotas:update": "{{wrapper}}",
+ "volume_extension:quotas:delete": "{{wrapper}}",
+ "volume_extension:quota_classes": "{{wrapper}}",
+ "volume_extension:quota_classes:validate_setup_for_nested_quota_use": "{{wrapper}}",
+
+ "volume_extension:volume_admin_actions:reset_status": "{{wrapper}}",
+ "volume_extension:snapshot_admin_actions:reset_status": "{{wrapper}}",
+ "volume_extension:backup_admin_actions:reset_status": "{{wrapper}}",
+ "volume_extension:volume_admin_actions:force_delete": "{{wrapper}}",
+ "volume_extension:volume_admin_actions:force_detach": "{{wrapper}}",
+ "volume_extension:snapshot_admin_actions:force_delete": "{{wrapper}}",
+ "volume_extension:backup_admin_actions:force_delete": "{{wrapper}}",
+ "volume_extension:volume_admin_actions:migrate_volume": "{{wrapper}}",
+ "volume_extension:volume_admin_actions:migrate_volume_completion": "{{wrapper}}",
+
+ "volume_extension:volume_host_attribute": "{{wrapper}}",
+ "volume_extension:volume_tenant_attribute": "{{wrapper}}",
+ "volume_extension:volume_mig_status_attribute": "{{wrapper}}",
+ "volume_extension:hosts": "{{wrapper}}",
+ "volume_extension:services:index": "{{wrapper}}",
+ "volume_extension:services:update" : "{{wrapper}}",
+
+ "volume_extension:volume_manage": "{{wrapper}}",
+ "volume_extension:volume_unmanage": "{{wrapper}}",
+
+ "volume_extension:capabilities": "{{wrapper}}",
+
+ "volume:create_transfer": "{{wrapper}}",
+ "volume:accept_transfer": "{{wrapper}}",
+ "volume:delete_transfer": "{{wrapper}}",
+ "volume:get_all_transfers": "{{wrapper}}",
+
+ "volume_extension:replication:promote": "{{wrapper}}",
+ "volume_extension:replication:reenable": "{{wrapper}}",
+
+ "volume:enable_replication": "{{wrapper}}",
+ "volume:disable_replication": "{{wrapper}}",
+ "volume:failover_replication": "{{wrapper}}",
+ "volume:list_replication_targets": "{{wrapper}}",
+
+ "backup:create" : "{{wrapper}}",
+ "backup:delete": "{{wrapper}}",
+ "backup:get": "{{wrapper}}",
+ "backup:get_all": "{{wrapper}}",
+ "backup:restore": "{{wrapper}}",
+ "backup:backup-import": "{{wrapper}}",
+ "backup:backup-export": "{{wrapper}}",
+
+ "snapshot_extension:snapshot_actions:update_snapshot_status": "{{wrapper}}",
+ "snapshot_extension:snapshot_manage": "{{wrapper}}",
+ "snapshot_extension:snapshot_unmanage": "{{wrapper}}",
+
+ "consistencygroup:create" : "{{wrapper}}",
+ "consistencygroup:delete": "{{wrapper}}",
+ "consistencygroup:update": "{{wrapper}}",
+ "consistencygroup:get": "{{wrapper}}",
+ "consistencygroup:get_all": "{{wrapper}}",
+
+ "consistencygroup:create_cgsnapshot" : "{{wrapper}}",
+ "consistencygroup:delete_cgsnapshot": "{{wrapper}}",
+ "consistencygroup:get_cgsnapshot": "{{wrapper}}",
+ "consistencygroup:get_all_cgsnapshots": "{{wrapper}}",
+
+ "scheduler_extension:scheduler_stats:get_pools" : "{{wrapper}}"
+}
diff --git a/external_policy_checker/conf/templates/glance.policy.json b/external_policy_checker/conf/templates/glance.policy.json
new file mode 100644
index 00000000..ec79d381
--- /dev/null
+++ b/external_policy_checker/conf/templates/glance.policy.json
@@ -0,0 +1,61 @@
+{
+
+ "add_image": "{{wrapper}}",
+ "delete_image": "{{wrapper}}",
+ "get_image": "{{wrapper}}",
+ "get_images": "{{wrapper}}",
+ "modify_image": "{{wrapper}}",
+ "publicize_image": "{{wrapper}}",
+ "communitize_image": "{{wrapper}}",
+ "copy_from": "{{wrapper}}",
+
+ "download_image": "{{wrapper}}",
+ "upload_image": "{{wrapper}}",
+
+ "delete_image_location": "{{wrapper}}",
+ "get_image_location": "{{wrapper}}",
+ "set_image_location": "{{wrapper}}",
+
+ "add_member": "{{wrapper}}",
+ "delete_member": "{{wrapper}}",
+ "get_member": "{{wrapper}}",
+ "get_members": "{{wrapper}}",
+ "modify_member": "{{wrapper}}",
+
+ "manage_image_cache": "{{wrapper}}",
+
+ "get_task": "{{wrapper}}",
+ "get_tasks": "{{wrapper}}",
+ "add_task": "{{wrapper}}",
+ "modify_task": "{{wrapper}}",
+ "tasks_api_access": "{{wrapper}}",
+
+ "deactivate": "{{wrapper}}",
+ "reactivate": "{{wrapper}}",
+
+ "get_metadef_namespace": "{{wrapper}}",
+ "get_metadef_namespaces":"{{wrapper}}",
+ "modify_metadef_namespace":"{{wrapper}}",
+ "add_metadef_namespace":"{{wrapper}}",
+
+ "get_metadef_object":"{{wrapper}}",
+ "get_metadef_objects":"{{wrapper}}",
+ "modify_metadef_object":"{{wrapper}}",
+ "add_metadef_object":"{{wrapper}}",
+
+ "list_metadef_resource_types":"{{wrapper}}",
+ "get_metadef_resource_type":"{{wrapper}}",
+ "add_metadef_resource_type_association":"{{wrapper}}",
+
+ "get_metadef_property":"{{wrapper}}",
+ "get_metadef_properties":"{{wrapper}}",
+ "modify_metadef_property":"{{wrapper}}",
+ "add_metadef_property":"{{wrapper}}",
+
+ "get_metadef_tag":"{{wrapper}}",
+ "get_metadef_tags":"{{wrapper}}",
+ "modify_metadef_tag":"{{wrapper}}",
+ "add_metadef_tag":"{{wrapper}}",
+ "add_metadef_tags":"{{wrapper}}"
+
+}
diff --git a/external_policy_checker/conf/templates/keystone.policy.json b/external_policy_checker/conf/templates/keystone.policy.json
new file mode 100644
index 00000000..7fc967d5
--- /dev/null
+++ b/external_policy_checker/conf/templates/keystone.policy.json
@@ -0,0 +1,250 @@
+{
+
+ "identity:get_region": "{{wrapper}}",
+ "identity:list_regions": "{{wrapper}}",
+ "identity:create_region": "{{wrapper}}",
+ "identity:update_region": "{{wrapper}}",
+ "identity:delete_region": "{{wrapper}}",
+
+ "identity:get_service": "{{wrapper}}",
+ "identity:list_services": "{{wrapper}}",
+ "identity:create_service": "{{wrapper}}",
+ "identity:update_service": "{{wrapper}}",
+ "identity:delete_service": "{{wrapper}}",
+
+ "identity:get_endpoint": "{{wrapper}}",
+ "identity:list_endpoints": "{{wrapper}}",
+ "identity:create_endpoint": "{{wrapper}}",
+ "identity:update_endpoint": "{{wrapper}}",
+ "identity:delete_endpoint": "{{wrapper}}",
+
+ "identity:get_registered_limit": "{{wrapper}}",
+ "identity:list_registered_limits": "{{wrapper}}",
+ "identity:create_registered_limits": "{{wrapper}}",
+ "identity:update_registered_limits": "{{wrapper}}",
+ "identity:delete_registered_limit": "{{wrapper}}",
+
+ "identity:get_limit": "{{wrapper}}",
+ "identity:list_limits": "{{wrapper}}",
+ "identity:create_limits": "{{wrapper}}",
+ "identity:update_limits": "{{wrapper}}",
+ "identity:delete_limit": "{{wrapper}}",
+
+ "identity:get_domain": "{{wrapper}}",
+ "identity:list_domains": "{{wrapper}}",
+ "identity:create_domain": "{{wrapper}}",
+ "identity:update_domain": "{{wrapper}}",
+ "identity:delete_domain": "{{wrapper}}",
+
+ "admin_and_matching_target_project_domain_id": "{{wrapper}}",
+ "admin_and_matching_project_domain_id": "{{wrapper}}",
+ "identity:get_project": "{{wrapper}}",
+ "identity:list_projects": "{{wrapper}}",
+ "identity:list_user_projects": "{{wrapper}}",
+ "identity:create_project": "{{wrapper}}",
+ "identity:update_project": "{{wrapper}}",
+ "identity:delete_project": "{{wrapper}}",
+ "identity:create_project_tag": "{{wrapper}}",
+ "identity:delete_project_tag": "{{wrapper}}",
+ "identity:get_project_tag": "{{wrapper}}",
+ "identity:list_project_tags": "{{wrapper}}",
+ "identity:delete_project_tags": "{{wrapper}}",
+ "identity:update_project_tags": "{{wrapper}}",
+
+ "admin_and_matching_target_user_domain_id": "{{wrapper}}",
+ "admin_and_matching_user_domain_id": "{{wrapper}}",
+ "identity:get_user": "{{wrapper}}",
+ "identity:list_users": "{{wrapper}}",
+ "identity:create_user": "{{wrapper}}",
+ "identity:update_user": "{{wrapper}}",
+ "identity:delete_user": "{{wrapper}}",
+
+ "admin_and_matching_target_group_domain_id": "{{wrapper}}",
+ "admin_and_matching_group_domain_id": "{{wrapper}}",
+ "identity:get_group": "{{wrapper}}",
+ "identity:list_groups": "{{wrapper}}",
+ "identity:list_groups_for_user": "{{wrapper}}",
+ "identity:create_group": "{{wrapper}}",
+ "identity:update_group": "{{wrapper}}",
+ "identity:delete_group": "{{wrapper}}",
+ "identity:list_users_in_group": "{{wrapper}}",
+ "identity:remove_user_from_group": "{{wrapper}}",
+ "identity:check_user_in_group": "{{wrapper}}",
+ "identity:add_user_to_group": "{{wrapper}}",
+
+ "identity:get_credential": "{{wrapper}}",
+ "identity:list_credentials": "{{wrapper}}",
+ "identity:create_credential": "{{wrapper}}",
+ "identity:update_credential": "{{wrapper}}",
+ "identity:delete_credential": "{{wrapper}}",
+
+ "identity:ec2_get_credential": "{{wrapper}}",
+ "identity:ec2_list_credentials": "{{wrapper}}",
+ "identity:ec2_create_credential": "{{wrapper}}",
+ "identity:ec2_delete_credential": "{{wrapper}}",
+
+ "identity:get_role": "{{wrapper}}",
+ "identity:list_roles": "{{wrapper}}",
+ "identity:create_role": "{{wrapper}}",
+ "identity:update_role": "{{wrapper}}",
+ "identity:delete_role": "{{wrapper}}",
+
+ "identity:get_domain_role": "{{wrapper}}",
+ "identity:list_domain_roles": "{{wrapper}}",
+ "identity:create_domain_role": "{{wrapper}}",
+ "identity:update_domain_role": "{{wrapper}}",
+ "identity:delete_domain_role": "{{wrapper}}",
+ "domain_admin_matches_domain_role": "{{wrapper}}",
+ "get_domain_roles": "{{wrapper}}",
+ "domain_admin_matches_target_domain_role": "{{wrapper}}",
+ "project_admin_matches_target_domain_role": "{{wrapper}}",
+ "list_domain_roles": "{{wrapper}}",
+ "domain_admin_matches_filter_on_list_domain_roles": "{{wrapper}}",
+ "project_admin_matches_filter_on_list_domain_roles": "{{wrapper}}",
+ "admin_and_matching_prior_role_domain_id": "{{wrapper}}",
+ "implied_role_matches_prior_role_domain_or_global": "{{wrapper}}",
+
+ "identity:get_implied_role": "{{wrapper}}",
+ "identity:list_implied_roles": "{{wrapper}}",
+ "identity:create_implied_role": "{{wrapper}}",
+ "identity:delete_implied_role": "{{wrapper}}",
+ "identity:list_role_inference_rules": "{{wrapper}}",
+ "identity:check_implied_role": "{{wrapper}}",
+
+ "identity:list_system_grants_for_user": "{{wrapper}}",
+ "identity:check_system_grant_for_user": "{{wrapper}}",
+ "identity:create_system_grant_for_user": "{{wrapper}}",
+ "identity:revoke_system_grant_for_user": "{{wrapper}}",
+
+ "identity:list_system_grants_for_group": "{{wrapper}}",
+ "identity:check_system_grant_for_group": "{{wrapper}}",
+ "identity:create_system_grant_for_group": "{{wrapper}}",
+ "identity:revoke_system_grant_for_group": "{{wrapper}}",
+
+ "identity:check_grant": "{{wrapper}}",
+ "identity:list_grants": "{{wrapper}}",
+ "identity:create_grant": "{{wrapper}}",
+ "identity:revoke_grant": "{{wrapper}}",
+ "domain_admin_for_grants": "{{wrapper}}",
+ "domain_admin_for_global_role_grants": "{{wrapper}}",
+ "domain_admin_for_domain_role_grants": "{{wrapper}}",
+ "domain_admin_grant_match": "{{wrapper}}",
+ "project_admin_for_grants": "{{wrapper}}",
+ "project_admin_for_global_role_grants": "{{wrapper}}",
+ "project_admin_for_domain_role_grants": "{{wrapper}}",
+ "domain_admin_for_list_grants": "{{wrapper}}",
+ "project_admin_for_list_grants": "{{wrapper}}",
+
+ "admin_on_domain_filter": "{{wrapper}}",
+ "admin_on_project_filter": "{{wrapper}}",
+ "admin_on_domain_of_project_filter": "{{wrapper}}",
+ "identity:list_role_assignments": "{{wrapper}}",
+ "identity:list_role_assignments_for_tree": "{{wrapper}}",
+ "identity:get_policy": "{{wrapper}}",
+ "identity:list_policies": "{{wrapper}}",
+ "identity:create_policy": "{{wrapper}}",
+ "identity:update_policy": "{{wrapper}}",
+ "identity:delete_policy": "{{wrapper}}",
+
+ "identity:check_token": "{{wrapper}}",
+ "identity:validate_token": "{{wrapper}}",
+ "identity:validate_token_head": "{{wrapper}}",
+ "identity:revocation_list": "{{wrapper}}",
+ "identity:revoke_token": "{{wrapper}}",
+
+ "identity:create_trust": "{{wrapper}}",
+ "identity:list_trusts": "{{wrapper}}",
+ "identity:list_roles_for_trust": "{{wrapper}}",
+ "identity:get_role_for_trust": "{{wrapper}}",
+ "identity:delete_trust": "{{wrapper}}",
+ "identity:get_trust": "{{wrapper}}",
+
+ "identity:create_consumer": "{{wrapper}}",
+ "identity:get_consumer": "{{wrapper}}",
+ "identity:list_consumers": "{{wrapper}}",
+ "identity:delete_consumer": "{{wrapper}}",
+ "identity:update_consumer": "{{wrapper}}",
+
+ "identity:authorize_request_token": "{{wrapper}}",
+ "identity:list_access_token_roles": "{{wrapper}}",
+ "identity:get_access_token_role": "{{wrapper}}",
+ "identity:list_access_tokens": "{{wrapper}}",
+ "identity:get_access_token": "{{wrapper}}",
+ "identity:delete_access_token": "{{wrapper}}",
+
+ "identity:list_projects_for_endpoint": "{{wrapper}}",
+ "identity:add_endpoint_to_project": "{{wrapper}}",
+ "identity:check_endpoint_in_project": "{{wrapper}}",
+ "identity:list_endpoints_for_project": "{{wrapper}}",
+ "identity:remove_endpoint_from_project": "{{wrapper}}",
+
+ "identity:create_endpoint_group": "{{wrapper}}",
+ "identity:list_endpoint_groups": "{{wrapper}}",
+ "identity:get_endpoint_group": "{{wrapper}}",
+ "identity:update_endpoint_group": "{{wrapper}}",
+ "identity:delete_endpoint_group": "{{wrapper}}",
+ "identity:list_projects_associated_with_endpoint_group": "{{wrapper}}",
+ "identity:list_endpoints_associated_with_endpoint_group": "{{wrapper}}",
+ "identity:get_endpoint_group_in_project": "{{wrapper}}",
+ "identity:list_endpoint_groups_for_project": "{{wrapper}}",
+ "identity:add_endpoint_group_to_project": "{{wrapper}}",
+ "identity:remove_endpoint_group_from_project": "{{wrapper}}",
+
+ "identity:create_identity_provider": "{{wrapper}}",
+ "identity:list_identity_providers": "{{wrapper}}",
+ "identity:get_identity_provider": "{{wrapper}}",
+ "identity:update_identity_provider": "{{wrapper}}",
+ "identity:delete_identity_provider": "{{wrapper}}",
+
+ "identity:create_protocol": "{{wrapper}}",
+ "identity:update_protocol": "{{wrapper}}",
+ "identity:get_protocol": "{{wrapper}}",
+ "identity:list_protocols": "{{wrapper}}",
+ "identity:delete_protocol": "{{wrapper}}",
+
+ "identity:create_mapping": "{{wrapper}}",
+ "identity:get_mapping": "{{wrapper}}",
+ "identity:list_mappings": "{{wrapper}}",
+ "identity:delete_mapping": "{{wrapper}}",
+ "identity:update_mapping": "{{wrapper}}",
+
+ "identity:create_service_provider": "{{wrapper}}",
+ "identity:list_service_providers": "{{wrapper}}",
+ "identity:get_service_provider": "{{wrapper}}",
+ "identity:update_service_provider": "{{wrapper}}",
+ "identity:delete_service_provider": "{{wrapper}}",
+
+ "identity:get_auth_catalog": "{{wrapper}}",
+ "identity:get_auth_projects": "{{wrapper}}",
+ "identity:get_auth_domains": "{{wrapper}}",
+ "identity:get_auth_system": "{{wrapper}}",
+
+ "identity:list_projects_for_user": "{{wrapper}}",
+ "identity:list_domains_for_user": "{{wrapper}}",
+
+ "identity:list_revoke_events": "{{wrapper}}",
+
+ "identity:create_policy_association_for_endpoint": "{{wrapper}}",
+ "identity:check_policy_association_for_endpoint": "{{wrapper}}",
+ "identity:delete_policy_association_for_endpoint": "{{wrapper}}",
+ "identity:create_policy_association_for_service": "{{wrapper}}",
+ "identity:check_policy_association_for_service": "{{wrapper}}",
+ "identity:delete_policy_association_for_service": "{{wrapper}}",
+ "identity:create_policy_association_for_region_and_service": "{{wrapper}}",
+ "identity:check_policy_association_for_region_and_service": "{{wrapper}}",
+ "identity:delete_policy_association_for_region_and_service": "{{wrapper}}",
+ "identity:get_policy_for_endpoint": "{{wrapper}}",
+ "identity:list_endpoints_for_policy": "{{wrapper}}",
+
+ "identity:create_domain_config": "{{wrapper}}",
+ "identity:get_domain_config": "{{wrapper}}",
+ "identity:get_security_compliance_domain_config": "{{wrapper}}",
+ "identity:update_domain_config": "{{wrapper}}",
+ "identity:delete_domain_config": "{{wrapper}}",
+ "identity:get_domain_config_default": "{{wrapper}}",
+
+ "identity:get_application_credential": "{{wrapper}}",
+ "identity:list_application_credentials": "{{wrapper}}",
+ "identity:create_application_credential": "{{wrapper}}",
+ "identity:delete_application_credential": "{{wrapper}}",
+}
diff --git a/external_policy_checker/conf/templates/neutron.policy.json b/external_policy_checker/conf/templates/neutron.policy.json
new file mode 100644
index 00000000..d0ab0b63
--- /dev/null
+++ b/external_policy_checker/conf/templates/neutron.policy.json
@@ -0,0 +1,235 @@
+{
+ "context_is_admin": "role:admin or user_name:neutron",
+ "owner": "{{wrapper}}",
+ "admin_or_owner": "{{wrapper}}",
+ "context_is_advsvc": "role:advsvc",
+ "admin_or_network_owner": "{{wrapper}}",
+ "admin_owner_or_network_owner": "{{wrapper}}",
+ "admin_only": "{{wrapper}}",
+ "regular_user": "{{wrapper}}",
+ "admin_or_data_plane_int": "{{wrapper}}",
+ "shared": "{{wrapper}}",
+ "shared_subnetpools": "{{wrapper}}",
+ "shared_address_scopes": "{{wrapper}}",
+ "external": "{{wrapper}}",
+ "default": "{{wrapper}}",
+
+ "create_subnet": "{{wrapper}}",
+ "create_subnet:segment_id": "{{wrapper}}",
+ "create_subnet:service_types": "{{wrapper}}",
+ "get_subnet": "{{wrapper}}",
+ "get_subnet:segment_id": "{{wrapper}}",
+ "update_subnet": "{{wrapper}}",
+ "update_subnet:service_types": "{{wrapper}}",
+ "delete_subnet": "{{wrapper}}",
+
+ "create_subnetpool": "{{wrapper}}",
+ "create_subnetpool:shared": "{{wrapper}}",
+ "create_subnetpool:is_default": "{{wrapper}}",
+ "get_subnetpool": "{{wrapper}}",
+ "update_subnetpool": "{{wrapper}}",
+ "update_subnetpool:is_default": "{{wrapper}}",
+ "delete_subnetpool": "{{wrapper}}",
+
+ "create_address_scope": "{{wrapper}}",
+ "create_address_scope:shared": "{{wrapper}}",
+ "get_address_scope": "{{wrapper}}",
+ "update_address_scope": "{{wrapper}}",
+ "update_address_scope:shared": "{{wrapper}}",
+ "delete_address_scope": "{{wrapper}}",
+
+ "create_network": "{{wrapper}}",
+ "get_network": "{{wrapper}}",
+ "get_network:router:external": "{{wrapper}}",
+ "get_network:segments": "{{wrapper}}",
+ "get_network:provider:network_type": "{{wrapper}}",
+ "get_network:provider:physical_network": "{{wrapper}}",
+ "get_network:provider:segmentation_id": "{{wrapper}}",
+ "get_network:queue_id": "{{wrapper}}",
+ "get_network_ip_availabilities": "{{wrapper}}",
+ "get_network_ip_availability": "{{wrapper}}",
+ "create_network:shared": "{{wrapper}}",
+ "create_network:router:external": "{{wrapper}}",
+ "create_network:is_default": "{{wrapper}}",
+ "create_network:segments": "{{wrapper}}",
+ "create_network:provider:network_type": "{{wrapper}}",
+ "create_network:provider:physical_network": "{{wrapper}}",
+ "create_network:provider:segmentation_id": "{{wrapper}}",
+ "update_network": "{{wrapper}}",
+ "update_network:segments": "{{wrapper}}",
+ "update_network:shared": "{{wrapper}}",
+ "update_network:provider:network_type": "{{wrapper}}",
+ "update_network:provider:physical_network": "{{wrapper}}",
+ "update_network:provider:segmentation_id": "{{wrapper}}",
+ "update_network:router:external": "{{wrapper}}",
+ "delete_network": "{{wrapper}}",
+
+ "create_segment": "{{wrapper}}",
+ "get_segment": "{{wrapper}}",
+ "update_segment": "{{wrapper}}",
+ "delete_segment": "{{wrapper}}",
+
+ "network_device": "{{wrapper}}",
+ "create_port": "{{wrapper}}",
+ "create_port:device_owner": "{{wrapper}}",
+ "create_port:mac_address": "{{wrapper}}",
+ "create_port:fixed_ips:ip_address": "{{wrapper}}",
+ "create_port:fixed_ips:subnet_id": "{{wrapper}}",
+ "create_port:port_security_enabled": "{{wrapper}}",
+ "create_port:binding:host_id": "{{wrapper}}",
+ "create_port:binding:profile": "{{wrapper}}",
+ "create_port:mac_learning_enabled": "{{wrapper}}",
+ "create_port:allowed_address_pairs": "{{wrapper}}",
+ "get_port": "{{wrapper}}",
+ "get_port:queue_id": "{{wrapper}}",
+ "get_port:binding:vif_type": "{{wrapper}}",
+ "get_port:binding:vif_details": "{{wrapper}}",
+ "get_port:binding:host_id": "{{wrapper}}",
+ "get_port:binding:profile": "{{wrapper}}",
+ "update_port": "{{wrapper}}",
+ "update_port:device_owner": "{{wrapper}}",
+ "update_port:mac_address": "{{wrapper}}",
+ "update_port:fixed_ips:ip_address": "{{wrapper}}",
+ "update_port:fixed_ips:subnet_id": "{{wrapper}}",
+ "update_port:port_security_enabled": "{{wrapper}}",
+ "update_port:binding:host_id": "{{wrapper}}",
+ "update_port:binding:profile": "{{wrapper}}",
+ "update_port:mac_learning_enabled": "{{wrapper}}",
+ "update_port:allowed_address_pairs": "{{wrapper}}",
+ "update_port:data_plane_status": "{{wrapper}}",
+ "delete_port": "{{wrapper}}",
+
+ "get_router:ha": "{{wrapper}}",
+ "create_router": "{{wrapper}}",
+ "create_router:external_gateway_info:enable_snat": "{{wrapper}}",
+ "create_router:distributed": "{{wrapper}}",
+ "create_router:ha": "{{wrapper}}",
+ "get_router": "{{wrapper}}",
+ "get_router:distributed": "{{wrapper}}",
+ "update_router": "{{wrapper}}",
+ "update_router:external_gateway_info": "{{wrapper}}",
+ "update_router:external_gateway_info:network_id": "{{wrapper}}",
+ "update_router:external_gateway_info:enable_snat": "{{wrapper}}",
+ "update_router:distributed": "{{wrapper}}",
+ "update_router:ha": "{{wrapper}}",
+ "delete_router": "{{wrapper}}",
+
+ "add_router_interface": "{{wrapper}}",
+ "remove_router_interface": "{{wrapper}}",
+
+ "create_router:external_gateway_info:external_fixed_ips": "{{wrapper}}",
+ "update_router:external_gateway_info:external_fixed_ips": "{{wrapper}}",
+
+ "create_qos_queue": "{{wrapper}}",
+ "get_qos_queue": "{{wrapper}}",
+
+ "update_agent": "{{wrapper}}",
+ "delete_agent": "{{wrapper}}",
+ "get_agent": "{{wrapper}}",
+
+ "create_dhcp-network": "{{wrapper}}",
+ "delete_dhcp-network": "{{wrapper}}",
+ "get_dhcp-networks": "{{wrapper}}",
+ "create_l3-router": "{{wrapper}}",
+ "delete_l3-router": "{{wrapper}}",
+ "get_l3-routers": "{{wrapper}}",
+ "get_dhcp-agents": "{{wrapper}}",
+ "get_l3-agents": "{{wrapper}}",
+ "get_loadbalancer-agent": "{{wrapper}}",
+ "get_loadbalancer-pools": "{{wrapper}}",
+ "get_agent-loadbalancers": "{{wrapper}}",
+ "get_loadbalancer-hosting-agent": "{{wrapper}}",
+
+ "create_floatingip": "{{wrapper}}",
+ "create_floatingip:floating_ip_address": "{{wrapper}}",
+ "update_floatingip": "{{wrapper}}",
+ "delete_floatingip": "{{wrapper}}",
+ "get_floatingip": "{{wrapper}}",
+
+ "create_network_profile": "{{wrapper}}",
+ "update_network_profile": "{{wrapper}}",
+ "delete_network_profile": "{{wrapper}}",
+ "get_network_profiles": "{{wrapper}}",
+ "get_network_profile": "{{wrapper}}",
+ "update_policy_profiles": "{{wrapper}}",
+ "get_policy_profiles": "{{wrapper}}",
+ "get_policy_profile": "{{wrapper}}",
+
+ "create_metering_label": "{{wrapper}}",
+ "delete_metering_label": "{{wrapper}}",
+ "get_metering_label": "{{wrapper}}",
+
+ "create_metering_label_rule": "{{wrapper}}",
+ "delete_metering_label_rule": "{{wrapper}}",
+ "get_metering_label_rule": "{{wrapper}}",
+
+ "get_service_provider": "{{wrapper}}",
+ "get_lsn": "{{wrapper}}",
+ "create_lsn": "{{wrapper}}",
+
+ "create_flavor": "{{wrapper}}",
+ "update_flavor": "{{wrapper}}",
+ "delete_flavor": "{{wrapper}}",
+ "get_flavors": "{{wrapper}}",
+ "get_flavor": "{{wrapper}}",
+ "create_service_profile": "{{wrapper}}",
+ "update_service_profile": "{{wrapper}}",
+ "delete_service_profile": "{{wrapper}}",
+ "get_service_profiles": "{{wrapper}}",
+ "get_service_profile": "{{wrapper}}",
+
+ "get_policy": "{{wrapper}}",
+ "create_policy": "{{wrapper}}",
+ "update_policy": "{{wrapper}}",
+ "delete_policy": "{{wrapper}}",
+ "get_policy_bandwidth_limit_rule": "{{wrapper}}",
+ "create_policy_bandwidth_limit_rule": "{{wrapper}}",
+ "delete_policy_bandwidth_limit_rule": "{{wrapper}}",
+ "update_policy_bandwidth_limit_rule": "{{wrapper}}",
+ "get_policy_dscp_marking_rule": "{{wrapper}}",
+ "create_policy_dscp_marking_rule": "{{wrapper}}",
+ "delete_policy_dscp_marking_rule": "{{wrapper}}",
+ "update_policy_dscp_marking_rule": "{{wrapper}}",
+ "get_rule_type": "{{wrapper}}",
+ "get_policy_minimum_bandwidth_rule": "{{wrapper}}",
+ "create_policy_minimum_bandwidth_rule": "{{wrapper}}",
+ "delete_policy_minimum_bandwidth_rule": "{{wrapper}}",
+ "update_policy_minimum_bandwidth_rule": "{{wrapper}}",
+
+ "restrict_wildcard": "{{wrapper}}",
+ "create_rbac_policy": "{{wrapper}}",
+ "create_rbac_policy:target_tenant": "{{wrapper}}",
+ "update_rbac_policy": "{{wrapper}}",
+ "update_rbac_policy:target_tenant": "{{wrapper}}",
+ "get_rbac_policy": "{{wrapper}}",
+ "delete_rbac_policy": "{{wrapper}}",
+
+ "create_flavor_service_profile": "{{wrapper}}",
+ "delete_flavor_service_profile": "{{wrapper}}",
+ "get_flavor_service_profile": "{{wrapper}}",
+ "get_auto_allocated_topology": "{{wrapper}}",
+
+ "create_trunk": "{{wrapper}}",
+ "get_trunk": "{{wrapper}}",
+ "delete_trunk": "{{wrapper}}",
+ "get_subports": "{{wrapper}}",
+ "add_subports": "{{wrapper}}",
+ "remove_subports": "{{wrapper}}",
+
+ "get_security_groups": "{{wrapper}}",
+ "get_security_group": "{{wrapper}}",
+ "create_security_group": "{{wrapper}}",
+ "update_security_group": "{{wrapper}}",
+ "delete_security_group": "{{wrapper}}",
+ "get_security_group_rules": "{{wrapper}}",
+ "get_security_group_rule": "{{wrapper}}",
+ "create_security_group_rule": "{{wrapper}}",
+ "delete_security_group_rule": "{{wrapper}}",
+
+ "get_loggable_resources": "{{wrapper}}",
+ "create_log": "{{wrapper}}",
+ "update_log": "{{wrapper}}",
+ "delete_log": "{{wrapper}}",
+ "get_logs": "{{wrapper}}",
+ "get_log": "{{wrapper}}",
+}
diff --git a/external_policy_checker/conf/templates/nova.policy.json b/external_policy_checker/conf/templates/nova.policy.json
new file mode 100644
index 00000000..e5de675f
--- /dev/null
+++ b/external_policy_checker/conf/templates/nova.policy.json
@@ -0,0 +1,488 @@
+{
+ "context_is_admin": "role:admin",
+ "admin_or_owner": "is_admin:True or project_id:%(project_id)s",
+ "default": "{{wrapper}}",
+
+ "cells_scheduler_filter:TargetCellFilter": "{{wrapper}}",
+
+ "compute:create": "{{wrapper}}",
+ "compute:create:attach_network": "{{wrapper}}",
+ "compute:create:attach_volume": "{{wrapper}}",
+ "compute:create:forced_host": "{{wrapper}}",
+
+ "compute:get": "{{wrapper}}",
+ "compute:get_all": "{{wrapper}}",
+ "compute:get_all_tenants": "{{wrapper}}",
+
+ "compute:update": "{{wrapper}}",
+
+ "compute:get_instance_metadata": "{{wrapper}}",
+ "compute:get_all_instance_metadata": "{{wrapper}}",
+ "compute:get_all_instance_system_metadata": "{{wrapper}}",
+ "compute:update_instance_metadata": "{{wrapper}}",
+ "compute:delete_instance_metadata": "{{wrapper}}",
+
+ "compute:get_instance_faults": "{{wrapper}}",
+ "compute:get_diagnostics": "{{wrapper}}",
+ "compute:get_instance_diagnostics": "{{wrapper}}",
+
+ "compute:start": "{{wrapper}}",
+ "compute:stop": "{{wrapper}}",
+
+ "compute:get_lock": "{{wrapper}}",
+ "compute:lock": "{{wrapper}}",
+ "compute:unlock": "{{wrapper}}",
+ "compute:unlock_override": "{{wrapper}}",
+
+ "compute:get_vnc_console": "{{wrapper}}",
+ "compute:get_spice_console": "{{wrapper}}",
+ "compute:get_rdp_console": "{{wrapper}}",
+ "compute:get_serial_console": "{{wrapper}}",
+ "compute:get_mks_console": "{{wrapper}}",
+ "compute:get_console_output": "{{wrapper}}",
+
+ "compute:reset_network": "{{wrapper}}",
+ "compute:inject_network_info": "{{wrapper}}",
+ "compute:add_fixed_ip": "{{wrapper}}",
+ "compute:remove_fixed_ip": "{{wrapper}}",
+
+ "compute:attach_volume": "{{wrapper}}",
+ "compute:detach_volume": "{{wrapper}}",
+ "compute:swap_volume": "{{wrapper}}",
+
+ "compute:attach_interface": "{{wrapper}}",
+ "compute:detach_interface": "{{wrapper}}",
+
+ "compute:set_admin_password": "{{wrapper}}",
+
+ "compute:rescue": "{{wrapper}}",
+ "compute:unrescue": "{{wrapper}}",
+
+ "compute:suspend": "{{wrapper}}",
+ "compute:resume": "{{wrapper}}",
+
+ "compute:pause": "{{wrapper}}",
+ "compute:unpause": "{{wrapper}}",
+
+ "compute:shelve": "{{wrapper}}",
+ "compute:shelve_offload": "{{wrapper}}",
+ "compute:unshelve": "{{wrapper}}",
+
+ "compute:snapshot": "{{wrapper}}",
+ "compute:snapshot_volume_backed": "{{wrapper}}",
+ "compute:backup": "{{wrapper}}",
+
+ "compute:resize": "{{wrapper}}",
+ "compute:confirm_resize": "{{wrapper}}",
+ "compute:revert_resize": "{{wrapper}}",
+
+ "compute:rebuild": "{{wrapper}}",
+ "compute:reboot": "{{wrapper}}",
+ "compute:delete": "{{wrapper}}",
+ "compute:soft_delete": "{{wrapper}}",
+ "compute:force_delete": "{{wrapper}}",
+
+ "compute:security_groups:add_to_instance": "{{wrapper}}",
+ "compute:security_groups:remove_from_instance": "{{wrapper}}",
+
+ "compute:delete": "{{wrapper}}",
+ "compute:soft_delete": "{{wrapper}}",
+ "compute:force_delete": "{{wrapper}}",
+ "compute:restore": "{{wrapper}}",
+
+ "compute:volume_snapshot_create": "{{wrapper}}",
+ "compute:volume_snapshot_delete": "{{wrapper}}",
+
+ "admin_api": "{{wrapper}}",
+ "compute_extension:accounts": "{{wrapper}}",
+ "compute_extension:admin_actions": "{{wrapper}}",
+ "compute_extension:admin_actions:pause": "{{wrapper}}",
+ "compute_extension:admin_actions:unpause": "{{wrapper}}",
+ "compute_extension:admin_actions:suspend": "{{wrapper}}",
+ "compute_extension:admin_actions:resume": "{{wrapper}}",
+ "compute_extension:admin_actions:lock": "{{wrapper}}",
+ "compute_extension:admin_actions:unlock": "{{wrapper}}",
+ "compute_extension:admin_actions:resetNetwork": "{{wrapper}}",
+ "compute_extension:admin_actions:injectNetworkInfo": "{{wrapper}}",
+ "compute_extension:admin_actions:createBackup": "{{wrapper}}",
+ "compute_extension:admin_actions:migrateLive": "{{wrapper}}",
+ "compute_extension:admin_actions:resetState": "{{wrapper}}",
+ "compute_extension:admin_actions:migrate": "{{wrapper}}",
+ "compute_extension:aggregates": "{{wrapper}}",
+ "compute_extension:agents": "{{wrapper}}",
+ "compute_extension:attach_interfaces": "{{wrapper}}",
+ "compute_extension:baremetal_nodes": "{{wrapper}}",
+ "compute_extension:cells": "{{wrapper}}",
+ "compute_extension:cells:create": "{{wrapper}}",
+ "compute_extension:cells:delete": "{{wrapper}}",
+ "compute_extension:cells:update": "{{wrapper}}",
+ "compute_extension:cells:sync_instances": "{{wrapper}}",
+ "compute_extension:certificates": "{{wrapper}}",
+ "compute_extension:cloudpipe": "{{wrapper}}",
+ "compute_extension:cloudpipe_update": "{{wrapper}}",
+ "compute_extension:config_drive": "{{wrapper}}",
+ "compute_extension:console_output": "{{wrapper}}",
+ "compute_extension:consoles": "{{wrapper}}",
+ "compute_extension:createserverext": "{{wrapper}}",
+ "compute_extension:deferred_delete": "{{wrapper}}",
+ "compute_extension:disk_config": "{{wrapper}}",
+ "compute_extension:evacuate": "{{wrapper}}",
+ "compute_extension:extended_server_attributes": "{{wrapper}}",
+ "compute_extension:extended_status": "{{wrapper}}",
+ "compute_extension:extended_availability_zone": "{{wrapper}}",
+ "compute_extension:extended_ips": "{{wrapper}}",
+ "compute_extension:extended_ips_mac": "{{wrapper}}",
+ "compute_extension:extended_vif_net": "{{wrapper}}",
+ "compute_extension:extended_volumes": "{{wrapper}}",
+ "compute_extension:fixed_ips": "{{wrapper}}",
+ "compute_extension:flavor_access": "{{wrapper}}",
+ "compute_extension:flavor_access:addTenantAccess": "{{wrapper}}",
+ "compute_extension:flavor_access:removeTenantAccess": "{{wrapper}}",
+ "compute_extension:flavor_disabled": "{{wrapper}}",
+ "compute_extension:flavor_rxtx": "{{wrapper}}",
+ "compute_extension:flavor_swap": "{{wrapper}}",
+ "compute_extension:flavorextradata": "{{wrapper}}",
+ "compute_extension:flavorextraspecs:index": "{{wrapper}}",
+ "compute_extension:flavorextraspecs:show": "{{wrapper}}",
+ "compute_extension:flavorextraspecs:create": "{{wrapper}}",
+ "compute_extension:flavorextraspecs:update": "{{wrapper}}",
+ "compute_extension:flavorextraspecs:delete": "{{wrapper}}",
+ "compute_extension:flavormanage": "{{wrapper}}",
+ "compute_extension:floating_ip_dns": "{{wrapper}}",
+ "compute_extension:floating_ip_pools": "{{wrapper}}",
+ "compute_extension:floating_ips": "{{wrapper}}",
+ "compute_extension:floating_ips_bulk": "{{wrapper}}",
+ "compute_extension:fping": "{{wrapper}}",
+ "compute_extension:fping:all_tenants": "{{wrapper}}",
+ "compute_extension:hide_server_addresses": "{{wrapper}}",
+ "compute_extension:hosts": "{{wrapper}}",
+ "compute_extension:hypervisors": "{{wrapper}}",
+ "compute_extension:image_size": "{{wrapper}}",
+ "compute_extension:instance_actions": "{{wrapper}}",
+ "compute_extension:instance_actions:events": "{{wrapper}}",
+ "compute_extension:instance_usage_audit_log": "{{wrapper}}",
+ "compute_extension:keypairs": "{{wrapper}}",
+ "compute_extension:keypairs:index": "{{wrapper}}",
+ "compute_extension:keypairs:show": "{{wrapper}}",
+ "compute_extension:keypairs:create": "{{wrapper}}",
+ "compute_extension:keypairs:delete": "{{wrapper}}",
+ "compute_extension:multinic": "{{wrapper}}",
+ "compute_extension:networks": "{{wrapper}}",
+ "compute_extension:networks:view": "{{wrapper}}",
+ "compute_extension:networks_associate": "{{wrapper}}",
+ "compute_extension:os-tenant-networks": "{{wrapper}}",
+ "compute_extension:quotas:show": "{{wrapper}}",
+ "compute_extension:quotas:update": "{{wrapper}}",
+ "compute_extension:quotas:delete": "{{wrapper}}",
+ "compute_extension:quota_classes": "{{wrapper}}",
+ "compute_extension:rescue": "{{wrapper}}",
+ "compute_extension:security_group_default_rules": "{{wrapper}}",
+ "compute_extension:security_groups": "{{wrapper}}",
+ "compute_extension:server_diagnostics": "{{wrapper}}",
+ "compute_extension:server_groups": "{{wrapper}}",
+ "compute_extension:server_password": "{{wrapper}}",
+ "compute_extension:server_usage": "{{wrapper}}",
+ "compute_extension:services": "{{wrapper}}",
+ "compute_extension:shelve": "{{wrapper}}",
+ "compute_extension:shelveOffload": "{{wrapper}}",
+ "compute_extension:simple_tenant_usage:show": "{{wrapper}}",
+ "compute_extension:simple_tenant_usage:list": "{{wrapper}}",
+ "compute_extension:unshelve": "{{wrapper}}",
+ "compute_extension:users": "{{wrapper}}",
+ "compute_extension:virtual_interfaces": "{{wrapper}}",
+ "compute_extension:virtual_storage_arrays": "{{wrapper}}",
+ "compute_extension:volumes": "{{wrapper}}",
+ "compute_extension:volume_attachments:index": "{{wrapper}}",
+ "compute_extension:volume_attachments:show": "{{wrapper}}",
+ "compute_extension:volume_attachments:create": "{{wrapper}}",
+ "compute_extension:volume_attachments:update": "{{wrapper}}",
+ "compute_extension:volume_attachments:delete": "{{wrapper}}",
+ "compute_extension:volumetypes": "{{wrapper}}",
+ "compute_extension:availability_zone:list": "{{wrapper}}",
+ "compute_extension:availability_zone:detail": "{{wrapper}}",
+ "compute_extension:used_limits_for_admin": "{{wrapper}}",
+ "compute_extension:migrations:index": "{{wrapper}}",
+ "compute_extension:os-assisted-volume-snapshots:create": "{{wrapper}}",
+ "compute_extension:os-assisted-volume-snapshots:delete": "{{wrapper}}",
+ "compute_extension:console_auth_tokens": "{{wrapper}}",
+ "compute_extension:os-server-external-events:create": "{{wrapper}}",
+
+ "network:get_all": "{{wrapper}}",
+ "network:get": "{{wrapper}}",
+ "network:create": "{{wrapper}}",
+ "network:delete": "{{wrapper}}",
+ "network:associate": "{{wrapper}}",
+ "network:disassociate": "{{wrapper}}",
+ "network:get_vifs_by_instance": "{{wrapper}}",
+ "network:allocate_for_instance": "{{wrapper}}",
+ "network:deallocate_for_instance": "{{wrapper}}",
+ "network:validate_networks": "{{wrapper}}",
+ "network:get_instance_uuids_by_ip_filter": "{{wrapper}}",
+ "network:get_instance_id_by_floating_address": "{{wrapper}}",
+ "network:setup_networks_on_host": "{{wrapper}}",
+ "network:get_backdoor_port": "{{wrapper}}",
+
+ "network:get_floating_ip": "{{wrapper}}",
+ "network:get_floating_ip_pools": "{{wrapper}}",
+ "network:get_floating_ip_by_address": "{{wrapper}}",
+ "network:get_floating_ips_by_project": "{{wrapper}}",
+ "network:get_floating_ips_by_fixed_address": "{{wrapper}}",
+ "network:allocate_floating_ip": "{{wrapper}}",
+ "network:associate_floating_ip": "{{wrapper}}",
+ "network:disassociate_floating_ip": "{{wrapper}}",
+ "network:release_floating_ip": "{{wrapper}}",
+ "network:migrate_instance_start": "{{wrapper}}",
+ "network:migrate_instance_finish": "{{wrapper}}",
+
+ "network:get_fixed_ip": "{{wrapper}}",
+ "network:get_fixed_ip_by_address": "{{wrapper}}",
+ "network:add_fixed_ip_to_instance": "{{wrapper}}",
+ "network:remove_fixed_ip_from_instance": "{{wrapper}}",
+ "network:add_network_to_project": "{{wrapper}}",
+ "network:get_instance_nw_info": "{{wrapper}}",
+
+ "network:get_dns_domains": "{{wrapper}}",
+ "network:add_dns_entry": "{{wrapper}}",
+ "network:modify_dns_entry": "{{wrapper}}",
+ "network:delete_dns_entry": "{{wrapper}}",
+ "network:get_dns_entries_by_address": "{{wrapper}}",
+ "network:get_dns_entries_by_name": "{{wrapper}}",
+ "network:create_private_dns_domain": "{{wrapper}}",
+ "network:create_public_dns_domain": "{{wrapper}}",
+ "network:delete_dns_domain": "{{wrapper}}",
+ "network:attach_external_network": "{{wrapper}}",
+ "network:get_vif_by_mac_address": "{{wrapper}}",
+
+ "os_compute_api:servers:detail:get_all_tenants": "{{wrapper}}",
+ "os_compute_api:servers:index:get_all_tenants": "{{wrapper}}",
+ "os_compute_api:servers:confirm_resize": "{{wrapper}}",
+ "os_compute_api:servers:create": "{{wrapper}}",
+ "os_compute_api:servers:create:attach_network": "{{wrapper}}",
+ "os_compute_api:servers:create:attach_volume": "{{wrapper}}",
+ "os_compute_api:servers:create:forced_host": "{{wrapper}}",
+ "os_compute_api:servers:delete": "{{wrapper}}",
+ "os_compute_api:servers:update": "{{wrapper}}",
+ "os_compute_api:servers:detail": "{{wrapper}}",
+ "os_compute_api:servers:index": "{{wrapper}}",
+ "os_compute_api:servers:reboot": "{{wrapper}}",
+ "os_compute_api:servers:rebuild": "{{wrapper}}",
+ "os_compute_api:servers:resize": "{{wrapper}}",
+ "os_compute_api:servers:revert_resize": "{{wrapper}}",
+ "os_compute_api:servers:show": "{{wrapper}}",
+ "os_compute_api:servers:create_image": "{{wrapper}}",
+ "os_compute_api:servers:create_image:allow_volume_backed": "{{wrapper}}",
+ "os_compute_api:servers:start": "{{wrapper}}",
+ "os_compute_api:servers:stop": "{{wrapper}}",
+ "os_compute_api:os-access-ips:discoverable": "{{wrapper}}",
+ "os_compute_api:os-access-ips": "{{wrapper}}",
+ "os_compute_api:os-admin-actions": "{{wrapper}}",
+ "os_compute_api:os-admin-actions:discoverable": "{{wrapper}}",
+ "os_compute_api:os-admin-actions:reset_network": "{{wrapper}}",
+ "os_compute_api:os-admin-actions:inject_network_info": "{{wrapper}}",
+ "os_compute_api:os-admin-actions:reset_state": "{{wrapper}}",
+ "os_compute_api:os-admin-password": "{{wrapper}}",
+ "os_compute_api:os-admin-password:discoverable": "{{wrapper}}",
+ "os_compute_api:os-aggregates:discoverable": "{{wrapper}}",
+ "os_compute_api:os-aggregates:index": "{{wrapper}}",
+ "os_compute_api:os-aggregates:create": "{{wrapper}}",
+ "os_compute_api:os-aggregates:show": "{{wrapper}}",
+ "os_compute_api:os-aggregates:update": "{{wrapper}}",
+ "os_compute_api:os-aggregates:delete": "{{wrapper}}",
+ "os_compute_api:os-aggregates:add_host": "{{wrapper}}",
+ "os_compute_api:os-aggregates:remove_host": "{{wrapper}}",
+ "os_compute_api:os-aggregates:set_metadata": "{{wrapper}}",
+ "os_compute_api:os-agents": "{{wrapper}}",
+ "os_compute_api:os-agents:discoverable": "{{wrapper}}",
+ "os_compute_api:os-attach-interfaces": "{{wrapper}}",
+ "os_compute_api:os-attach-interfaces:discoverable": "{{wrapper}}",
+ "os_compute_api:os-baremetal-nodes": "{{wrapper}}",
+ "os_compute_api:os-baremetal-nodes:discoverable": "{{wrapper}}",
+ "os_compute_api:os-block-device-mapping-v1:discoverable": "{{wrapper}}",
+ "os_compute_api:os-cells": "{{wrapper}}",
+ "os_compute_api:os-cells:create": "{{wrapper}}",
+ "os_compute_api:os-cells:delete": "{{wrapper}}",
+ "os_compute_api:os-cells:update": "{{wrapper}}",
+ "os_compute_api:os-cells:sync_instances": "{{wrapper}}",
+ "os_compute_api:os-cells:discoverable": "{{wrapper}}",
+ "os_compute_api:os-certificates:create": "{{wrapper}}",
+ "os_compute_api:os-certificates:show": "{{wrapper}}",
+ "os_compute_api:os-certificates:discoverable": "{{wrapper}}",
+ "os_compute_api:os-cloudpipe": "{{wrapper}}",
+ "os_compute_api:os-cloudpipe:discoverable": "{{wrapper}}",
+ "os_compute_api:os-config-drive": "{{wrapper}}",
+ "os_compute_api:os-consoles:discoverable": "{{wrapper}}",
+ "os_compute_api:os-consoles:create": "{{wrapper}}",
+ "os_compute_api:os-consoles:delete": "{{wrapper}}",
+ "os_compute_api:os-consoles:index": "{{wrapper}}",
+ "os_compute_api:os-consoles:show": "{{wrapper}}",
+ "os_compute_api:os-console-output:discoverable": "{{wrapper}}",
+ "os_compute_api:os-console-output": "{{wrapper}}",
+ "os_compute_api:os-remote-consoles": "{{wrapper}}",
+ "os_compute_api:os-remote-consoles:discoverable": "{{wrapper}}",
+ "os_compute_api:os-create-backup:discoverable": "{{wrapper}}",
+ "os_compute_api:os-create-backup": "{{wrapper}}",
+ "os_compute_api:os-deferred-delete": "{{wrapper}}",
+ "os_compute_api:os-deferred-delete:discoverable": "{{wrapper}}",
+ "os_compute_api:os-disk-config": "{{wrapper}}",
+ "os_compute_api:os-disk-config:discoverable": "{{wrapper}}",
+ "os_compute_api:os-evacuate": "{{wrapper}}",
+ "os_compute_api:os-evacuate:discoverable": "{{wrapper}}",
+ "os_compute_api:os-extended-server-attributes": "{{wrapper}}",
+ "os_compute_api:os-extended-server-attributes:discoverable": "{{wrapper}}",
+ "os_compute_api:os-extended-status": "{{wrapper}}",
+ "os_compute_api:os-extended-status:discoverable": "{{wrapper}}",
+ "os_compute_api:os-extended-availability-zone": "{{wrapper}}",
+ "os_compute_api:os-extended-availability-zone:discoverable": "{{wrapper}}",
+ "os_compute_api:extensions": "{{wrapper}}",
+ "os_compute_api:extension_info:discoverable": "{{wrapper}}",
+ "os_compute_api:os-extended-volumes": "{{wrapper}}",
+ "os_compute_api:os-extended-volumes:discoverable": "{{wrapper}}",
+ "os_compute_api:os-fixed-ips": "{{wrapper}}",
+ "os_compute_api:os-fixed-ips:discoverable": "{{wrapper}}",
+ "os_compute_api:os-flavor-access": "{{wrapper}}",
+ "os_compute_api:os-flavor-access:discoverable": "{{wrapper}}",
+ "os_compute_api:os-flavor-access:remove_tenant_access": "{{wrapper}}",
+ "os_compute_api:os-flavor-access:add_tenant_access": "{{wrapper}}",
+ "os_compute_api:os-flavor-rxtx": "{{wrapper}}",
+ "os_compute_api:os-flavor-rxtx:discoverable": "{{wrapper}}",
+ "os_compute_api:flavors:discoverable": "{{wrapper}}",
+ "os_compute_api:os-flavor-extra-specs:discoverable": "{{wrapper}}",
+ "os_compute_api:os-flavor-extra-specs:index": "{{wrapper}}",
+ "os_compute_api:os-flavor-extra-specs:show": "{{wrapper}}",
+ "os_compute_api:os-flavor-extra-specs:create": "{{wrapper}}",
+ "os_compute_api:os-flavor-extra-specs:update": "{{wrapper}}",
+ "os_compute_api:os-flavor-extra-specs:delete": "{{wrapper}}",
+ "os_compute_api:os-flavor-manage:discoverable": "{{wrapper}}",
+ "os_compute_api:os-flavor-manage": "{{wrapper}}",
+ "os_compute_api:os-floating-ip-dns": "{{wrapper}}",
+ "os_compute_api:os-floating-ip-dns:discoverable": "{{wrapper}}",
+ "os_compute_api:os-floating-ip-dns:domain:update": "{{wrapper}}",
+ "os_compute_api:os-floating-ip-dns:domain:delete": "{{wrapper}}",
+ "os_compute_api:os-floating-ip-pools": "{{wrapper}}",
+ "os_compute_api:os-floating-ip-pools:discoverable": "{{wrapper}}",
+ "os_compute_api:os-floating-ips": "{{wrapper}}",
+ "os_compute_api:os-floating-ips:discoverable": "{{wrapper}}",
+ "os_compute_api:os-floating-ips-bulk": "{{wrapper}}",
+ "os_compute_api:os-floating-ips-bulk:discoverable": "{{wrapper}}",
+ "os_compute_api:os-fping": "{{wrapper}}",
+ "os_compute_api:os-fping:discoverable": "{{wrapper}}",
+ "os_compute_api:os-fping:all_tenants": "{{wrapper}}",
+ "os_compute_api:os-hide-server-addresses": "{{wrapper}}",
+ "os_compute_api:os-hide-server-addresses:discoverable": "{{wrapper}}",
+ "os_compute_api:os-hosts": "{{wrapper}}",
+ "os_compute_api:os-hosts:discoverable": "{{wrapper}}",
+ "os_compute_api:os-hypervisors": "{{wrapper}}",
+ "os_compute_api:os-hypervisors:discoverable": "{{wrapper}}",
+ "os_compute_api:images:discoverable": "{{wrapper}}",
+ "os_compute_api:image-size": "{{wrapper}}",
+ "os_compute_api:image-size:discoverable": "{{wrapper}}",
+ "os_compute_api:os-instance-actions": "{{wrapper}}",
+ "os_compute_api:os-instance-actions:discoverable": "{{wrapper}}",
+ "os_compute_api:os-instance-actions:events": "{{wrapper}}",
+ "os_compute_api:os-instance-usage-audit-log": "{{wrapper}}",
+ "os_compute_api:os-instance-usage-audit-log:discoverable": "{{wrapper}}",
+ "os_compute_api:ips:discoverable": "{{wrapper}}",
+ "os_compute_api:ips:index": "{{wrapper}}",
+ "os_compute_api:ips:show": "{{wrapper}}",
+ "os_compute_api:os-keypairs:discoverable": "{{wrapper}}",
+ "os_compute_api:os-keypairs": "{{wrapper}}",
+ "os_compute_api:os-keypairs:index": "{{wrapper}}",
+ "os_compute_api:os-keypairs:show": "{{wrapper}}",
+ "os_compute_api:os-keypairs:create": "{{wrapper}}",
+ "os_compute_api:os-keypairs:delete": "{{wrapper}}",
+ "os_compute_api:limits:discoverable": "{{wrapper}}",
+ "os_compute_api:limits": "{{wrapper}}",
+ "os_compute_api:os-lock-server:discoverable": "{{wrapper}}",
+ "os_compute_api:os-lock-server:lock": "{{wrapper}}",
+ "os_compute_api:os-lock-server:unlock": "{{wrapper}}",
+ "os_compute_api:os-lock-server:unlock:unlock_override": "{{wrapper}}",
+ "os_compute_api:os-migrate-server:discoverable": "{{wrapper}}",
+ "os_compute_api:os-migrate-server:migrate": "{{wrapper}}",
+ "os_compute_api:os-migrate-server:migrate_live": "{{wrapper}}",
+ "os_compute_api:os-multinic": "{{wrapper}}",
+ "os_compute_api:os-multinic:discoverable": "{{wrapper}}",
+ "os_compute_api:os-networks": "{{wrapper}}",
+ "os_compute_api:os-networks:view": "{{wrapper}}",
+ "os_compute_api:os-networks:discoverable": "{{wrapper}}",
+ "os_compute_api:os-networks-associate": "{{wrapper}}",
+ "os_compute_api:os-networks-associate:discoverable": "{{wrapper}}",
+ "os_compute_api:os-pause-server:discoverable": "{{wrapper}}",
+ "os_compute_api:os-pause-server:pause": "{{wrapper}}",
+ "os_compute_api:os-pause-server:unpause": "{{wrapper}}",
+ "os_compute_api:os-pci:pci_servers": "{{wrapper}}",
+ "os_compute_api:os-pci:discoverable": "{{wrapper}}",
+ "os_compute_api:os-pci:index": "{{wrapper}}",
+ "os_compute_api:os-pci:detail": "{{wrapper}}",
+ "os_compute_api:os-pci:show": "{{wrapper}}",
+ "os_compute_api:os-personality:discoverable": "{{wrapper}}",
+ "os_compute_api:os-preserve-ephemeral-rebuild:discoverable": "{{wrapper}}",
+ "os_compute_api:os-quota-sets:discoverable": "{{wrapper}}",
+ "os_compute_api:os-quota-sets:show": "{{wrapper}}",
+ "os_compute_api:os-quota-sets:defaults": "{{wrapper}}",
+ "os_compute_api:os-quota-sets:update": "{{wrapper}}",
+ "os_compute_api:os-quota-sets:delete": "{{wrapper}}",
+ "os_compute_api:os-quota-sets:detail": "{{wrapper}}",
+ "os_compute_api:os-quota-class-sets:update": "{{wrapper}}",
+ "os_compute_api:os-quota-class-sets:show": "{{wrapper}}",
+ "os_compute_api:os-quota-class-sets:discoverable": "{{wrapper}}",
+ "os_compute_api:os-rescue": "{{wrapper}}",
+ "os_compute_api:os-rescue:discoverable": "{{wrapper}}",
+ "os_compute_api:os-scheduler-hints:discoverable": "{{wrapper}}",
+ "os_compute_api:os-security-group-default-rules:discoverable": "{{wrapper}}",
+ "os_compute_api:os-security-group-default-rules": "{{wrapper}}",
+ "os_compute_api:os-security-groups": "{{wrapper}}",
+ "os_compute_api:os-security-groups:discoverable": "{{wrapper}}",
+ "os_compute_api:os-server-diagnostics": "{{wrapper}}",
+ "os_compute_api:os-server-diagnostics:discoverable": "{{wrapper}}",
+ "os_compute_api:os-server-password": "{{wrapper}}",
+ "os_compute_api:os-server-password:discoverable": "{{wrapper}}",
+ "os_compute_api:os-server-usage": "{{wrapper}}",
+ "os_compute_api:os-server-usage:discoverable": "{{wrapper}}",
+ "os_compute_api:os-server-groups": "{{wrapper}}",
+ "os_compute_api:os-server-groups:discoverable": "{{wrapper}}",
+ "os_compute_api:os-services": "{{wrapper}}",
+ "os_compute_api:os-services:discoverable": "{{wrapper}}",
+ "os_compute_api:server-metadata:discoverable": "{{wrapper}}",
+ "os_compute_api:server-metadata:index": "{{wrapper}}",
+ "os_compute_api:server-metadata:show": "{{wrapper}}",
+ "os_compute_api:server-metadata:delete": "{{wrapper}}",
+ "os_compute_api:server-metadata:create": "{{wrapper}}",
+ "os_compute_api:server-metadata:update": "{{wrapper}}",
+ "os_compute_api:server-metadata:update_all": "{{wrapper}}",
+ "os_compute_api:servers:discoverable": "{{wrapper}}",
+ "os_compute_api:os-shelve:shelve": "{{wrapper}}",
+ "os_compute_api:os-shelve:shelve:discoverable": "{{wrapper}}",
+ "os_compute_api:os-shelve:shelve_offload": "{{wrapper}}",
+ "os_compute_api:os-simple-tenant-usage:discoverable": "{{wrapper}}",
+ "os_compute_api:os-simple-tenant-usage:show": "{{wrapper}}",
+ "os_compute_api:os-simple-tenant-usage:list": "{{wrapper}}",
+ "os_compute_api:os-suspend-server:discoverable": "{{wrapper}}",
+ "os_compute_api:os-suspend-server:suspend": "{{wrapper}}",
+ "os_compute_api:os-suspend-server:resume": "{{wrapper}}",
+ "os_compute_api:os-tenant-networks": "{{wrapper}}",
+ "os_compute_api:os-tenant-networks:discoverable": "{{wrapper}}",
+ "os_compute_api:os-shelve:unshelve": "{{wrapper}}",
+ "os_compute_api:os-user-data:discoverable": "{{wrapper}}",
+ "os_compute_api:os-virtual-interfaces": "{{wrapper}}",
+ "os_compute_api:os-virtual-interfaces:discoverable": "{{wrapper}}",
+ "os_compute_api:os-volumes": "{{wrapper}}",
+ "os_compute_api:os-volumes:discoverable": "{{wrapper}}",
+ "os_compute_api:os-volumes-attachments:index": "{{wrapper}}",
+ "os_compute_api:os-volumes-attachments:show": "{{wrapper}}",
+ "os_compute_api:os-volumes-attachments:create": "{{wrapper}}",
+ "os_compute_api:os-volumes-attachments:update": "{{wrapper}}",
+ "os_compute_api:os-volumes-attachments:delete": "{{wrapper}}",
+ "os_compute_api:os-volumes-attachments:discoverable": "{{wrapper}}",
+ "os_compute_api:os-availability-zone:list": "{{wrapper}}",
+ "os_compute_api:os-availability-zone:discoverable": "{{wrapper}}",
+ "os_compute_api:os-availability-zone:detail": "{{wrapper}}",
+ "os_compute_api:os-used-limits": "{{wrapper}}",
+ "os_compute_api:os-used-limits:discoverable": "{{wrapper}}",
+ "os_compute_api:os-migrations:index": "{{wrapper}}",
+ "os_compute_api:os-migrations:discoverable": "{{wrapper}}",
+ "os_compute_api:os-assisted-volume-snapshots:create": "{{wrapper}}",
+ "os_compute_api:os-assisted-volume-snapshots:delete": "{{wrapper}}",
+ "os_compute_api:os-assisted-volume-snapshots:discoverable": "{{wrapper}}",
+ "os_compute_api:os-console-auth-tokens": "{{wrapper}}",
+ "os_compute_api:os-server-external-events:create": "{{wrapper}}",
+}
diff --git a/external_policy_checker/external_policy_checker/__init__.py b/external_policy_checker/external_policy_checker/__init__.py
new file mode 100644
index 00000000..a4e2017f
--- /dev/null
+++ b/external_policy_checker/external_policy_checker/__init__.py
@@ -0,0 +1 @@
+__version__ = "0.1"
diff --git a/external_policy_checker/external_policy_checker/__main__.py b/external_policy_checker/external_policy_checker/__main__.py
new file mode 100644
index 00000000..4499a96b
--- /dev/null
+++ b/external_policy_checker/external_policy_checker/__main__.py
@@ -0,0 +1,9 @@
+# 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 moon_bouchon.server
+
+moon_bouchon.server.main()
diff --git a/external_policy_checker/external_policy_checker/conf_installer.py b/external_policy_checker/external_policy_checker/conf_installer.py
new file mode 100644
index 00000000..ec45003b
--- /dev/null
+++ b/external_policy_checker/external_policy_checker/conf_installer.py
@@ -0,0 +1,83 @@
+import shutil
+import logging
+import argparse
+import os
+from uuid import uuid4
+import glob
+
+logger = logging.getLogger(__name__)
+
+COMPONENTS = (
+ "cinder",
+ "nova",
+ "neutron",
+ "glance",
+ "keystone"
+)
+
+
+def init():
+ parser = argparse.ArgumentParser()
+ parser.add_argument("--verbose", '-v', action='store_true', help='verbose mode')
+ parser.add_argument("--debug", '-d', action='store_true', help='debug mode')
+ parser.add_argument("--templates", '-t', help='set template directory', default="templates/")
+ parser.add_argument("--out-dir", '-o', help='if set, copy the files in this directory', default=None)
+ parser.add_argument("wrapper_url", help='Wrapper URL to use', nargs="*",
+ default=["http://127.0.0.1:8080/policy_checker"])
+ args = parser.parse_args()
+ logging_format = "%(levelname)s: %(message)s"
+ if args.verbose:
+ logging.basicConfig(level=logging.INFO, format=logging_format)
+ if args.debug:
+ logging.basicConfig(level=logging.DEBUG, format=logging_format)
+ return args
+
+
+def update_templates(templates_dir, wrapper_url):
+ tmp_dir = os.path.join("/tmp", str(uuid4()))
+ wrapper_url = wrapper_url[0].strip('"').strip("'")
+ os.mkdir(tmp_dir)
+ for comp in COMPONENTS:
+ input_file = os.path.join(templates_dir, comp + ".policy.json")
+ output_file = os.path.join(tmp_dir, comp + ".policy.json")
+ output_fd = open(output_file, "w")
+ for line in open(input_file):
+ output_fd.write(line.replace("{{wrapper}}", wrapper_url))
+ return tmp_dir
+
+
+def remove_tmp_files(tmp_dir):
+ for _filename in glob.glob(os.path.join(tmp_dir, "*")):
+ logger.debug("{} {}".format(_filename, os.path.isfile(_filename)))
+ if os.path.isfile(_filename):
+ logger.debug("Trying to delete {}".format(_filename))
+ os.remove(_filename)
+ logger.debug("Delete done")
+ os.removedirs(tmp_dir)
+
+
+def main(templates_dir, wrapper_url, out_dir=None):
+ logger.info("Moving configuration files")
+ tmp_dir = update_templates(templates_dir, wrapper_url)
+ if out_dir:
+ logger.info("Moving to {}".format(out_dir))
+ try:
+ os.mkdir(out_dir)
+ except FileExistsError:
+ logger.warning("Output directory exists, writing on it!")
+ for comp in COMPONENTS:
+ logger.info("Moving {}".format(comp))
+ shutil.copy(os.path.join(tmp_dir, comp + ".policy.json"),
+ os.path.join(out_dir, comp + ".policy.json"))
+ else:
+ logger.info("Moving to /etc")
+ for comp in COMPONENTS:
+ logger.info("Moving {}".format(comp))
+ shutil.copy(os.path.join(tmp_dir, comp + ".policy.json"),
+ os.path.join("etc", comp, "policy.json"))
+ remove_tmp_files(tmp_dir)
+
+
+if __name__ == "__main__":
+ args = init()
+ main(args.templates, args.wrapper_url, args.out_dir)
diff --git a/external_policy_checker/external_policy_checker/server.py b/external_policy_checker/external_policy_checker/server.py
new file mode 100644
index 00000000..cbb4a933
--- /dev/null
+++ b/external_policy_checker/external_policy_checker/server.py
@@ -0,0 +1,135 @@
+# Copyright 2018 Orange
+# 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 sys
+import flask
+from flask import Flask
+from flask import request
+import json
+import logging
+import random
+
+logger = logging.getLogger(__name__)
+logging.basicConfig(level=logging.INFO)
+app = Flask(__name__)
+
+
+def test_target(data, result):
+ if "resource_id" in data:
+ result["resource_id"] = data['object_id']
+ if "object_id" in data:
+ result["resource_id"] = data['object_id']
+ if 'project_id' in data:
+ result["project_id"] = data['project_id']
+ if 'user_id' in data:
+ result["user_id"] = data['user_id']
+
+
+def test_credentials(data, result):
+ if 'project_id' in data:
+ result["project_id"] = data['project_id']
+ if 'user_id' in data:
+ result["user_id"] = data['user_id']
+ if 'project_domain_id' in data:
+ result["domain_id"] = data['project_domain_id']
+
+
+def test_rule(data, result):
+ result['action_name'] = data
+
+
+def test_data():
+ data = request.form
+ result = {
+ "user_id": "",
+ "project_id": "",
+ "action_name": "",
+ "resource_id": "",
+ "domain_id": "",
+ }
+ if not dict(request.form):
+ data = json.loads(request.data.decode("utf-8"))
+ try:
+ target = json.loads(data.get('target', {}))
+ except Exception:
+ raise Exception("Error reading target")
+ try:
+ credentials = json.loads(data.get('credentials', {}))
+ except Exception:
+ raise Exception("Error reading credentials")
+ try:
+ rule = data.get('rule', "")
+ except Exception:
+ raise Exception("Error reading rule")
+ test_target(target, result)
+ test_credentials(credentials, result)
+ test_rule(rule, result)
+ return_value = True
+ logger.info("Analysing request with {}".format(rule))
+ for key in result:
+ if not result[key] and key != "domain_id":
+ return_value = False
+ logger.error("Attribute {} is absent".format(key))
+ if not result[key] and key == "domain_id":
+ logger.warning("Attribute {} is missing.".format(key))
+ return return_value
+
+
+@app.route("/policy_checker", methods=["POST"])
+def checker():
+ information_is_complete = False
+ try:
+ information_is_complete = test_data()
+ except Exception as e:
+ logger.exception(e)
+ if information_is_complete:
+ response = flask.make_response("True")
+ response.headers['content-type'] = 'application/octet-stream'
+ return response
+ else:
+ response = flask.make_response("False")
+ response.headers['content-type'] = 'application/octet-stream'
+ return response, 403
+
+
+def get_target():
+ data = request.form
+ if not dict(request.form):
+ data = json.loads(request.data.decode("utf-8"))
+ try:
+ return json.loads(data.get('target', {}))
+ except Exception:
+ raise Exception("Error reading target")
+
+
+@app.route("/authz/grant", methods=["POST"])
+def wrapper_grant():
+ logger.info("Requesting wrapper authz with {}".format(get_target()))
+ response = flask.make_response("True")
+ response.headers['content-type'] = 'application/octet-stream'
+ return response
+
+
+@app.route("/authz/deny", methods=["POST"])
+def wrapper_deny():
+ logger.info("Requesting wrapper authz with {}".format(get_target()))
+ response = flask.make_response("False")
+ response.headers['content-type'] = 'application/octet-stream'
+ return response, 403
+
+
+def main():
+ port = 8080
+ if len(sys.argv) > 1:
+ try:
+ port = int(sys.argv[1])
+ except ValueError:
+ logger.error("Argument for Port in command line is not an integer")
+ sys.exit(1)
+ app.run(host="0.0.0.0", port=port)
+
+
+if __name__ == "__main__":
+ main()
diff --git a/external_policy_checker/requirements.txt b/external_policy_checker/requirements.txt
new file mode 100644
index 00000000..8ab6294c
--- /dev/null
+++ b/external_policy_checker/requirements.txt
@@ -0,0 +1 @@
+flask \ No newline at end of file
diff --git a/external_policy_checker/setup.cfg b/external_policy_checker/setup.cfg
new file mode 100644
index 00000000..7c2b2874
--- /dev/null
+++ b/external_policy_checker/setup.cfg
@@ -0,0 +1,2 @@
+[bdist_wheel]
+universal = 1 \ No newline at end of file
diff --git a/external_policy_checker/setup.py b/external_policy_checker/setup.py
new file mode 100644
index 00000000..acd994a6
--- /dev/null
+++ b/external_policy_checker/setup.py
@@ -0,0 +1,47 @@
+# 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'.
+
+from setuptools import setup, find_packages
+import external_policy_checker
+
+
+setup(
+
+ name='external_policy_checker',
+
+ version=external_policy_checker.__version__,
+
+ packages=find_packages(),
+
+ author="Thomas Duval",
+
+ author_email="thomas.duval@orange.com",
+
+ description="",
+
+ long_description=open('README.md').read(),
+
+ install_requires=["flask"],
+
+ include_package_data=True,
+
+ url='https://git.opnfv.org/cgit/moon',
+
+ classifiers=[
+ "Programming Language :: Python",
+ "Development Status :: 1 - Planning",
+ "License :: OSI Approved",
+ "Natural Language :: French",
+ "Operating System :: OS Independent",
+ "Programming Language :: Python :: 3",
+ ],
+
+ entry_points={
+ 'console_scripts': [
+ 'external_policy_checker = external_policy_checker.server:main',
+ ],
+ }
+
+)
diff --git a/moon_authz/Changelog b/moon_authz/Changelog
new file mode 100644
index 00000000..59d7f8e4
--- /dev/null
+++ b/moon_authz/Changelog
@@ -0,0 +1,30 @@
+# Copyright 2018 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
+=======
+
+1.0.0
+-----
+- First version of the manager
+
+2.0.0
+-----
+- Version built inside the Keystone component
+
+3.0.0
+-----
+- Version built outside the Keystone component
+
+4.0.0
+-----
+- First micro-architecture version
+
+4.3.3
+-----
+- use the threading capability of Flask app
+- set the number of manager to 1
+- update to the latest version of the python-moondb library
diff --git a/moon_authz/Dockerfile b/moon_authz/Dockerfile
index fea9555d..7081e31c 100644
--- a/moon_authz/Dockerfile
+++ b/moon_authz/Dockerfile
@@ -1,8 +1,15 @@
FROM python:3
+LABEL Name=Authz_plugin
+LABEL Description="Authz plugin for the Moon platform"
+LABEL Maintainer="Thomas Duval"
+LABEL Url="https://wiki.opnfv.org/display/moon/Moon+Project+Proposal"
+
+USER root
+
ADD . /root
WORKDIR /root/
-RUN pip3 install -r requirements.txt
-RUN pip3 install .
+RUN pip3 install --no-cache-dir -r requirements.txt
+RUN pip3 install --no-cache-dir .
CMD ["python3", "-m", "moon_authz"] \ No newline at end of file
diff --git a/moon_authz/moon_authz/__init__.py b/moon_authz/moon_authz/__init__.py
index 6f964a63..0fb32055 100644
--- a/moon_authz/moon_authz/__init__.py
+++ b/moon_authz/moon_authz/__init__.py
@@ -3,4 +3,4 @@
# license which can be found in the file 'LICENSE' in this package distribution
# or at 'http://www.apache.org/licenses/LICENSE-2.0'.
-__version__ = "4.3.2"
+__version__ = "4.3.3"
diff --git a/moon_authz/moon_authz/http_server.py b/moon_authz/moon_authz/http_server.py
index 836efbc8..7d3b1ec3 100644
--- a/moon_authz/moon_authz/http_server.py
+++ b/moon_authz/moon_authz/http_server.py
@@ -94,8 +94,7 @@ class Root(Resource):
class HTTPServer(Server):
-
- def __init__(self, host="0.0.0.0", port=38001, **kwargs):
+ def __init__(self, host="localhost", port=38001, **kwargs):
super(HTTPServer, self).__init__(host=host, port=port, **kwargs)
self.component_data = kwargs.get("component_data", {})
logger.info("HTTPServer port={} {}".format(port, kwargs))
@@ -136,4 +135,4 @@ class HTTPServer(Server):
)
def run(self):
- self.app.run(host=self._host, port=self._port) # nosec
+ self.app.run(host=self._host, port=self._port, threaded=True) # nosec
diff --git a/moon_authz/tests/unit_python/mock_pods.py b/moon_authz/tests/unit_python/mock_pods.py
index 74801cd1..9e05e335 100644
--- a/moon_authz/tests/unit_python/mock_pods.py
+++ b/moon_authz/tests/unit_python/mock_pods.py
@@ -87,7 +87,7 @@ subject_mock = {
"name": "testuser",
"email": "mail",
"id": "89ba91c18dd54abfbfde7a66936c51a6",
- "partner_id": ""
+ "extra": {}
}
},
"policy_id_1": {
@@ -141,7 +141,7 @@ object_mock = {
"name": "vm1",
"description": "test",
"id": "9089b3d2ce5b4e929ffc7e35b55eba1a",
- "partner_id": "",
+ "extra": {},
"policy_list": [
"f8f49a779ceb47b3ac810f01ef71b4e0",
"636cd473324f4c0bbd9102cb5b62a16d"
@@ -195,7 +195,7 @@ action_mock = {
"name": "boot",
"description": "test",
"id": "cdb3df220dc04a6ea3334b994827b068",
- "partner_id": "",
+ "extra": {},
"policy_list": [
"f8f49a779ceb47b3ac810f01ef71b4e0",
"636cd473324f4c0bbd9102cb5b62a16d"
@@ -205,7 +205,7 @@ action_mock = {
"name": "stop",
"description": "test",
"id": "cdb3df220dc04a6ea3334b994827b068",
- "partner_id": "",
+ "extra": {},
"policy_list": [
"f8f49a779ceb47b3ac810f01ef71b4e0",
"636cd473324f4c0bbd9102cb5b62a16d"
@@ -215,7 +215,7 @@ action_mock = {
"name": "start",
"description": "test",
"id": "9f5112afe9b34a6c894eb87246ccb7aa",
- "partner_id": "",
+ "extra": {},
"policy_list": [
"f8f49a779ceb47b3ac810f01ef71b4e0",
"636cd473324f4c0bbd9102cb5b62a16d"
diff --git a/moon_dashboard/.gitignore b/moon_dashboard/.gitignore
new file mode 100644
index 00000000..61f2dc9f
--- /dev/null
+++ b/moon_dashboard/.gitignore
@@ -0,0 +1 @@
+**/__pycache__/
diff --git a/moon_dashboard/.gitlab-ci.yml b/moon_dashboard/.gitlab-ci.yml
new file mode 100644
index 00000000..50fd8a4e
--- /dev/null
+++ b/moon_dashboard/.gitlab-ci.yml
@@ -0,0 +1,64 @@
+stages:
+ - lint
+ - build
+ - test
+ - publish
+
+variables:
+ http_proxy: "http://devwatt-proxy.si.fr.intraorange:8080"
+ https_proxy: "http://devwatt-proxy.si.fr.intraorange:8080"
+ no_proxy: dind, gitlab.forge.orange-labs.fr
+ DOCKER_DRIVER: overlay
+ DOCKER_HOST: tcp://dind:2375
+ CONTAINER_RELEASE_IMAGE: moonplatform/$CI_PROJECT_NAME
+ CONTAINER_TAG: dev
+ DOCKER_VERSION: "17.12"
+
+services:
+ - name: dockerproxy-iva.si.francetelecom.fr/docker:$DOCKER_VERSION-dind
+ alias: dind
+image: dockerproxy-iva.si.francetelecom.fr/docker:$DOCKER_VERSION
+
+lint-job:
+ image: dockerfactory-iva.si.francetelecom.fr/docker/orange-dockerfile-lint:0.2.7-alpine3.6-2
+ tags:
+ - rsc
+ - docker
+ - shared
+ stage: lint
+ script:
+ - dockerfile_lint -f Dockerfile
+
+build-job:
+ stage: build
+ tags:
+ - rsc
+ - docker-privileged
+ script:
+ - docker login -u $DOCKER_USERNAME -p $DOCKER_PASSWORD
+ - docker build -t $CONTAINER_RELEASE_IMAGE:$CONTAINER_TAG --build-arg http_proxy=$http_proxy --build-arg https_proxy=$http_proxy .
+ - docker push $CONTAINER_RELEASE_IMAGE:$CONTAINER_TAG
+
+test-job:
+ stage: test
+ tags:
+ - rsc
+ - docker-privileged
+ script:
+ - docker login -u $DOCKER_USERNAME -p $DOCKER_PASSWORD
+ - docker run -e http_proxy=$http_proxy -e https_proxy=$http_proxy $CONTAINER_RELEASE_IMAGE:$CONTAINER_TAG curl http://localhost:8000
+
+publish-job:
+ stage: publish
+ tags:
+ - rsc
+ - docker-privileged
+ script:
+ - docker login -u $DOCKER_USERNAME -p $DOCKER_PASSWORD
+ - FINAL_TAG=$(grep version setup.cfg | cut -d "=" -f 2)
+ - echo FINAL_TAG=$FINAL_TAG
+ - docker pull $CONTAINER_RELEASE_IMAGE:$CONTAINER_TAG
+ - docker tag $CONTAINER_RELEASE_IMAGE:$CONTAINER_TAG $CONTAINER_RELEASE_IMAGE:$FINAL_TAG
+ - docker push $CONTAINER_RELEASE_IMAGE:$FINAL_TAG
+ only:
+ - master
diff --git a/moon_dashboard/Dockerfile b/moon_dashboard/Dockerfile
new file mode 100644
index 00000000..8f997fe1
--- /dev/null
+++ b/moon_dashboard/Dockerfile
@@ -0,0 +1,34 @@
+FROM python:3.5
+
+LABEL Name=Dashboard
+LABEL Description="User interface for the Moon platform"
+LABEL Maintainer="Thomas Duval"
+LABEL Url="https://wiki.opnfv.org/display/moon/Moon+Project+Proposal"
+
+ENV MANAGER_HOST="127.0.0.1"
+ENV MANAGER_PORT=30001
+ENV KEYSTONE_HOST="127.0.0.1"
+ENV KEYSTONE_PORT=30005
+ENV OPENSTACK_HOST="127.0.0.1"
+ENV OPENSTACK_KEYSTONE_URL="http://${KEYSTONE_HOST}:${KEYSTONE_PORT}/v2.0"
+
+USER root
+
+WORKDIR /root/
+ADD . /root
+
+RUN git clone https://git.openstack.org/openstack/horizon
+
+WORKDIR /root/horizon
+
+RUN pip install --no-cache-dir -c http://git.openstack.org/cgit/openstack/requirements/plain/upper-constraints.txt .
+
+RUN cp openstack_dashboard/local/local_settings.py.example openstack_dashboard/local/local_settings.py
+RUN pip install --no-cache-dir tox
+
+WORKDIR /root/
+
+RUN cp -v moon/enabled/_32000_moon.py horizon/openstack_dashboard/local/enabled/_32000_moon.py
+RUN cp -rv moon/ horizon/openstack_dashboard/dashboards/
+
+CMD ["/bin/sh", "/root/run.sh"] \ No newline at end of file
diff --git a/moon_manager/tests/unit_python/api/__init__.py b/moon_dashboard/LICENSE
index e69de29b..e69de29b 100644
--- a/moon_manager/tests/unit_python/api/__init__.py
+++ b/moon_dashboard/LICENSE
diff --git a/moon_dashboard/MANIFEST.in b/moon_dashboard/MANIFEST.in
new file mode 100644
index 00000000..1f077b06
--- /dev/null
+++ b/moon_dashboard/MANIFEST.in
@@ -0,0 +1,3 @@
+include setup.py
+
+recursive-include myplugin *.js *.html *.scss \ No newline at end of file
diff --git a/moon_dashboard/README.md b/moon_dashboard/README.md
new file mode 100644
index 00000000..fca52b2d
--- /dev/null
+++ b/moon_dashboard/README.md
@@ -0,0 +1,40 @@
+# Moon plugin for Horizon (OpenStack Dashboard)
+
+## Install Horizon
+
+https://docs.openstack.org/horizon/latest/install/index.html
+
+or for developper quick start:
+
+https://docs.openstack.org/horizon/latest/contributor/quickstart.html
+
+
+## Moon plugin
+
+Clone the plugin:
+
+```bash
+git clone https://gitlab.forge.orange-labs.fr/moon/dashboard.git
+```
+
+* ``$plugin`` is the location of moon plugin
+* ``$horizon`` is the location of horizon
+
+Make symbolic link to enabled file:
+
+```bash
+ln -s $plugin/moon/enabled/_32000_moon.py $horizon/openstack_dashboard/local/enabled/_32000_moon.py
+```
+
+Make symbolic link to dashboard folder:
+
+```bash
+ln -s $plugin/moon/ $horizon/openstack_dashboard/dashboards/moon
+```
+
+Finish by restarting the Horizon server.
+
+## Set Moon API endpoint
+
+Set the endpoint in $plugin/moon/moon/static/moon/js/moon.module.js file
+
diff --git a/moon_dashboard/README.rst b/moon_dashboard/README.rst
new file mode 100644
index 00000000..de9c4058
--- /dev/null
+++ b/moon_dashboard/README.rst
@@ -0,0 +1,39 @@
+=============================================
+Moon plugin for Horizon (OpenStack Dashboard)
+=============================================
+
+Install Horizon
+===============
+
+https://docs.openstack.org/horizon/latest/install/index.html
+
+or for developper quick start:
+
+https://docs.openstack.org/horizon/latest/contributor/quickstart.html
+
+
+Moon plugin
+===========
+
+Clone the plugin:
+
+"git clone https://gitlab.forge.orange-labs.fr/moon/dashboard.git"
+
+* ``plugin`` is the location of moon plugin
+* ``horizon`` is the location of horizon
+
+Make symbolic link to enabled file:
+
+"ln -s ``plugin`Ì€`/moon/enabled/_32000_moon.py ``horizon``/openstack_dashboard/local/enabled/_32000_moon.py"
+
+Make symbolic link to dashboard folder:
+
+"ln -s ``plugin`Ì€`/moon/ ``horizon``/openstack_dashboard/dashboards/moon"
+
+Finish by restarting the Horizon server.
+
+
+Set Moon API endpoint
+===========
+
+Set the endpoint in ``plugin``/moon/moon/static/moon/js/moon.module.js file \ No newline at end of file
diff --git a/moon_dashboard/babel-django.cfg b/moon_dashboard/babel-django.cfg
new file mode 100644
index 00000000..fa906ad8
--- /dev/null
+++ b/moon_dashboard/babel-django.cfg
@@ -0,0 +1,5 @@
+[extractors]
+django = django_babel.extract:extract_django
+
+[python: **.py]
+[django: **/templates/**.html] \ No newline at end of file
diff --git a/moon_dashboard/babel-djangojs.cfg b/moon_dashboard/babel-djangojs.cfg
new file mode 100644
index 00000000..1c07ba6a
--- /dev/null
+++ b/moon_dashboard/babel-djangojs.cfg
@@ -0,0 +1,14 @@
+[extractors]
+# We use a custom extractor to find translatable strings in AngularJS
+# templates. The extractor is included in horizon.utils for now.
+# See http://babel.pocoo.org/docs/messages/#referencing-extraction-methods for
+# details on how this works.
+angular = horizon.utils.babel_extract_angular:extract_angular
+
+[javascript: **.js]
+
+# We need to look into all static folders for HTML files.
+# The **/static ensures that we also search within
+# /openstack_dashboard/dashboards/XYZ/static which will ensure
+# that plugins are also translated.
+[angular: **/static/**.html] \ No newline at end of file
diff --git a/moon_dashboard/moon/__init__.py b/moon_dashboard/moon/__init__.py
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/moon_dashboard/moon/__init__.py
diff --git a/moon_dashboard/moon/dashboard.py b/moon_dashboard/moon/dashboard.py
new file mode 100644
index 00000000..0e3e491e
--- /dev/null
+++ b/moon_dashboard/moon/dashboard.py
@@ -0,0 +1,13 @@
+from django.utils.translation import ugettext_lazy as _
+
+import horizon
+
+
+class Moon(horizon.Dashboard):
+ name = _("Moon")
+ slug = "moon"
+ panels = ('model','policy','pdp',) # Add your panels here.
+ default_panel = 'model' # Specify the slug of the default panel.
+
+
+horizon.register(Moon)
diff --git a/moon_dashboard/moon/enabled/_32000_moon.py b/moon_dashboard/moon/enabled/_32000_moon.py
new file mode 100644
index 00000000..73198de6
--- /dev/null
+++ b/moon_dashboard/moon/enabled/_32000_moon.py
@@ -0,0 +1,19 @@
+# The name of the dashboard to be added to HORIZON['dashboards']. Required.
+DASHBOARD = 'moon'
+
+# If set to True, this dashboard will not be added to the settings.
+DISABLED = False
+
+# A list of AngularJS modules to be loaded when Angular bootstraps.
+ADD_ANGULAR_MODULES = ['moon']
+
+# Automatically discover static resources in installed apps
+AUTO_DISCOVER_STATIC_FILES = True
+
+# A list of applications to be added to INSTALLED_APPS.
+ADD_INSTALLED_APPS = [
+ 'openstack_dashboard.dashboards.moon',
+]
+
+# A list of scss files to be included in the compressed set of files
+ADD_SCSS_FILES = ['moon/scss/moon.scss']
diff --git a/moon_dashboard/moon/model/__init__.py b/moon_dashboard/moon/model/__init__.py
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/moon_dashboard/moon/model/__init__.py
diff --git a/moon_dashboard/moon/model/panel.py b/moon_dashboard/moon/model/panel.py
new file mode 100644
index 00000000..9cb65ef0
--- /dev/null
+++ b/moon_dashboard/moon/model/panel.py
@@ -0,0 +1,23 @@
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License. You may obtain
+# a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+
+from django.utils.translation import ugettext_lazy as _
+
+import horizon
+from openstack_dashboard.dashboards.moon import dashboard
+
+class Model(horizon.Panel):
+ name = _("Models")
+ slug = "model"
+
+
+dashboard.Moon.register(Model)
diff --git a/moon_dashboard/moon/model/templates/model/index.html b/moon_dashboard/moon/model/templates/model/index.html
new file mode 100644
index 00000000..db372a02
--- /dev/null
+++ b/moon_dashboard/moon/model/templates/model/index.html
@@ -0,0 +1,16 @@
+{% extends 'base.html' %}
+{% load i18n %}
+{% block title %}{% trans "Models" %}{% endblock %}
+
+{% block page_header %}
+ {% include "horizon/common/_page_header.html" with title=_("Models") %}
+{% endblock page_header %}
+
+
+
+{% block main %}
+ <ng-include
+ src="'{{ STATIC_URL }}moon/model/model.html'">
+ </ng-include>
+{% endblock %}
+
diff --git a/moon_dashboard/moon/model/tests.py b/moon_dashboard/moon/model/tests.py
new file mode 100644
index 00000000..ec988636
--- /dev/null
+++ b/moon_dashboard/moon/model/tests.py
@@ -0,0 +1,19 @@
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License. You may obtain
+# a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+
+from horizon.test import helpers as test
+
+
+class MypanelTests(test.TestCase):
+ # Unit tests for mypanel.
+ def test_me(self):
+ self.assertTrue(1 + 1 == 2)
diff --git a/moon_dashboard/moon/model/urls.py b/moon_dashboard/moon/model/urls.py
new file mode 100644
index 00000000..ca9507fb
--- /dev/null
+++ b/moon_dashboard/moon/model/urls.py
@@ -0,0 +1,20 @@
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License. You may obtain
+# a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+
+from django.conf.urls import url
+
+from openstack_dashboard.dashboards.moon.model import views
+
+
+urlpatterns = [
+ url(r'^$', views.IndexView.as_view(), name='index'),
+]
diff --git a/moon_dashboard/moon/model/views.py b/moon_dashboard/moon/model/views.py
new file mode 100644
index 00000000..73509537
--- /dev/null
+++ b/moon_dashboard/moon/model/views.py
@@ -0,0 +1,22 @@
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License. You may obtain
+# a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+
+from horizon import views
+
+
+class IndexView(views.APIView):
+ # A very simple class-based view...
+ template_name = 'moon/model/index.html'
+
+ def get_data(self, request, context, *args, **kwargs):
+ # Add data to the context here...
+ return context
diff --git a/moon_dashboard/moon/pdp/__init__.py b/moon_dashboard/moon/pdp/__init__.py
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/moon_dashboard/moon/pdp/__init__.py
diff --git a/moon_dashboard/moon/pdp/panel.py b/moon_dashboard/moon/pdp/panel.py
new file mode 100644
index 00000000..9c4b3fa3
--- /dev/null
+++ b/moon_dashboard/moon/pdp/panel.py
@@ -0,0 +1,23 @@
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License. You may obtain
+# a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+
+from django.utils.translation import ugettext_lazy as _
+
+import horizon
+from openstack_dashboard.dashboards.moon import dashboard
+
+class Pdp(horizon.Panel):
+ name = _("PDP")
+ slug = "pdp"
+
+
+dashboard.Moon.register(Pdp)
diff --git a/moon_dashboard/moon/pdp/templates/pdp/index.html b/moon_dashboard/moon/pdp/templates/pdp/index.html
new file mode 100644
index 00000000..30ac5f93
--- /dev/null
+++ b/moon_dashboard/moon/pdp/templates/pdp/index.html
@@ -0,0 +1,16 @@
+{% extends 'base.html' %}
+{% load i18n %}
+{% block title %}{% trans "PDP" %}{% endblock %}
+
+{% block page_header %}
+ {% include "horizon/common/_page_header.html" with title=_("PDP") %}
+{% endblock page_header %}
+
+
+
+{% block main %}
+ <ng-include
+ src="'{{ STATIC_URL }}moon/pdp/pdp.html'">
+ </ng-include>
+{% endblock %}
+
diff --git a/moon_dashboard/moon/pdp/tests.py b/moon_dashboard/moon/pdp/tests.py
new file mode 100644
index 00000000..ec988636
--- /dev/null
+++ b/moon_dashboard/moon/pdp/tests.py
@@ -0,0 +1,19 @@
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License. You may obtain
+# a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+
+from horizon.test import helpers as test
+
+
+class MypanelTests(test.TestCase):
+ # Unit tests for mypanel.
+ def test_me(self):
+ self.assertTrue(1 + 1 == 2)
diff --git a/moon_dashboard/moon/pdp/urls.py b/moon_dashboard/moon/pdp/urls.py
new file mode 100644
index 00000000..a66c8e0c
--- /dev/null
+++ b/moon_dashboard/moon/pdp/urls.py
@@ -0,0 +1,20 @@
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License. You may obtain
+# a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+
+from django.conf.urls import url
+
+from openstack_dashboard.dashboards.moon.pdp import views
+
+
+urlpatterns = [
+ url(r'^$', views.IndexView.as_view(), name='index'),
+]
diff --git a/moon_dashboard/moon/pdp/views.py b/moon_dashboard/moon/pdp/views.py
new file mode 100644
index 00000000..8355a5d5
--- /dev/null
+++ b/moon_dashboard/moon/pdp/views.py
@@ -0,0 +1,22 @@
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License. You may obtain
+# a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+
+from horizon import views
+
+
+class IndexView(views.APIView):
+ # A very simple class-based view...
+ template_name = 'moon/pdp/index.html'
+
+ def get_data(self, request, context, *args, **kwargs):
+ # Add data to the context here...
+ return context
diff --git a/moon_dashboard/moon/policy/__init__.py b/moon_dashboard/moon/policy/__init__.py
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/moon_dashboard/moon/policy/__init__.py
diff --git a/moon_dashboard/moon/policy/panel.py b/moon_dashboard/moon/policy/panel.py
new file mode 100644
index 00000000..875a2d76
--- /dev/null
+++ b/moon_dashboard/moon/policy/panel.py
@@ -0,0 +1,23 @@
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License. You may obtain
+# a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+
+from django.utils.translation import ugettext_lazy as _
+
+import horizon
+from openstack_dashboard.dashboards.moon import dashboard
+
+class Policy(horizon.Panel):
+ name = _("Policies")
+ slug = "policy"
+
+
+dashboard.Moon.register(Policy)
diff --git a/moon_dashboard/moon/policy/templates/policy/index.html b/moon_dashboard/moon/policy/templates/policy/index.html
new file mode 100644
index 00000000..67cd9c3d
--- /dev/null
+++ b/moon_dashboard/moon/policy/templates/policy/index.html
@@ -0,0 +1,16 @@
+{% extends 'base.html' %}
+{% load i18n %}
+{% block title %}{% trans "Policies" %}{% endblock %}
+
+{% block page_header %}
+ {% include "horizon/common/_page_header.html" with title=_("Policies") %}
+{% endblock page_header %}
+
+
+
+{% block main %}
+ <ng-include
+ src="'{{ STATIC_URL }}moon/policy/policy.html'">
+ </ng-include>
+{% endblock %}
+
diff --git a/moon_dashboard/moon/policy/tests.py b/moon_dashboard/moon/policy/tests.py
new file mode 100644
index 00000000..ec988636
--- /dev/null
+++ b/moon_dashboard/moon/policy/tests.py
@@ -0,0 +1,19 @@
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License. You may obtain
+# a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+
+from horizon.test import helpers as test
+
+
+class MypanelTests(test.TestCase):
+ # Unit tests for mypanel.
+ def test_me(self):
+ self.assertTrue(1 + 1 == 2)
diff --git a/moon_dashboard/moon/policy/urls.py b/moon_dashboard/moon/policy/urls.py
new file mode 100644
index 00000000..81bde0ca
--- /dev/null
+++ b/moon_dashboard/moon/policy/urls.py
@@ -0,0 +1,20 @@
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License. You may obtain
+# a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+
+from django.conf.urls import url
+
+from openstack_dashboard.dashboards.moon.policy import views
+
+
+urlpatterns = [
+ url(r'^$', views.IndexView.as_view(), name='index'),
+]
diff --git a/moon_dashboard/moon/policy/views.py b/moon_dashboard/moon/policy/views.py
new file mode 100644
index 00000000..826c833b
--- /dev/null
+++ b/moon_dashboard/moon/policy/views.py
@@ -0,0 +1,22 @@
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License. You may obtain
+# a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+
+from horizon import views
+
+
+class IndexView(views.APIView):
+ # A very simple class-based view...
+ template_name = 'moon/policy/index.html'
+
+ def get_data(self, request, context, *args, **kwargs):
+ # Add data to the context here...
+ return context
diff --git a/moon_dashboard/moon/static/moon/js/angular-resource.js b/moon_dashboard/moon/static/moon/js/angular-resource.js
new file mode 100644
index 00000000..e8bb3014
--- /dev/null
+++ b/moon_dashboard/moon/static/moon/js/angular-resource.js
@@ -0,0 +1,863 @@
+/**
+ * @license AngularJS v1.5.8
+ * (c) 2010-2016 Google, Inc. http://angularjs.org
+ * License: MIT
+ */
+(function(window, angular) {'use strict';
+
+var $resourceMinErr = angular.$$minErr('$resource');
+
+// Helper functions and regex to lookup a dotted path on an object
+// stopping at undefined/null. The path must be composed of ASCII
+// identifiers (just like $parse)
+var MEMBER_NAME_REGEX = /^(\.[a-zA-Z_$@][0-9a-zA-Z_$@]*)+$/;
+
+function isValidDottedPath(path) {
+ return (path != null && path !== '' && path !== 'hasOwnProperty' &&
+ MEMBER_NAME_REGEX.test('.' + path));
+}
+
+function lookupDottedPath(obj, path) {
+ if (!isValidDottedPath(path)) {
+ throw $resourceMinErr('badmember', 'Dotted member path "@{0}" is invalid.', path);
+ }
+ var keys = path.split('.');
+ for (var i = 0, ii = keys.length; i < ii && angular.isDefined(obj); i++) {
+ var key = keys[i];
+ obj = (obj !== null) ? obj[key] : undefined;
+ }
+ return obj;
+}
+
+/**
+ * Create a shallow copy of an object and clear other fields from the destination
+ */
+function shallowClearAndCopy(src, dst) {
+ dst = dst || {};
+
+ angular.forEach(dst, function(value, key) {
+ delete dst[key];
+ });
+
+ for (var key in src) {
+ if (src.hasOwnProperty(key) && !(key.charAt(0) === '$' && key.charAt(1) === '$')) {
+ dst[key] = src[key];
+ }
+ }
+
+ return dst;
+}
+
+/**
+ * @ngdoc module
+ * @name ngResource
+ * @description
+ *
+ * # ngResource
+ *
+ * The `ngResource` module provides interaction support with RESTful services
+ * via the $resource service.
+ *
+ *
+ * <div doc-module-components="ngResource"></div>
+ *
+ * See {@link ngResource.$resourceProvider} and {@link ngResource.$resource} for usage.
+ */
+
+/**
+ * @ngdoc provider
+ * @name $resourceProvider
+ *
+ * @description
+ *
+ * Use `$resourceProvider` to change the default behavior of the {@link ngResource.$resource}
+ * service.
+ *
+ * ## Dependencies
+ * Requires the {@link ngResource } module to be installed.
+ *
+ */
+
+/**
+ * @ngdoc service
+ * @name $resource
+ * @requires $http
+ * @requires ng.$log
+ * @requires $q
+ * @requires ng.$timeout
+ *
+ * @description
+ * A factory which creates a resource object that lets you interact with
+ * [RESTful](http://en.wikipedia.org/wiki/Representational_State_Transfer) server-side data sources.
+ *
+ * The returned resource object has action methods which provide high-level behaviors without
+ * the need to interact with the low level {@link ng.$http $http} service.
+ *
+ * Requires the {@link ngResource `ngResource`} module to be installed.
+ *
+ * By default, trailing slashes will be stripped from the calculated URLs,
+ * which can pose problems with server backends that do not expect that
+ * behavior. This can be disabled by configuring the `$resourceProvider` like
+ * this:
+ *
+ * ```js
+ app.config(['$resourceProvider', function($resourceProvider) {
+ // Don't strip trailing slashes from calculated URLs
+ $resourceProvider.defaults.stripTrailingSlashes = false;
+ }]);
+ * ```
+ *
+ * @param {string} url A parameterized URL template with parameters prefixed by `:` as in
+ * `/user/:username`. If you are using a URL with a port number (e.g.
+ * `http://example.com:8080/api`), it will be respected.
+ *
+ * If you are using a url with a suffix, just add the suffix, like this:
+ * `$resource('http://example.com/resource.json')` or `$resource('http://example.com/:id.json')`
+ * or even `$resource('http://example.com/resource/:resource_id.:format')`
+ * If the parameter before the suffix is empty, :resource_id in this case, then the `/.` will be
+ * collapsed down to a single `.`. If you need this sequence to appear and not collapse then you
+ * can escape it with `/\.`.
+ *
+ * @param {Object=} paramDefaults Default values for `url` parameters. These can be overridden in
+ * `actions` methods. If a parameter value is a function, it will be called every time
+ * a param value needs to be obtained for a request (unless the param was overridden). The function
+ * will be passed the current data value as an argument.
+ *
+ * Each key value in the parameter object is first bound to url template if present and then any
+ * excess keys are appended to the url search query after the `?`.
+ *
+ * Given a template `/path/:verb` and parameter `{verb:'greet', salutation:'Hello'}` results in
+ * URL `/path/greet?salutation=Hello`.
+ *
+ * If the parameter value is prefixed with `@`, then the value for that parameter will be
+ * extracted from the corresponding property on the `data` object (provided when calling a
+ * "non-GET" action method).
+ * For example, if the `defaultParam` object is `{someParam: '@someProp'}` then the value of
+ * `someParam` will be `data.someProp`.
+ * Note that the parameter will be ignored, when calling a "GET" action method (i.e. an action
+ * method that does not accept a request body)
+ *
+ * @param {Object.<Object>=} actions Hash with declaration of custom actions that should extend
+ * the default set of resource actions. The declaration should be created in the format of {@link
+ * ng.$http#usage $http.config}:
+ *
+ * {action1: {method:?, params:?, isArray:?, headers:?, ...},
+ * action2: {method:?, params:?, isArray:?, headers:?, ...},
+ * ...}
+ *
+ * Where:
+ *
+ * - **`action`** – {string} – The name of action. This name becomes the name of the method on
+ * your resource object.
+ * - **`method`** – {string} – Case insensitive HTTP method (e.g. `GET`, `POST`, `PUT`,
+ * `DELETE`, `JSONP`, etc).
+ * - **`params`** – {Object=} – Optional set of pre-bound parameters for this action. If any of
+ * the parameter value is a function, it will be called every time when a param value needs to
+ * be obtained for a request (unless the param was overridden). The function will be passed the
+ * current data value as an argument.
+ * - **`url`** – {string} – action specific `url` override. The url templating is supported just
+ * like for the resource-level urls.
+ * - **`isArray`** – {boolean=} – If true then the returned object for this action is an array,
+ * see `returns` section.
+ * - **`transformRequest`** –
+ * `{function(data, headersGetter)|Array.<function(data, headersGetter)>}` –
+ * transform function or an array of such functions. The transform function takes the http
+ * request body and headers and returns its transformed (typically serialized) version.
+ * By default, transformRequest will contain one function that checks if the request data is
+ * an object and serializes to using `angular.toJson`. To prevent this behavior, set
+ * `transformRequest` to an empty array: `transformRequest: []`
+ * - **`transformResponse`** –
+ * `{function(data, headersGetter)|Array.<function(data, headersGetter)>}` –
+ * transform function or an array of such functions. The transform function takes the http
+ * response body and headers and returns its transformed (typically deserialized) version.
+ * By default, transformResponse will contain one function that checks if the response looks
+ * like a JSON string and deserializes it using `angular.fromJson`. To prevent this behavior,
+ * set `transformResponse` to an empty array: `transformResponse: []`
+ * - **`cache`** – `{boolean|Cache}` – If true, a default $http cache will be used to cache the
+ * GET request, otherwise if a cache instance built with
+ * {@link ng.$cacheFactory $cacheFactory}, this cache will be used for
+ * caching.
+ * - **`timeout`** – `{number}` – timeout in milliseconds.<br />
+ * **Note:** In contrast to {@link ng.$http#usage $http.config}, {@link ng.$q promises} are
+ * **not** supported in $resource, because the same value would be used for multiple requests.
+ * If you are looking for a way to cancel requests, you should use the `cancellable` option.
+ * - **`cancellable`** – `{boolean}` – if set to true, the request made by a "non-instance" call
+ * will be cancelled (if not already completed) by calling `$cancelRequest()` on the call's
+ * return value. Calling `$cancelRequest()` for a non-cancellable or an already
+ * completed/cancelled request will have no effect.<br />
+ * - **`withCredentials`** - `{boolean}` - whether to set the `withCredentials` flag on the
+ * XHR object. See
+ * [requests with credentials](https://developer.mozilla.org/en/http_access_control#section_5)
+ * for more information.
+ * - **`responseType`** - `{string}` - see
+ * [requestType](https://developer.mozilla.org/en-US/docs/DOM/XMLHttpRequest#responseType).
+ * - **`interceptor`** - `{Object=}` - The interceptor object has two optional methods -
+ * `response` and `responseError`. Both `response` and `responseError` interceptors get called
+ * with `http response` object. See {@link ng.$http $http interceptors}.
+ *
+ * @param {Object} options Hash with custom settings that should extend the
+ * default `$resourceProvider` behavior. The supported options are:
+ *
+ * - **`stripTrailingSlashes`** – {boolean} – If true then the trailing
+ * slashes from any calculated URL will be stripped. (Defaults to true.)
+ * - **`cancellable`** – {boolean} – If true, the request made by a "non-instance" call will be
+ * cancelled (if not already completed) by calling `$cancelRequest()` on the call's return value.
+ * This can be overwritten per action. (Defaults to false.)
+ *
+ * @returns {Object} A resource "class" object with methods for the default set of resource actions
+ * optionally extended with custom `actions`. The default set contains these actions:
+ * ```js
+ * { 'get': {method:'GET'},
+ * 'save': {method:'POST'},
+ * 'query': {method:'GET', isArray:true},
+ * 'remove': {method:'DELETE'},
+ * 'delete': {method:'DELETE'} };
+ * ```
+ *
+ * Calling these methods invoke an {@link ng.$http} with the specified http method,
+ * destination and parameters. When the data is returned from the server then the object is an
+ * instance of the resource class. The actions `save`, `remove` and `delete` are available on it
+ * as methods with the `$` prefix. This allows you to easily perform CRUD operations (create,
+ * read, update, delete) on server-side data like this:
+ * ```js
+ * var User = $resource('/user/:userId', {userId:'@id'});
+ * var user = User.get({userId:123}, function() {
+ * user.abc = true;
+ * user.$save();
+ * });
+ * ```
+ *
+ * It is important to realize that invoking a $resource object method immediately returns an
+ * empty reference (object or array depending on `isArray`). Once the data is returned from the
+ * server the existing reference is populated with the actual data. This is a useful trick since
+ * usually the resource is assigned to a model which is then rendered by the view. Having an empty
+ * object results in no rendering, once the data arrives from the server then the object is
+ * populated with the data and the view automatically re-renders itself showing the new data. This
+ * means that in most cases one never has to write a callback function for the action methods.
+ *
+ * The action methods on the class object or instance object can be invoked with the following
+ * parameters:
+ *
+ * - HTTP GET "class" actions: `Resource.action([parameters], [success], [error])`
+ * - non-GET "class" actions: `Resource.action([parameters], postData, [success], [error])`
+ * - non-GET instance actions: `instance.$action([parameters], [success], [error])`
+ *
+ *
+ * Success callback is called with (value, responseHeaders) arguments, where the value is
+ * the populated resource instance or collection object. The error callback is called
+ * with (httpResponse) argument.
+ *
+ * Class actions return empty instance (with additional properties below).
+ * Instance actions return promise of the action.
+ *
+ * The Resource instances and collections have these additional properties:
+ *
+ * - `$promise`: the {@link ng.$q promise} of the original server interaction that created this
+ * instance or collection.
+ *
+ * On success, the promise is resolved with the same resource instance or collection object,
+ * updated with data from server. This makes it easy to use in
+ * {@link ngRoute.$routeProvider resolve section of $routeProvider.when()} to defer view
+ * rendering until the resource(s) are loaded.
+ *
+ * On failure, the promise is rejected with the {@link ng.$http http response} object, without
+ * the `resource` property.
+ *
+ * If an interceptor object was provided, the promise will instead be resolved with the value
+ * returned by the interceptor.
+ *
+ * - `$resolved`: `true` after first server interaction is completed (either with success or
+ * rejection), `false` before that. Knowing if the Resource has been resolved is useful in
+ * data-binding.
+ *
+ * The Resource instances and collections have these additional methods:
+ *
+ * - `$cancelRequest`: If there is a cancellable, pending request related to the instance or
+ * collection, calling this method will abort the request.
+ *
+ * The Resource instances have these additional methods:
+ *
+ * - `toJSON`: It returns a simple object without any of the extra properties added as part of
+ * the Resource API. This object can be serialized through {@link angular.toJson} safely
+ * without attaching Angular-specific fields. Notice that `JSON.stringify` (and
+ * `angular.toJson`) automatically use this method when serializing a Resource instance
+ * (see [MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify#toJSON()_behavior)).
+ *
+ * @example
+ *
+ * # Credit card resource
+ *
+ * ```js
+ // Define CreditCard class
+ var CreditCard = $resource('/user/:userId/card/:cardId',
+ {userId:123, cardId:'@id'}, {
+ charge: {method:'POST', params:{charge:true}}
+ });
+
+ // We can retrieve a collection from the server
+ var cards = CreditCard.query(function() {
+ // GET: /user/123/card
+ // server returns: [ {id:456, number:'1234', name:'Smith'} ];
+
+ var card = cards[0];
+ // each item is an instance of CreditCard
+ expect(card instanceof CreditCard).toEqual(true);
+ card.name = "J. Smith";
+ // non GET methods are mapped onto the instances
+ card.$save();
+ // POST: /user/123/card/456 {id:456, number:'1234', name:'J. Smith'}
+ // server returns: {id:456, number:'1234', name: 'J. Smith'};
+
+ // our custom method is mapped as well.
+ card.$charge({amount:9.99});
+ // POST: /user/123/card/456?amount=9.99&charge=true {id:456, number:'1234', name:'J. Smith'}
+ });
+
+ // we can create an instance as well
+ var newCard = new CreditCard({number:'0123'});
+ newCard.name = "Mike Smith";
+ newCard.$save();
+ // POST: /user/123/card {number:'0123', name:'Mike Smith'}
+ // server returns: {id:789, number:'0123', name: 'Mike Smith'};
+ expect(newCard.id).toEqual(789);
+ * ```
+ *
+ * The object returned from this function execution is a resource "class" which has "static" method
+ * for each action in the definition.
+ *
+ * Calling these methods invoke `$http` on the `url` template with the given `method`, `params` and
+ * `headers`.
+ *
+ * @example
+ *
+ * # User resource
+ *
+ * When the data is returned from the server then the object is an instance of the resource type and
+ * all of the non-GET methods are available with `$` prefix. This allows you to easily support CRUD
+ * operations (create, read, update, delete) on server-side data.
+
+ ```js
+ var User = $resource('/user/:userId', {userId:'@id'});
+ User.get({userId:123}, function(user) {
+ user.abc = true;
+ user.$save();
+ });
+ ```
+ *
+ * It's worth noting that the success callback for `get`, `query` and other methods gets passed
+ * in the response that came from the server as well as $http header getter function, so one
+ * could rewrite the above example and get access to http headers as:
+ *
+ ```js
+ var User = $resource('/user/:userId', {userId:'@id'});
+ User.get({userId:123}, function(user, getResponseHeaders){
+ user.abc = true;
+ user.$save(function(user, putResponseHeaders) {
+ //user => saved user object
+ //putResponseHeaders => $http header getter
+ });
+ });
+ ```
+ *
+ * You can also access the raw `$http` promise via the `$promise` property on the object returned
+ *
+ ```
+ var User = $resource('/user/:userId', {userId:'@id'});
+ User.get({userId:123})
+ .$promise.then(function(user) {
+ $scope.user = user;
+ });
+ ```
+ *
+ * @example
+ *
+ * # Creating a custom 'PUT' request
+ *
+ * In this example we create a custom method on our resource to make a PUT request
+ * ```js
+ * var app = angular.module('app', ['ngResource', 'ngRoute']);
+ *
+ * // Some APIs expect a PUT request in the format URL/object/ID
+ * // Here we are creating an 'update' method
+ * app.factory('Notes', ['$resource', function($resource) {
+ * return $resource('/notes/:id', null,
+ * {
+ * 'update': { method:'PUT' }
+ * });
+ * }]);
+ *
+ * // In our controller we get the ID from the URL using ngRoute and $routeParams
+ * // We pass in $routeParams and our Notes factory along with $scope
+ * app.controller('NotesCtrl', ['$scope', '$routeParams', 'Notes',
+ function($scope, $routeParams, Notes) {
+ * // First get a note object from the factory
+ * var note = Notes.get({ id:$routeParams.id });
+ * $id = note.id;
+ *
+ * // Now call update passing in the ID first then the object you are updating
+ * Notes.update({ id:$id }, note);
+ *
+ * // This will PUT /notes/ID with the note object in the request payload
+ * }]);
+ * ```
+ *
+ * @example
+ *
+ * # Cancelling requests
+ *
+ * If an action's configuration specifies that it is cancellable, you can cancel the request related
+ * to an instance or collection (as long as it is a result of a "non-instance" call):
+ *
+ ```js
+ // ...defining the `Hotel` resource...
+ var Hotel = $resource('/api/hotel/:id', {id: '@id'}, {
+ // Let's make the `query()` method cancellable
+ query: {method: 'get', isArray: true, cancellable: true}
+ });
+
+ // ...somewhere in the PlanVacationController...
+ ...
+ this.onDestinationChanged = function onDestinationChanged(destination) {
+ // We don't care about any pending request for hotels
+ // in a different destination any more
+ this.availableHotels.$cancelRequest();
+
+ // Let's query for hotels in '<destination>'
+ // (calls: /api/hotel?location=<destination>)
+ this.availableHotels = Hotel.query({location: destination});
+ };
+ ```
+ *
+ */
+angular.module('ngResource', ['ng']).
+ provider('$resource', function() {
+ var PROTOCOL_AND_DOMAIN_REGEX = /^https?:\/\/[^\/]*/;
+ var provider = this;
+
+ /**
+ * @ngdoc property
+ * @name $resourceProvider#defaults
+ * @description
+ * Object containing default options used when creating `$resource` instances.
+ *
+ * The default values satisfy a wide range of usecases, but you may choose to overwrite any of
+ * them to further customize your instances. The available properties are:
+ *
+ * - **stripTrailingSlashes** – `{boolean}` – If true, then the trailing slashes from any
+ * calculated URL will be stripped.<br />
+ * (Defaults to true.)
+ * - **cancellable** – `{boolean}` – If true, the request made by a "non-instance" call will be
+ * cancelled (if not already completed) by calling `$cancelRequest()` on the call's return
+ * value. For more details, see {@link ngResource.$resource}. This can be overwritten per
+ * resource class or action.<br />
+ * (Defaults to false.)
+ * - **actions** - `{Object.<Object>}` - A hash with default actions declarations. Actions are
+ * high-level methods corresponding to RESTful actions/methods on resources. An action may
+ * specify what HTTP method to use, what URL to hit, if the return value will be a single
+ * object or a collection (array) of objects etc. For more details, see
+ * {@link ngResource.$resource}. The actions can also be enhanced or overwritten per resource
+ * class.<br />
+ * The default actions are:
+ * ```js
+ * {
+ * get: {method: 'GET'},
+ * save: {method: 'POST'},
+ * query: {method: 'GET', isArray: true},
+ * remove: {method: 'DELETE'},
+ * delete: {method: 'DELETE'}
+ * }
+ * ```
+ *
+ * #### Example
+ *
+ * For example, you can specify a new `update` action that uses the `PUT` HTTP verb:
+ *
+ * ```js
+ * angular.
+ * module('myApp').
+ * config(['resourceProvider', function ($resourceProvider) {
+ * $resourceProvider.defaults.actions.update = {
+ * method: 'PUT'
+ * };
+ * });
+ * ```
+ *
+ * Or you can even overwrite the whole `actions` list and specify your own:
+ *
+ * ```js
+ * angular.
+ * module('myApp').
+ * config(['resourceProvider', function ($resourceProvider) {
+ * $resourceProvider.defaults.actions = {
+ * create: {method: 'POST'}
+ * get: {method: 'GET'},
+ * getAll: {method: 'GET', isArray:true},
+ * update: {method: 'PUT'},
+ * delete: {method: 'DELETE'}
+ * };
+ * });
+ * ```
+ *
+ */
+ this.defaults = {
+ // Strip slashes by default
+ stripTrailingSlashes: true,
+
+ // Make non-instance requests cancellable (via `$cancelRequest()`)
+ cancellable: false,
+
+ // Default actions configuration
+ actions: {
+ 'get': {method: 'GET'},
+ 'save': {method: 'POST'},
+ 'query': {method: 'GET', isArray: true},
+ 'remove': {method: 'DELETE'},
+ 'delete': {method: 'DELETE'}
+ }
+ };
+
+ this.$get = ['$http', '$log', '$q', '$timeout', function($http, $log, $q, $timeout) {
+
+ var noop = angular.noop,
+ forEach = angular.forEach,
+ extend = angular.extend,
+ copy = angular.copy,
+ isFunction = angular.isFunction;
+
+ /**
+ * We need our custom method because encodeURIComponent is too aggressive and doesn't follow
+ * http://www.ietf.org/rfc/rfc3986.txt with regards to the character set
+ * (pchar) allowed in path segments:
+ * segment = *pchar
+ * pchar = unreserved / pct-encoded / sub-delims / ":" / "@"
+ * pct-encoded = "%" HEXDIG HEXDIG
+ * unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~"
+ * sub-delims = "!" / "$" / "&" / "'" / "(" / ")"
+ * / "*" / "+" / "," / ";" / "="
+ */
+ function encodeUriSegment(val) {
+ return encodeUriQuery(val, true).
+ replace(/%26/gi, '&').
+ replace(/%3D/gi, '=').
+ replace(/%2B/gi, '+');
+ }
+
+
+ /**
+ * This method is intended for encoding *key* or *value* parts of query component. We need a
+ * custom method because encodeURIComponent is too aggressive and encodes stuff that doesn't
+ * have to be encoded per http://tools.ietf.org/html/rfc3986:
+ * query = *( pchar / "/" / "?" )
+ * pchar = unreserved / pct-encoded / sub-delims / ":" / "@"
+ * unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~"
+ * pct-encoded = "%" HEXDIG HEXDIG
+ * sub-delims = "!" / "$" / "&" / "'" / "(" / ")"
+ * / "*" / "+" / "," / ";" / "="
+ */
+ function encodeUriQuery(val, pctEncodeSpaces) {
+ return encodeURIComponent(val).
+ replace(/%40/gi, '@').
+ replace(/%3A/gi, ':').
+ replace(/%24/g, '$').
+ replace(/%2C/gi, ',').
+ replace(/%20/g, (pctEncodeSpaces ? '%20' : '+'));
+ }
+
+ function Route(template, defaults) {
+ this.template = template;
+ this.defaults = extend({}, provider.defaults, defaults);
+ this.urlParams = {};
+ }
+
+ Route.prototype = {
+ setUrlParams: function(config, params, actionUrl) {
+ var self = this,
+ url = actionUrl || self.template,
+ val,
+ encodedVal,
+ protocolAndDomain = '';
+
+ var urlParams = self.urlParams = {};
+ forEach(url.split(/\W/), function(param) {
+ if (param === 'hasOwnProperty') {
+ throw $resourceMinErr('badname', "hasOwnProperty is not a valid parameter name.");
+ }
+ if (!(new RegExp("^\\d+$").test(param)) && param &&
+ (new RegExp("(^|[^\\\\]):" + param + "(\\W|$)").test(url))) {
+ urlParams[param] = {
+ isQueryParamValue: (new RegExp("\\?.*=:" + param + "(?:\\W|$)")).test(url)
+ };
+ }
+ });
+ url = url.replace(/\\:/g, ':');
+ url = url.replace(PROTOCOL_AND_DOMAIN_REGEX, function(match) {
+ protocolAndDomain = match;
+ return '';
+ });
+
+ params = params || {};
+ forEach(self.urlParams, function(paramInfo, urlParam) {
+ val = params.hasOwnProperty(urlParam) ? params[urlParam] : self.defaults[urlParam];
+ if (angular.isDefined(val) && val !== null) {
+ if (paramInfo.isQueryParamValue) {
+ encodedVal = encodeUriQuery(val, true);
+ } else {
+ encodedVal = encodeUriSegment(val);
+ }
+ url = url.replace(new RegExp(":" + urlParam + "(\\W|$)", "g"), function(match, p1) {
+ return encodedVal + p1;
+ });
+ } else {
+ url = url.replace(new RegExp("(\/?):" + urlParam + "(\\W|$)", "g"), function(match,
+ leadingSlashes, tail) {
+ if (tail.charAt(0) == '/') {
+ return tail;
+ } else {
+ return leadingSlashes + tail;
+ }
+ });
+ }
+ });
+
+ // strip trailing slashes and set the url (unless this behavior is specifically disabled)
+ if (self.defaults.stripTrailingSlashes) {
+ url = url.replace(/\/+$/, '') || '/';
+ }
+
+ // then replace collapse `/.` if found in the last URL path segment before the query
+ // E.g. `http://url.com/id./format?q=x` becomes `http://url.com/id.format?q=x`
+ url = url.replace(/\/\.(?=\w+($|\?))/, '.');
+ // replace escaped `/\.` with `/.`
+ config.url = protocolAndDomain + url.replace(/\/\\\./, '/.');
+
+
+ // set params - delegate param encoding to $http
+ forEach(params, function(value, key) {
+ if (!self.urlParams[key]) {
+ config.params = config.params || {};
+ config.params[key] = value;
+ }
+ });
+ }
+ };
+
+
+ function resourceFactory(url, paramDefaults, actions, options) {
+ var route = new Route(url, options);
+
+ actions = extend({}, provider.defaults.actions, actions);
+
+ function extractParams(data, actionParams) {
+ var ids = {};
+ actionParams = extend({}, paramDefaults, actionParams);
+ forEach(actionParams, function(value, key) {
+ if (isFunction(value)) { value = value(data); }
+ ids[key] = value && value.charAt && value.charAt(0) == '@' ?
+ lookupDottedPath(data, value.substr(1)) : value;
+ });
+ return ids;
+ }
+
+ function defaultResponseInterceptor(response) {
+ return response.resource;
+ }
+
+ function Resource(value) {
+ shallowClearAndCopy(value || {}, this);
+ }
+
+ Resource.prototype.toJSON = function() {
+ var data = extend({}, this);
+ delete data.$promise;
+ delete data.$resolved;
+ return data;
+ };
+
+ forEach(actions, function(action, name) {
+ var hasBody = /^(POST|PUT|PATCH)$/i.test(action.method);
+ var numericTimeout = action.timeout;
+ var cancellable = angular.isDefined(action.cancellable) ? action.cancellable :
+ (options && angular.isDefined(options.cancellable)) ? options.cancellable :
+ provider.defaults.cancellable;
+
+ if (numericTimeout && !angular.isNumber(numericTimeout)) {
+ $log.debug('ngResource:\n' +
+ ' Only numeric values are allowed as `timeout`.\n' +
+ ' Promises are not supported in $resource, because the same value would ' +
+ 'be used for multiple requests. If you are looking for a way to cancel ' +
+ 'requests, you should use the `cancellable` option.');
+ delete action.timeout;
+ numericTimeout = null;
+ }
+
+ Resource[name] = function(a1, a2, a3, a4) {
+ var params = {}, data, success, error;
+
+ /* jshint -W086 */ /* (purposefully fall through case statements) */
+ switch (arguments.length) {
+ case 4:
+ error = a4;
+ success = a3;
+ //fallthrough
+ case 3:
+ case 2:
+ if (isFunction(a2)) {
+ if (isFunction(a1)) {
+ success = a1;
+ error = a2;
+ break;
+ }
+
+ success = a2;
+ error = a3;
+ //fallthrough
+ } else {
+ params = a1;
+ data = a2;
+ success = a3;
+ break;
+ }
+ case 1:
+ if (isFunction(a1)) success = a1;
+ else if (hasBody) data = a1;
+ else params = a1;
+ break;
+ case 0: break;
+ default:
+ throw $resourceMinErr('badargs',
+ "Expected up to 4 arguments [params, data, success, error], got {0} arguments",
+ arguments.length);
+ }
+ /* jshint +W086 */ /* (purposefully fall through case statements) */
+
+ var isInstanceCall = this instanceof Resource;
+ var value = isInstanceCall ? data : (action.isArray ? [] : new Resource(data));
+ var httpConfig = {};
+ var responseInterceptor = action.interceptor && action.interceptor.response ||
+ defaultResponseInterceptor;
+ var responseErrorInterceptor = action.interceptor && action.interceptor.responseError ||
+ undefined;
+ var timeoutDeferred;
+ var numericTimeoutPromise;
+
+ forEach(action, function(value, key) {
+ switch (key) {
+ default:
+ httpConfig[key] = copy(value);
+ break;
+ case 'params':
+ case 'isArray':
+ case 'interceptor':
+ case 'cancellable':
+ break;
+ }
+ });
+
+ if (!isInstanceCall && cancellable) {
+ timeoutDeferred = $q.defer();
+ httpConfig.timeout = timeoutDeferred.promise;
+
+ if (numericTimeout) {
+ numericTimeoutPromise = $timeout(timeoutDeferred.resolve, numericTimeout);
+ }
+ }
+
+ if (hasBody) httpConfig.data = data;
+ route.setUrlParams(httpConfig,
+ extend({}, extractParams(data, action.params || {}), params),
+ action.url);
+
+ var promise = $http(httpConfig).then(function(response) {
+ var data = response.data;
+
+ if (data) {
+ // Need to convert action.isArray to boolean in case it is undefined
+ // jshint -W018
+ if (angular.isArray(data) !== (!!action.isArray)) {
+ throw $resourceMinErr('badcfg',
+ 'Error in resource configuration for action `{0}`. Expected response to ' +
+ 'contain an {1} but got an {2} (Request: {3} {4})', name, action.isArray ? 'array' : 'object',
+ angular.isArray(data) ? 'array' : 'object', httpConfig.method, httpConfig.url);
+ }
+ // jshint +W018
+ if (action.isArray) {
+ value.length = 0;
+ forEach(data, function(item) {
+ if (typeof item === "object") {
+ value.push(new Resource(item));
+ } else {
+ // Valid JSON values may be string literals, and these should not be converted
+ // into objects. These items will not have access to the Resource prototype
+ // methods, but unfortunately there
+ value.push(item);
+ }
+ });
+ } else {
+ var promise = value.$promise; // Save the promise
+ shallowClearAndCopy(data, value);
+ value.$promise = promise; // Restore the promise
+ }
+ }
+ response.resource = value;
+
+ return response;
+ }, function(response) {
+ (error || noop)(response);
+ return $q.reject(response);
+ });
+
+ promise['finally'](function() {
+ value.$resolved = true;
+ if (!isInstanceCall && cancellable) {
+ value.$cancelRequest = angular.noop;
+ $timeout.cancel(numericTimeoutPromise);
+ timeoutDeferred = numericTimeoutPromise = httpConfig.timeout = null;
+ }
+ });
+
+ promise = promise.then(
+ function(response) {
+ var value = responseInterceptor(response);
+ (success || noop)(value, response.headers);
+ return value;
+ },
+ responseErrorInterceptor);
+
+ if (!isInstanceCall) {
+ // we are creating instance / collection
+ // - set the initial promise
+ // - return the instance / collection
+ value.$promise = promise;
+ value.$resolved = false;
+ if (cancellable) value.$cancelRequest = timeoutDeferred.resolve;
+
+ return value;
+ }
+
+ // instance call
+ return promise;
+ };
+
+
+ Resource.prototype['$' + name] = function(params, success, error) {
+ if (isFunction(params)) {
+ error = success; success = params; params = {};
+ }
+ var result = Resource[name].call(this, params, this, success, error);
+ return result.$promise || result;
+ };
+ });
+
+ Resource.bind = function(additionalParamDefaults) {
+ return resourceFactory(url, extend({}, paramDefaults, additionalParamDefaults), actions);
+ };
+
+ return Resource;
+ }
+
+ return resourceFactory;
+ }];
+ });
+
+
+})(window, window.angular);
diff --git a/moon_dashboard/moon/static/moon/js/import.service.js b/moon_dashboard/moon/static/moon/js/import.service.js
new file mode 100755
index 00000000..d55c8a19
--- /dev/null
+++ b/moon_dashboard/moon/static/moon/js/import.service.js
@@ -0,0 +1,27 @@
+(function () {
+
+ 'use strict';
+
+ angular
+ .module('moon')
+ .factory('moon.import.service', importService);
+
+ importService.$inject = ['moon.util.service', '$resource', 'moon.URI'];
+
+ function importService(util, $resource, URI) {
+ var host = URI.API;
+ var importResource = $resource(host + '/import/', {}, {
+ create: { method: 'POST' },
+ });
+
+ return {
+ importData: function importData(data) {
+ return importResource.create(null, data).$promise.then(success, util.displayErrorFunction('Unable to import data'));
+
+ function success(data) {
+ util.displaySuccess('Data imported');
+ }
+ }
+ }
+ }
+})(); \ No newline at end of file
diff --git a/moon_dashboard/moon/static/moon/js/moon.module.js b/moon_dashboard/moon/static/moon/js/moon.module.js
new file mode 100755
index 00000000..ed56ec2a
--- /dev/null
+++ b/moon_dashboard/moon/static/moon/js/moon.module.js
@@ -0,0 +1,29 @@
+/**
+# Copyright 2015 Orange
+#
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License. You may obtain
+# a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+ */
+
+(function () {
+
+ 'use strict';
+
+ var moon = angular
+
+ .module('moon', [
+ 'ngResource',
+ ]).constant('moon.URI', {
+ API: 'http://{{MANAGER_HOST}}:{{MANAGER_PORT}}',
+ })
+
+})();
diff --git a/moon_dashboard/moon/static/moon/js/util.service.js b/moon_dashboard/moon/static/moon/js/util.service.js
new file mode 100755
index 00000000..18ae901d
--- /dev/null
+++ b/moon_dashboard/moon/static/moon/js/util.service.js
@@ -0,0 +1,136 @@
+(function () {
+
+ 'use strict';
+
+ angular
+ .module('moon')
+ .factory('moon.util.service', utilService);
+
+ utilService.$inject = ['horizon.framework.widgets.toast.service'];
+
+ function utilService(toast) {
+
+
+ return {
+ mapToArray: function mapToArray(map, action) {
+ var result = []
+ for (var key in map) {
+ if (map.hasOwnProperty(key)) {
+ var item = map[key];
+ item.id = key;
+ if (action != null) {
+ action(item);
+ }
+ result.push(item);
+ }
+ }
+ return result;
+ },
+
+ mapIdToItem: function mapIdToItem(array, map) {
+ if (array) {
+ for (var index = 0; index < array.length; index++) {
+ var id = array[index];
+ array[index] = map[id];
+ }
+ }
+ },
+
+ mapItemToId: function mapItemToId(array) {
+ if (array) {
+ for (var index = 0; index < array.length; index++) {
+ var item = array[index];
+ array[index] = item.id;
+ }
+ }
+ },
+
+ addToMap: function addToMap(array, map) {
+ if (array) {
+ for (var index = 0; index < array.length; index++) {
+ var item = array[index];
+ map[item.id] = item;
+ }
+ }
+ },
+
+ updateObject: function updateObject(object, newObject) {
+ for (var key in newObject) {
+ if (newObject.hasOwnProperty(key)) {
+ object[key] = newObject[key];
+ }
+ }
+ },
+
+ cleanObject: function cleanObject(object) {
+ for (var key in object) {
+ if (object.hasOwnProperty(key)) {
+ delete object[key];
+ }
+ }
+ },
+
+ pushAll: function pushAll(array, arrayToPush) {
+ Array.prototype.push.apply(array, arrayToPush);
+ },
+
+ indexOf: function indexOf(array, property, value) {
+ for (var i = 0; i < array.length; i += 1) {
+ if (array[i][property] === value) {
+ return i;
+ }
+ }
+ return -1;
+ },
+
+ createInternal: function createInternal(data, array, map, action) {
+ var added = this.mapToArray(data, action)
+ this.addToMap(added, map);
+ this.pushAll(array, added);
+ return added;
+ },
+
+ updateInternal: function updateInternal(data, map, action) {
+ var updated = this.mapToArray(data, action)
+ var result = []
+ for (var index = 0; index < updated.length; index++) {
+ var item = updated[index];
+ this.updateObject(map[item.id], item)
+ result.push(map[item.id])
+ }
+ return result;
+ },
+
+ removeInternal: function removeInternal(id, array, map) {
+ var old = map[id];
+ delete map[old.id];
+ array.splice(array.indexOf(old), 1);
+ return old;
+ },
+
+ arrayToTitleMap: function arrayToTitleMap(array) {
+ return array.map(function (item) {
+ return { value: item.id, name: item.name }
+ }).sort(function (itemA, itemB) {
+ return itemA.name.localeCompare(itemB.name);
+ })
+ },
+
+ displayErrorFunction: function displayErrorFunction(message) {
+ return function() {
+ toast.add('error', gettext(message));
+ }
+ },
+
+ displaySuccess: function displaySuccess(message) {
+ toast.add('success', gettext(message));
+ },
+
+ displayError: function displayError(message) {
+ toast.add('error', gettext(message));
+ },
+
+ }
+
+ }
+})(); \ No newline at end of file
diff --git a/moon_dashboard/moon/static/moon/js/util.service.spec.js b/moon_dashboard/moon/static/moon/js/util.service.spec.js
new file mode 100755
index 00000000..d8e3ed31
--- /dev/null
+++ b/moon_dashboard/moon/static/moon/js/util.service.spec.js
@@ -0,0 +1,86 @@
+(function () {
+ 'use strict';
+
+ describe('moon.util.service', function () {
+ var service;
+
+ beforeEach(module('horizon.app.core'));
+ beforeEach(module('horizon.framework'));
+ beforeEach(module('moon'));
+
+ beforeEach(inject(function ($injector) {
+ service = $injector.get('moon.util.service');
+ }));
+
+ it('should push all', function () {
+ var a1 = [0, 1, 2];
+ var a2 = [3, 4];
+ service.pushAll(a1, a2)
+
+ expect(a1.length).toBe(5);
+ expect(a1).toEqual([0, 1, 2, 3, 4]);
+ });
+
+ it('should index of', function () {
+ var a = [{ name: 'n0' }, { name: 'n1' }, { name: 'n2' }];
+ var result = service.indexOf(a, 'name', 'n1');
+
+ expect(result).toBe(1);
+ });
+
+ it('should map to array', function () {
+ var map = { "a": { name: "a" }, "b": { name: "b" } };
+ var result = service.mapToArray(map);
+
+ expect(result.length).toBe(2);
+ });
+
+ it('should map ID to item', function () {
+ var map = { "a": { name: "a" }, "b": { name: "b" } };
+ var array = ["a", "b"];
+ service.mapIdToItem(array, map);
+
+ expect(array.length).toBe(2);
+ expect(array[0].name).toBe("a");
+ expect(array[1].name).toBe("b");
+ });
+
+ it('should map item to ID', function () {
+ var array = [{ id: "a" }, { id: "b" }];
+ service.mapItemToId(array);
+
+ expect(array.length).toBe(2);
+ expect(array[0]).toBe("a");
+ expect(array[1]).toBe("b");
+ });
+
+ it('should add to map', function () {
+ var map = { "a": { name: "a" }, "b": { name: "b" } };
+ var array = [{ id: "c" }];
+ service.addToMap(array, map);
+
+ expect(map.c).toEqual({ id: "c" });
+ });
+
+ it('should update object', function () {
+ var object = { a: 1, b: "test" };
+ var update = { a: 2, c: "test2" };
+ service.updateObject(object, update);
+
+ expect(object.a).toBe(2);
+ expect(object.b).toBe("test");
+ expect(object.c).toBe("test2");
+ });
+
+ it('should clean object', function () {
+ var object = { a: 1, b: "test" };
+ service.cleanObject(object);
+
+ expect(object.a).not.toBeDefined();
+ expect(object.b).not.toBeDefined();
+ expect(object).toEqual({});
+ });
+ });
+
+
+})(); \ No newline at end of file
diff --git a/moon_dashboard/moon/static/moon/model/model.controller.js b/moon_dashboard/moon/static/moon/model/model.controller.js
new file mode 100644
index 00000000..d6a7503b
--- /dev/null
+++ b/moon_dashboard/moon/static/moon/model/model.controller.js
@@ -0,0 +1,244 @@
+(function () {
+ 'use strict';
+
+ angular
+ .module('moon')
+ .directive('onReadFile', directive)
+ .controller('moon.model.controller', controller);
+
+ controller.$inject = ['moon.util.service', 'moon.model.service', 'moon.import.service', 'horizon.framework.widgets.form.ModalFormService'];
+
+ directive.$inject = ['$parse'];
+
+ function directive($parse) {
+ return {
+ restrict: 'A',
+ scope: false,
+ link: function (scope, element, attrs) {
+ element.bind('change', function (e) {
+
+ var onFileReadFn = $parse(attrs.onReadFile);
+ var reader = new FileReader();
+
+ reader.onload = function () {
+ var fileContents = reader.result;
+ scope.$apply(function () {
+ onFileReadFn(scope, {
+ 'contents': fileContents
+ });
+ });
+ };
+ reader.readAsText(element[0].files[0]);
+ });
+ }
+ };
+ }
+
+ var categoryMap = {
+ 'subject': {
+ addTitle: 'Add Subject Category',
+ removeTitleFromMetaRule: 'Are you sure to remove from meta rule this Subject Category?',
+ removeTitle: 'Are you sure to remove this Subject Category?',
+ listName: 'subject_categories',
+ serviceListName: 'subjectCategories'
+ },
+ 'object': {
+ addTitle: 'Add Object Category',
+ removeTitleFromMetaRule: 'Are you sure to remove from meta rule this Object Category?',
+ removeTitle: 'Are you sure to remove this Object Category?',
+ listName: 'object_categories',
+ serviceListName: 'objectCategories'
+ },
+ 'action': {
+ addTitle: 'Add Action Category',
+ removeTitleFromMetaRule: 'Are you sure to remove from meta rule this Action Category?',
+ removeTitle: 'Are you sure to remove this Action Category?',
+ listName: 'action_categories',
+ serviceListName: 'actionCategories'
+ },
+ }
+
+ function controller(util, modelService, importService, ModalFormService) {
+ var self = this;
+ self.model = modelService;
+ self.showOrphan = false;
+ modelService.initialize();
+
+ self.importData = function importData(text) {
+ importService.importData(JSON.parse(text)).then(function () {
+ modelService.initialize();
+ })
+ }
+
+ self.createModel = function createModel() {
+ var schema = {
+ type: "object",
+ properties: {
+ name: { type: "string", minLength: 2, title: gettext("Name") },
+ description: { type: "string", minLength: 2, title: gettext("Description") }
+ }
+ };
+ var model = { name: '', description: '' };
+ var config = {
+ title: gettext('Create Model'),
+ schema: schema,
+ form: ['name', { key: 'description', type: 'textarea' }],
+ model: model
+ };
+ ModalFormService.open(config).then(submit);
+
+ function submit(form) {
+ modelService.createModel(form.model);
+ }
+ }
+
+ self.updateModel = function updateModel(model) {
+ var schema = {
+ type: "object",
+ properties: {
+ name: { type: "string", minLength: 2, title: gettext("Name") },
+ description: { type: "string", minLength: 2, title: gettext("Description") }
+ }
+ };
+ var config = {
+ title: gettext('Update Model'),
+ schema: schema,
+ form: ['name', { key: 'description', type: 'textarea' }],
+ model: angular.copy(model)
+ };
+ ModalFormService.open(config).then(submit);
+
+ function submit(form) {
+ modelService.updateModel(form.model);
+ }
+ }
+
+ self.removeModel = function removeModel(model) {
+ if (confirm(gettext('Are you sure to delete this Model?')))
+ modelService.removeModel(model);
+ }
+
+ self.addMetaRule = function addMetaRule(model) {
+ var schema = {
+ type: "object",
+ properties: {
+ name: { type: "string", minLength: 2, title: gettext("Name") },
+ description: { type: "string", minLength: 2, title: gettext("Description") },
+ id: { type: "string", title: gettext("Select a Meta Rule:") }
+ }
+ };
+ var metaRule = { name: '', description: '' };
+ var titleMap = util.arrayToTitleMap(modelService.metaRules)
+ var config = {
+ title: gettext('Add Meta Rule'),
+ schema: schema,
+ form: [{ key: 'id', type: 'select', titleMap: titleMap }, { type: 'help', helpvalue: gettext("Or create a new one:") }, 'name', { key: 'description', type: 'textarea' }],
+ model: metaRule
+ };
+ ModalFormService.open(config).then(submit);
+
+ function submit(form) {
+ function addMetaRuleToModel(metaRule) {
+ var modelCopy = angular.copy(model);
+ modelCopy.meta_rules.push(metaRule);
+ modelService.updateModel(modelCopy);
+ }
+
+ if (form.model.name) {
+ modelService.createMetaRule(form.model).then(addMetaRuleToModel)
+ } else if (form.model.id) {
+ addMetaRuleToModel(modelService.getMetaRule(form.model.id));
+ }
+ }
+ }
+
+ self.updateMetaRule = function updateMetaRule(metaRule) {
+ var schema = {
+ type: "object",
+ properties: {
+ name: { type: "string", minLength: 2, title: gettext("Name") },
+ description: { type: "string", minLength: 2, title: gettext("Description") }
+ }
+ };
+ var metaRuleCopy = angular.copy(metaRule);
+ var config = {
+ title: gettext('Update Meta Rule'),
+ schema: schema,
+ form: ['name', { key: 'description', type: 'textarea' }],
+ model: metaRuleCopy
+ };
+ ModalFormService.open(config).then(submit);
+
+ function submit(form) {
+ modelService.updateMetaRule(form.model);
+ }
+ }
+
+ self.removeMetaRuleFromModel = function removeMetaRuleFromModel(model, metaRule) {
+ if (confirm(gettext('Are you sure to remove this Meta Rule from model?'))) {
+ var modelCopy = angular.copy(model);
+ modelCopy.meta_rules.splice(model.meta_rules.indexOf(metaRule), 1);
+ modelService.updateModel(modelCopy);
+ }
+ }
+
+ self.removeMetaRule = function removeMetaRule(metaRule) {
+ if (confirm(gettext('Are you sure to remove this Meta Rule?'))) {
+ modelService.removeMetaRule(metaRule);
+ }
+ }
+
+ self.addCategory = function addCategory(type, metaRule) {
+ var typeValue = categoryMap[type];
+ var schema = {
+ type: "object",
+ properties: {
+ name: { type: "string", minLength: 2, title: gettext("Name") },
+ description: { type: "string", minLength: 2, title: gettext("Description") },
+ id: { type: "string", title: gettext("Select a Category:") }
+ }
+ };
+ var category = { name: '', description: '' };
+ var titleMap = util.arrayToTitleMap(modelService[typeValue.serviceListName])
+ var config = {
+ title: gettext(typeValue.addTitle),
+ schema: schema,
+ form: [{ key: 'id', type: 'select', titleMap: titleMap }, { type: 'help', helpvalue: gettext("Or create a new one:") }, 'name', { key: 'description', type: 'textarea' }],
+ model: category
+ };
+ ModalFormService.open(config).then(submit);
+
+ function submit(form) {
+ function addCategoryToMetaRule(category) {
+ var metaRuleCopy = angular.copy(metaRule);
+ metaRuleCopy[typeValue.listName].push(category);
+ modelService.updateMetaRule(metaRuleCopy)
+ }
+
+ if (form.model.name) {
+ modelService.createCategory(type, form.model).then(addCategoryToMetaRule)
+ } else if (form.model.id) {
+ addCategoryToMetaRule(modelService.getCategory(type, form.model.id));
+ }
+ }
+ }
+
+ self.removeCategoryFromMetaRule = function removeCategoryFromMetaRule(type, metaRule, category) {
+ var typeValue = categoryMap[type];
+ if (confirm(gettext(typeValue.removeTitleFromMetaRule))) {
+ var metaRuleCopy = angular.copy(metaRule);
+ metaRuleCopy[typeValue.listName].splice(metaRule[typeValue.listName].indexOf(category), 1);
+ modelService.updateMetaRule(metaRuleCopy);
+ }
+ }
+
+ self.removeCategory = function removeCategory(type, category) {
+ var typeValue = categoryMap[type];
+ if (confirm(gettext(typeValue.removeTitle))) {
+ modelService.removeCategory(type, category);
+ }
+ }
+
+
+ }
+})(); \ No newline at end of file
diff --git a/moon_dashboard/moon/static/moon/model/model.html b/moon_dashboard/moon/static/moon/model/model.html
new file mode 100644
index 00000000..98d64c75
--- /dev/null
+++ b/moon_dashboard/moon/static/moon/model/model.html
@@ -0,0 +1,143 @@
+<div ng-controller="moon.model.controller as ctrl">
+ <div ng-if="ctrl.model.orphanMetaRules.length
+ || ctrl.model.orphanSubjectCategories.length
+ || ctrl.model.orphanActionCategories.length
+ || ctrl.model.orphanObjectCategories.length" class="alert alert-dismissable alert-warning">
+ <button type="button" class="close" data-dismiss="alert" ng-click="ctrl.showOrphan=false">×</button>
+ <h4 translate>Warning!</h4>
+ <p translate>
+ Some metarules or categories are orphan, please check them and delete them if necessary.
+ <a href="" ng-click="ctrl.showOrphan=true" ng-show="!ctrl.showOrphan" translate>Show orphans</a>
+ <a href="" ng-click="ctrl.showOrphan=false" ng-show="ctrl.showOrphan" translate>Hide orphans</a>
+ </p>
+ </div>
+
+ <div class="row" ng-show="ctrl.showOrphan">
+ <div class="list-group col-lg-3" ng-if="ctrl.model.orphanMetaRules.length">
+ <h3 class="list-group-item active" translate>Orphan Meta rules</h3>
+ <div ng-repeat="metaRule in ctrl.model.orphanMetaRules | orderBy:'name'" class="list-group-item">
+ <h4 class="list-group-item-heading inline">{$ metaRule.name $}</h4>
+ <button type="button" class="fa fa-trash pull-right" ng-click="ctrl.removeMetaRule(metaRule)" title="{$ 'Remove Meta rule' | translate $}"></button>
+ <p class="list-group-item-text">{$ metaRule.description $}</p>
+ </div>
+ </div>
+
+ <div class="list-group col-lg-3" ng-if="ctrl.model.orphanSubjectCategories.length">
+ <h3 class="list-group-item active" translate>Orphan Subject categories</h3>
+ <div ng-repeat="subject in ctrl.model.orphanSubjectCategories | orderBy:'name'" class="list-group-item">
+ <h4 class="list-group-item-heading inline">{$ subject.name $}</h4>
+ <button type="button" class="fa fa-trash pull-right" ng-click="ctrl.removeCategory('subject', subject)" title="{$ 'Remove Subject category' | translate $}"></button>
+ <p class="list-group-item-text">{$ subject.description $}</p>
+ </div>
+ </div>
+
+ <div class="list-group col-lg-3" ng-if="ctrl.model.orphanObjectCategories.length">
+ <h3 class="list-group-item active" translate>Orphan Object categories</h3>
+ <div ng-repeat="object in ctrl.model.orphanObjectCategories | orderBy:'name'" class="list-group-item">
+ <h4 class="list-group-item-heading inline">{$ object.name $}</h4>
+ <button type="button" class="fa fa-trash pull-right" ng-click="ctrl.removeCategory('object', object)" title="{$ 'Remove Object category' | translate $}"></button>
+ <p class="list-group-item-text">{$ object.description $}</p>
+ </div>
+ </div>
+
+ <div class="list-group col-lg-3" ng-if="ctrl.model.orphanActionCategories.length">
+ <h3 class="list-group-item active" translate>Orphan Action categories</h3>
+ <div ng-repeat="action in ctrl.model.orphanActionCategories | orderBy:'name'" class="list-group-item">
+ <h4 class="list-group-item-heading inline">{$ action.name $}</h4>
+ <button type="button" class="fa fa-trash pull-right" ng-click="ctrl.removeCategory('action', action)" title="{$ 'Remove Action category' | translate $}"></button>
+ <p class="list-group-item-text">{$ action.description $}</p>
+ </div>
+ </div>
+ </div>
+
+ <div class="clearfix list-group">
+ <div class="pull-right">
+ <input type="search" class="form-control filter" placeholder="Filter" ng-model="filterText">
+ <button type="button" class="btn btn-default" ng-click="ctrl.createModel()">
+ <span class="fa fa-plus"></span>
+ <translate>Create Model</translate>
+ </button>
+ <label for="file" class="label-file btn btn-primary">
+ <span class="fa fa-upload"></span>
+ <translate>Import</translate>
+ </label>
+ <input id="file" class="input-file" type="file" on-read-file="ctrl.importData(contents)" accept="application/json,.json"/>
+ <!--button type="button" class="btn btn-primary" ng-click="ctrl.createModel()">
+ <span class="fa fa-upload"></span>
+ <translate>Import</translate>
+ </button-->
+ </div>
+ </div>
+
+
+ <div class="list-group">
+ <div ng-repeat="model in ctrl.model.models | orderBy:'name' | filter:filterText " class="list-group-item">
+ <h3 class="list-group-item-heading inline">{$ model.name $}</h3>
+ <div class="pull-right">
+ <button type="button" class="fa fa-trash" ng-click="ctrl.removeModel(model)" title="{$ 'Remove Model' | translate $}"></button>
+ <button type="button" class="fa fa-edit" ng-click="ctrl.updateModel(model)" title="{$ 'Edit Model' | translate $}"></button>
+ </div>
+ <p class="list-group-item-text">{$ model.description $}</p>
+ <details class="list-group-item-text">
+ <summary>
+ <h4 class="inline">{$ model.meta_rules.length $}
+ <translate>meta rule(s)</translate>
+ </h4>
+ <button type="button" class="fa fa-plus " ng-click="ctrl.addMetaRule(model)" title="{$ 'Add Meta Rule' | translate $}"></button>
+ </summary>
+ <div class="list-group">
+ <div ng-repeat="metaRule in model.meta_rules | orderBy:'name'" class="list-group-item">
+ <h3 class="list-group-item-heading inline">{$ metaRule.name $}</h3>
+ <div class="pull-right">
+ <button type="button" class="fa fa-trash" ng-click="ctrl.removeMetaRuleFromModel(model, metaRule)" title="{$ 'Remove Meta Rule' | translate $}"></button>
+ <button type="button" class="fa fa-edit" ng-click="ctrl.updateMetaRule(metaRule)" title="{$ 'Edit Meta Rule' | translate $}"></button>
+ </div>
+ <p class="list-group-item-text">{$ metaRule.description $}</p>
+ <p class="list-group-item-text">
+ <table class="table categories">
+ <thead>
+ <tr>
+ <th>
+ <span translate>Subjects</span>
+ <button type="button" class="fa fa-plus pull-right" ng-click="ctrl.addCategory('subject', metaRule)" title="{$ 'Add Subject' | translate $}"></button>
+ </th>
+ <th>
+ <span translate>Objects</span>
+ <button type="button" class="fa fa-plus pull-right" ng-click="ctrl.addCategory('object', metaRule)" title="{$ 'Add Object' | translate $}"></button>
+ </th>
+ <th>
+ <span translate>Actions</span>
+ <button type="button" class="fa fa-plus pull-right" ng-click="ctrl.addCategory('action', metaRule)" title="{$ 'Add Action' | translate $}"></button>
+ </th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr>
+ <td>
+ <p ng-repeat="category in metaRule.subject_categories">
+ <span>{$ category.name $}</span>
+ <button type="button" class="fa fa-trash pull-right" ng-click="ctrl.removeCategoryFromMetaRule('subject', metaRule, category)" title="{$ 'Remove Subject' | translate $}"></button>
+ </p>
+ </td>
+ <td>
+ <p ng-repeat="category in metaRule.object_categories">
+ <span>{$ category.name $}</span>
+ <button type="button" class="fa fa-trash pull-right" ng-click="ctrl.removeCategoryFromMetaRule('object', metaRule, category)" title="{$ 'Remove Object' | translate $}"></button>
+ </p>
+ </td>
+ <td>
+ <p ng-repeat="category in metaRule.action_categories">
+ <span>{$ category.name $}</span>
+ <button type="button" class="fa fa-trash pull-right" ng-click="ctrl.removeCategoryFromMetaRule('action', metaRule, category)" title="{$ 'Remove Action' | translate $}"></button>
+ </p>
+ </td>
+ </tr>
+ </tbody>
+ </table>
+ </p>
+ </div>
+ </div>
+ </details>
+ </div>
+ </div>
+</div> \ No newline at end of file
diff --git a/moon_dashboard/moon/static/moon/model/model.service.js b/moon_dashboard/moon/static/moon/model/model.service.js
new file mode 100755
index 00000000..76c3da01
--- /dev/null
+++ b/moon_dashboard/moon/static/moon/model/model.service.js
@@ -0,0 +1,286 @@
+(function () {
+
+ 'use strict';
+
+ angular
+ .module('moon')
+ .factory('moon.model.service', modelService);
+
+ modelService.$inject = ['moon.util.service', '$resource', 'moon.URI', '$q'];
+
+ function modelService(util, $resource, URI, $q) {
+ var host = URI.API;
+ var modelResource = $resource(host + '/models/' + ':id', {}, {
+ get: { method: 'GET' },
+ query: { method: 'GET' },
+ create: { method: 'POST' },
+ remove: { method: 'DELETE' },
+ update: { method: 'PATCH' }
+ });
+
+ var metaRuleResource = $resource(host + '/meta_rules/' + ':id', {}, {
+ query: { method: 'GET' },
+ get: { method: 'GET' },
+ update: { method: 'PATCH' },
+ create: { method: 'POST' },
+ remove: { method: 'DELETE' }
+ });
+
+ var subjectCategoryResource = $resource(host + '/subject_categories/' + ':id', {}, {
+ query: { method: 'GET' },
+ get: { method: 'GET' },
+ create: { method: 'POST' },
+ remove: { method: 'DELETE' }
+ });
+
+ var objectCategoryResource = $resource(host + '/object_categories/' + ':id', {}, {
+ query: { method: 'GET' },
+ get: { method: 'GET' },
+ create: { method: 'POST' },
+ remove: { method: 'DELETE' }
+ });
+
+ var actionCategoryResource = $resource(host + '/action_categories/' + ':id', {}, {
+ query: { method: 'GET' },
+ get: { method: 'GET' },
+ create: { method: 'POST' },
+ remove: { method: 'DELETE' }
+ });
+
+ var modelsMap = {};
+ var metaRulesMap = {};
+ var subjectCategoriesMap = {};
+ var objectCategoriesMap = {};
+ var actionCategoriesMap = {};
+ var models = [];
+ var metaRules = [];
+ var orphanMetaRules = [];
+ var subjectCategories = [];
+ var objectCategories = [];
+ var actionCategories = [];
+ var orphanSubjectCategories = [];
+ var orphanObjectCategories = [];
+ var orphanActionCategories = [];
+
+ var categoryMap = {
+ 'subject': {
+ resource: subjectCategoryResource,
+ map: subjectCategoriesMap,
+ list: subjectCategories,
+ listName: 'subject_categories'
+ },
+ 'object': {
+ resource: objectCategoryResource,
+ map: objectCategoriesMap,
+ list: objectCategories,
+ listName: 'object_categories'
+ },
+ 'action': {
+ resource: actionCategoryResource,
+ map: actionCategoriesMap,
+ list: actionCategories,
+ listName: 'action_categories'
+ }
+ }
+
+ function loadModels() {
+ var queries = {
+ subjectCategories: subjectCategoryResource.query().$promise,
+ objectCategories: objectCategoryResource.query().$promise,
+ actionCategories: actionCategoryResource.query().$promise,
+ metaRules: metaRuleResource.query().$promise,
+ models: modelResource.query().$promise,
+ }
+
+ var result = $q.all(queries).then(function (result) {
+ createModels(result.models, result.metaRules, result.subjectCategories, result.objectCategories, result.actionCategories)
+ console.log('moon', 'models initialized')
+ })
+
+ return result;
+ }
+
+ function createModels(modelsData, metarulesData, subjectCategoriesData, objectCategoriesData, actionCategoriesData) {
+ util.cleanObject(modelsMap);
+ util.cleanObject(metaRulesMap);
+ util.cleanObject(subjectCategoriesMap);
+ util.cleanObject(objectCategoriesMap);
+ util.cleanObject(actionCategoriesMap);
+ models.splice(0, models.length);
+ metaRules.splice(0, metaRules.length);
+ subjectCategories.splice(0, subjectCategories.length);
+ objectCategories.splice(0, objectCategories.length);
+ actionCategories.splice(0, actionCategories.length);
+ if (subjectCategoriesData.subject_categories) createCategoryInternal('subject', subjectCategoriesData.subject_categories);
+ if (objectCategoriesData.object_categories) createCategoryInternal('object', objectCategoriesData.object_categories);
+ if (actionCategoriesData.action_categories) createCategoryInternal('action', actionCategoriesData.action_categories);
+ if (metarulesData.meta_rules) createMetaRuleInternal(metarulesData.meta_rules);
+ if (modelsData.models) createModelInternal(modelsData.models);
+ updateOrphan();
+ }
+
+ function mapModel(model) {
+ util.mapIdToItem(model.meta_rules, metaRulesMap);
+ }
+
+ function createModelInternal(data) {
+ return util.createInternal(data, models, modelsMap, mapModel);
+ }
+
+ function updateModelInternal(data) {
+ return util.updateInternal(data, modelsMap, mapModel);
+ }
+
+ function removeModelInternal(id) {
+ return util.removeInternal(id, models, modelsMap);
+ }
+
+ function mapMetaRule(metaRule) {
+ util.mapIdToItem(metaRule.subject_categories, subjectCategoriesMap);
+ util.mapIdToItem(metaRule.object_categories, objectCategoriesMap);
+ util.mapIdToItem(metaRule.action_categories, actionCategoriesMap);
+ }
+
+ function createMetaRuleInternal(data) {
+ return util.createInternal(data, metaRules, metaRulesMap, mapMetaRule);
+ }
+
+ function updateMetaRuleInternal(data) {
+ return util.updateInternal(data, metaRulesMap, mapMetaRule);
+ }
+
+ function removeMetaRuleInternal(id) {
+ return util.removeInternal(id, metaRules, metaRulesMap);
+ }
+
+ function createCategoryInternal(type, data) {
+ var categoryValue = categoryMap[type];
+ return util.createInternal(data, categoryValue.list, categoryValue.map)
+ }
+
+ function removeCategoryInternal(type, id) {
+ var categoryValue = categoryMap[type];
+ return util.removeInternal(id, categoryValue.list, categoryValue.map);
+ }
+
+ function updateOrphan() {
+ updateOrphanInternal(metaRules, orphanMetaRules, models, "meta_rules");
+ updateOrphanInternal(subjectCategories, orphanSubjectCategories, metaRules, "subject_categories");
+ updateOrphanInternal(objectCategories, orphanObjectCategories, metaRules, "object_categories");
+ updateOrphanInternal(actionCategories, orphanActionCategories, metaRules, "action_categories");
+ }
+
+ function updateOrphanInternal(list, orphanList, parentList, childListName) {
+ orphanList.splice(0, orphanList.length);
+ util.pushAll(orphanList, list);
+ for (var i = 0; i < parentList.length; i++) {
+ var parent = parentList[i];
+ var children = parent[childListName];
+ if (children) {
+ for (var j = 0; j < children.length; j++) {
+ var child = children[j];
+ var notOrphanIndex = util.indexOf(orphanList, "id", child.id);
+ if (notOrphanIndex >= 0) {
+ orphanList.splice(notOrphanIndex, 1);
+ }
+ }
+ }
+ }
+ }
+
+
+ return {
+ initialize: loadModels,
+ createModels: createModels,
+ models: models,
+ metaRules: metaRules,
+ orphanMetaRules: orphanMetaRules,
+ orphanSubjectCategories: orphanSubjectCategories,
+ orphanObjectCategories: orphanObjectCategories,
+ orphanActionCategories: orphanActionCategories,
+ subjectCategories: subjectCategories,
+ objectCategories: objectCategories,
+ actionCategories: actionCategories,
+ getModel: function getModel(id) {
+ return modelsMap[id];
+ },
+ createModel: function createModel(model) {
+ modelResource.create(null, model, success, util.displayErrorFunction('Unable to create model'));
+
+ function success(data) {
+ createModelInternal(data.models);
+ util.displaySuccess('Model created');
+ }
+ },
+ removeModel: function removeModel(model) {
+ modelResource.remove({ id: model.id }, null, success, util.displayErrorFunction('Unable to remove model'));
+
+ function success(data) {
+ removeModelInternal(model.id);
+ updateOrphan();
+ util.displaySuccess('Model removed');
+ }
+ },
+ updateModel: function updateModel(model) {
+ util.mapItemToId(model.meta_rules)
+ modelResource.update({ id: model.id }, model, success, util.displayErrorFunction('Unable to update model'));
+
+ function success(data) {
+ updateModelInternal(data.models)
+ updateOrphan();
+ util.displaySuccess('Model updated');
+ }
+ },
+ getMetaRule: function getMetaRule(id) {
+ return metaRulesMap[id];
+ },
+ createMetaRule: function createMetaRule(metaRule) {
+ return metaRuleResource.create(null, metaRule).$promise.then(function (data) {
+ util.displaySuccess('Meta Rule created');
+ return createMetaRuleInternal(data.meta_rules)[0];
+ }, util.displayErrorFunction('Unable to create meta rule'))
+ },
+ updateMetaRule: function updateMetaRule(metaRule) {
+ util.mapItemToId(metaRule.subject_categories);
+ util.mapItemToId(metaRule.object_categories);
+ util.mapItemToId(metaRule.action_categories);
+ metaRuleResource.update({ id: metaRule.id }, metaRule, success, util.displayErrorFunction('Unable to update meta rule'));
+
+ function success(data) {
+ updateMetaRuleInternal(data.meta_rules);
+ updateOrphan();
+ util.displaySuccess('Meta Rule updated');
+ }
+ },
+ removeMetaRule: function removeMetaRule(metaRule) {
+ metaRuleResource.remove({ id: metaRule.id }, null, success, util.displayErrorFunction('Unable to remove meta rule'));
+
+ function success(data) {
+ removeMetaRuleInternal(metaRule.id);
+ updateOrphan();
+ util.displaySuccess('Meta Rule removed');
+ }
+ },
+ getCategory: function getCategory(type, id) {
+ return categoryMap[type].map[id];
+ },
+ createCategory: function createCategory(type, category) {
+ var categoryValue = categoryMap[type];
+ return categoryValue.resource.create({}, category).$promise.then(function (data) {
+ util.displaySuccess('Category created');
+ return createCategoryInternal(type, data[categoryValue.listName])[0];
+ }, util.displayErrorFunction('Unable to create category'))
+ },
+ removeCategory: function removeCategory(type, category) {
+ var categoryValue = categoryMap[type];
+ categoryValue.resource.remove({ id: category.id }, null, success, util.displayErrorFunction('Unable to remove category'));
+
+ function success(data) {
+ removeCategoryInternal(type, category.id);
+ updateOrphan();
+ util.displaySuccess('Category removed');
+ }
+ },
+ }
+ }
+})(); \ No newline at end of file
diff --git a/moon_dashboard/moon/static/moon/model/model.service.spec.js b/moon_dashboard/moon/static/moon/model/model.service.spec.js
new file mode 100755
index 00000000..04d47793
--- /dev/null
+++ b/moon_dashboard/moon/static/moon/model/model.service.spec.js
@@ -0,0 +1,288 @@
+(function () {
+ 'use strict';
+
+ describe('moon.model.service', function () {
+ var service, $httpBackend, URI;
+ var modelsData, metaRulesData, subjectCategoriesData, objectCategoriesData, actionCategoriesData;
+
+ function initData() {
+ modelsData = {
+ models:
+ { 'modelId1': { name: 'model1', description: 'mDescription1', meta_rules: ['metaRuleId1'] } }
+ };
+
+ subjectCategoriesData = {
+ subject_categories:
+ {
+ 'subjectCategoryId1': { name: 'subjectCategory1', description: 'scDescription1' },
+ 'subjectCategoryId2': { name: 'subjectCategory2', description: 'scDescription2' }
+ },
+ };
+ objectCategoriesData = {
+ object_categories:
+ {
+ 'objectCategoryId1': { name: 'objectCategory1', description: 'ocDescription1' },
+ 'objectCategoryId2': { name: 'objectCategory2', description: 'ocDescription2' }
+ }
+ };
+ actionCategoriesData = {
+ action_categories:
+ {
+ 'actionCategoryId1': { name: 'actionCategory1', description: 'acDescription1' },
+ 'actionCategoryId2': { name: 'actionCategory2', description: 'acDescription2' }
+ }
+ };
+ metaRulesData = {
+ meta_rules:
+ {
+ 'metaRuleId1': { name: 'metaRule1', description: 'mrDescription1', subject_categories: ['subjectCategoryId1'], object_categories: ['objectCategoryId1'], action_categories: ['actionCategoryId1'] },
+ 'metaRuleId2': { name: 'metaRule2', description: 'mrDescription2', subject_categories: [], object_categories: [], action_categories: [] }
+ }
+ };
+ }
+
+ beforeEach(module('horizon.app.core'));
+ beforeEach(module('horizon.framework'));
+ beforeEach(module('moon'));
+
+ beforeEach(inject(function ($injector) {
+ service = $injector.get('moon.model.service');
+ $httpBackend = $injector.get('$httpBackend');
+ URI = $injector.get('moon.URI');
+ }));
+
+ afterEach(function () {
+ $httpBackend.verifyNoOutstandingExpectation();
+ $httpBackend.verifyNoOutstandingRequest();
+ });
+
+ it('should initialize', function () {
+ initData();
+ $httpBackend.expectGET(URI.API + '/subject_categories').respond(200, subjectCategoriesData);
+ $httpBackend.expectGET(URI.API + '/object_categories').respond(200, objectCategoriesData);
+ $httpBackend.expectGET(URI.API + '/action_categories').respond(200, actionCategoriesData);
+ $httpBackend.expectGET(URI.API + '/meta_rules').respond(200, metaRulesData);
+ $httpBackend.expectGET(URI.API + '/models').respond(200, modelsData);
+
+ service.initialize();
+ $httpBackend.flush();
+
+ expect(service.models.length).toBe(1);
+ var model = service.models[0];
+ expect(model.id).toBe('modelId1');
+ expect(model.name).toBe('model1');
+ expect(model.description).toBe('mDescription1');
+
+ expect(service.metaRules.length).toBe(2);
+ expect(model.meta_rules.length).toBe(1);
+ var metaRule = model.meta_rules[0];
+ expect(metaRule.id).toBe('metaRuleId1');
+ expect(metaRule.name).toBe('metaRule1');
+ expect(metaRule.description).toBe('mrDescription1');
+
+ expect(service.subjectCategories.length).toBe(2);
+ expect(metaRule.subject_categories.length).toBe(1);
+ var subjectCategory = metaRule.subject_categories[0];
+ expect(subjectCategory.id).toBe('subjectCategoryId1');
+ expect(subjectCategory.name).toBe('subjectCategory1');
+ expect(subjectCategory.description).toBe('scDescription1');
+
+ expect(service.objectCategories.length).toBe(2);
+ expect(metaRule.object_categories.length).toBe(1);
+ var objectCategory = metaRule.object_categories[0];
+ expect(objectCategory.id).toBe('objectCategoryId1');
+ expect(objectCategory.name).toBe('objectCategory1');
+ expect(objectCategory.description).toBe('ocDescription1');
+
+ expect(service.actionCategories.length).toBe(2);
+ expect(metaRule.action_categories.length).toBe(1);
+ var actionCategory = metaRule.action_categories[0];
+ expect(actionCategory.id).toBe('actionCategoryId1');
+ expect(actionCategory.name).toBe('actionCategory1');
+ expect(actionCategory.description).toBe('acDescription1');
+
+ expect(service.orphanMetaRules.length).toBe(1);
+ metaRule = service.orphanMetaRules[0];
+ expect(metaRule.id).toBe('metaRuleId2');
+ expect(metaRule.name).toBe('metaRule2');
+ expect(metaRule.description).toBe('mrDescription2');
+
+ expect(service.orphanSubjectCategories.length).toBe(1);
+ subjectCategory = service.orphanSubjectCategories[0];
+ expect(subjectCategory.id).toBe('subjectCategoryId2');
+ expect(subjectCategory.name).toBe('subjectCategory2');
+ expect(subjectCategory.description).toBe('scDescription2');
+
+ expect(service.orphanObjectCategories.length).toBe(1);
+ objectCategory = service.orphanObjectCategories[0];
+ expect(objectCategory.id).toBe('objectCategoryId2');
+ expect(objectCategory.name).toBe('objectCategory2');
+ expect(objectCategory.description).toBe('ocDescription2');
+
+ expect(service.orphanActionCategories.length).toBe(1);
+ actionCategory = service.orphanActionCategories[0];
+ expect(actionCategory.id).toBe('actionCategoryId2');
+ expect(actionCategory.name).toBe('actionCategory2');
+ expect(actionCategory.description).toBe('acDescription2');
+
+ });
+
+
+
+ it('should create model', function () {
+ var modelCreatedData = {
+ models:
+ { 'modelId1': { name: 'model1', description: 'mDescription1', meta_rules: [] } }
+ };
+
+ $httpBackend.expectPOST(URI.API + '/models').respond(200, modelCreatedData);
+
+ service.createModel({ name: 'model1', description: 'mDescription1' });
+ $httpBackend.flush();
+
+ expect(service.models.length).toBe(1);
+ var model = service.models[0];
+ expect(model.id).toBe('modelId1');
+ expect(model.name).toBe('model1');
+ expect(model.description).toBe('mDescription1');
+ });
+
+ it('should remove model', function () {
+ initData();
+ service.createModels(modelsData, metaRulesData, subjectCategoriesData, objectCategoriesData, actionCategoriesData);
+
+ $httpBackend.expectDELETE(URI.API + '/models/modelId1').respond(200);
+
+ service.removeModel({ id: 'modelId1' });
+ $httpBackend.flush();
+
+ expect(service.models.length).toBe(0);
+
+ expect(service.orphanMetaRules.length).toBe(2);
+ });
+
+ it('should update model', function () {
+ initData();
+ var modelUpdatedData = {
+ models:
+ { 'modelId1': { name: 'model2', description: 'mDescription2', meta_rules: ['metaRuleId2'] } }
+ };
+ service.createModels(modelsData, metaRulesData, subjectCategoriesData, objectCategoriesData, actionCategoriesData);
+
+ $httpBackend.expectPATCH(URI.API + '/models/modelId1').respond(200, modelUpdatedData);
+
+ service.updateModel({ id: 'modelId1', name: 'model2', description: 'mDescription2', meta_rules: service.getMetaRule('metaRuleId2') });
+ $httpBackend.flush();
+
+ expect(service.models.length).toBe(1);
+ var model = service.models[0];
+ expect(model.id).toBe('modelId1');
+ expect(model.name).toBe('model2');
+ expect(model.description).toBe('mDescription2');
+
+ expect(model.meta_rules.length).toBe(1);
+ var metaRule = model.meta_rules[0];
+ expect(metaRule.id).toBe('metaRuleId2');
+
+ expect(service.orphanMetaRules.length).toBe(1);
+ metaRule = service.orphanMetaRules[0];
+ expect(metaRule.id).toBe('metaRuleId1');
+ });
+
+ it('should create meta rule', function () {
+ var metaRuleCreatedData = {
+ meta_rules:
+ { 'metaRuleId1': { name: 'metaRule1', description: 'mrDescription1' } }
+ };
+
+ $httpBackend.expectPOST(URI.API + '/meta_rules').respond(200, metaRuleCreatedData);
+
+ service.createMetaRule({ name: 'metaRule1', description: 'mrDescription1' });
+ $httpBackend.flush();
+
+ expect(service.metaRules.length).toBe(1);
+ var metaRule = service.metaRules[0];
+ expect(metaRule.id).toBe('metaRuleId1');
+ expect(metaRule.name).toBe('metaRule1');
+ expect(metaRule.description).toBe('mrDescription1');
+ });
+
+ it('should update meta rule', function () {
+ initData();
+ var metaRuleUpdatedData = {
+ meta_rules:
+ { 'metaRuleId1': { name: 'metaRule2', description: 'mrDescription2', subject_categories: ['subjectCategoryId2'], object_categories: ['objectCategoryId2'], action_categories: ['actionCategoryId2'] } }
+ };
+ service.createModels(modelsData, metaRulesData, subjectCategoriesData, objectCategoriesData, actionCategoriesData);
+
+ $httpBackend.expectPATCH(URI.API + '/meta_rules/metaRuleId1').respond(200, metaRuleUpdatedData);
+
+ service.updateMetaRule({ id: 'metaRuleId1', name: 'metaRule2', description: 'mrDescription2', subject_categories: [service.getCategory('subject', 'subjectCategoryId2')], object_categories: [service.getCategory('object', 'objectCategoryId2')], action_categories: [service.getCategory('action','actionCategoryId2')] });
+ $httpBackend.flush();
+
+ var metaRule = service.getMetaRule('metaRuleId1');
+ expect(metaRule.id).toBe('metaRuleId1');
+ expect(metaRule.name).toBe('metaRule2');
+ expect(metaRule.description).toBe('mrDescription2');
+
+ expect(service.orphanSubjectCategories.length).toBe(1);
+ var subjectCategory = service.orphanSubjectCategories[0];
+ expect(subjectCategory.id).toBe('subjectCategoryId1');
+
+ expect(service.orphanObjectCategories.length).toBe(1);
+ var objectCategory = service.orphanObjectCategories[0];
+ expect(objectCategory.id).toBe('objectCategoryId1');
+
+ expect(service.orphanActionCategories.length).toBe(1);
+ var actionCategory = service.orphanActionCategories[0];
+ expect(actionCategory.id).toBe('actionCategoryId1');
+ });
+
+ it('should remove meta rule', function () {
+ initData();
+ service.createModels(modelsData, metaRulesData, subjectCategoriesData, objectCategoriesData, actionCategoriesData);
+
+ $httpBackend.expectDELETE(URI.API + '/meta_rules/metaRuleId2').respond(200);
+
+ service.removeMetaRule(service.getMetaRule('metaRuleId2'));
+ $httpBackend.flush();
+
+ expect(service.metaRules.length).toBe(1);
+ expect(service.orphanMetaRules.length).toBe(0);
+ });
+
+ it('should create category', function () {
+ var categoryCreatedData = {
+ subject_categories:
+ { 'subjectCategoryId1': { name: 'subjectCategory1', description: 'scDescription1' } }
+ };
+
+ $httpBackend.expectPOST(URI.API + '/subject_categories').respond(200, categoryCreatedData);
+
+ service.createCategory('subject', { name: 'subjectCategory1', description: 'scDescription1' });
+ $httpBackend.flush();
+
+ expect(service.subjectCategories.length).toBe(1);
+ var subjectCategory = service.subjectCategories[0];
+ expect(subjectCategory.id).toBe('subjectCategoryId1');
+ expect(subjectCategory.name).toBe('subjectCategory1');
+ expect(subjectCategory.description).toBe('scDescription1');
+ });
+
+ it('should remove category', function () {
+ initData();
+ service.createModels(modelsData, metaRulesData, subjectCategoriesData, objectCategoriesData, actionCategoriesData);
+
+ $httpBackend.expectDELETE(URI.API + '/subject_categories/subjectCategoryId2').respond(200);
+
+ service.removeCategory('subject', service.getCategory('subject', 'subjectCategoryId2'));
+ $httpBackend.flush();
+
+ expect(service.subjectCategories.length).toBe(1);
+ expect(service.orphanSubjectCategories.length).toBe(0);
+ });
+
+ });
+
+
+})(); \ No newline at end of file
diff --git a/moon_dashboard/moon/static/moon/pdp/pdp.controller.js b/moon_dashboard/moon/static/moon/pdp/pdp.controller.js
new file mode 100644
index 00000000..c57f3b28
--- /dev/null
+++ b/moon_dashboard/moon/static/moon/pdp/pdp.controller.js
@@ -0,0 +1,121 @@
+(function () {
+ 'use strict';
+
+ angular
+ .module('moon')
+ .controller('moon.pdp.controller',
+ controller);
+
+ controller.$inject = ['moon.util.service', 'moon.pdp.service', 'horizon.framework.widgets.form.ModalFormService'];
+
+ function controller(util, pdpService, ModalFormService) {
+ var self = this;
+ self.model = pdpService;
+ pdpService.initialize();
+
+ self.createPdp = function createPdp() {
+ var schema = {
+ type: "object",
+ properties: {
+ name: { type: "string", minLength: 2, title: gettext("Name") },
+ description: { type: "string", minLength: 2, title: gettext("Description") }
+ }
+ };
+ var pdp = { name: '', description: '' };
+ var config = {
+ title: gettext('Create PDP'),
+ schema: schema,
+ form: ['name', { key: 'description', type: 'textarea' }],
+ model: pdp
+ };
+ ModalFormService.open(config).then(submit);
+
+ function submit(form) {
+ pdpService.createPdp(form.model);
+ }
+ }
+
+ self.updatePdp = function updatePdp(pdp) {
+ var schema = {
+ type: "object",
+ properties: {
+ name: { type: "string", minLength: 2, title: gettext("Name") },
+ description: { type: "string", minLength: 2, title: gettext("Description") }
+ }
+ };
+ var config = {
+ title: gettext('Update PDP'),
+ schema: schema,
+ form: ['name', { key: 'description', type: 'textarea' }],
+ model: angular.copy(pdp)
+ };
+ ModalFormService.open(config).then(submit);
+
+ function submit(form) {
+ pdpService.updatePdp(form.model);
+ }
+ }
+
+ self.removePdp = function removePdp(pdp) {
+ if (confirm(gettext('Are you sure to delete this PDP?')))
+ pdpService.removePdp(pdp);
+ }
+
+ self.addPolicy = function addPolicy(pdp) {
+ var schema = {
+ type: "object",
+ properties: {
+ id: { type: "string", title: gettext("Select a Policy:") }
+ }
+ };
+ var titleMap = util.arrayToTitleMap(pdpService.policies)
+ var config = {
+ title: gettext('Add Policy'),
+ schema: schema,
+ form: [{ key: 'id', type: 'select', titleMap: titleMap }],
+ model: {}
+ };
+ ModalFormService.open(config).then(submit);
+
+ function submit(form) {
+ var pdpCopy = angular.copy(pdp);
+ pdpCopy.security_pipeline.push(pdpService.getPolicy(form.model.id));
+ pdpService.updatePdp(pdpCopy);
+ }
+ }
+
+ self.removePolicyFromPdp = function removePolicyFromPdp(pdp, policy) {
+ if (confirm(gettext('Are you sure to remove this Policy from PDP?'))) {
+ var pdpCopy = angular.copy(pdp);
+ pdpCopy.security_pipeline.splice(pdp.security_pipeline.indexOf(policy), 1);
+ pdpService.updatePdp(pdpCopy);
+ }
+ }
+
+ self.changeProject = function changeProject(pdp) {
+ var schema = {
+ type: "object",
+ properties: {
+ id: { type: "string", title: gettext("Select a Project:") }
+ }
+ };
+ var model = {id : pdp.keystone_project_id};
+
+ var titleMap = util.arrayToTitleMap(pdpService.projects)
+ var config = {
+ title: gettext('Change Project'),
+ schema: schema,
+ form: [{ key: 'id', type: 'select', titleMap: titleMap }],
+ model: model
+ };
+ ModalFormService.open(config).then(submit);
+
+ function submit(form) {
+ var pdpCopy = angular.copy(pdp);
+ pdpCopy.project = pdpService.getProject(form.model.id);
+ pdpService.updatePdp(pdpCopy);
+ }
+ }
+
+ }
+})(); \ No newline at end of file
diff --git a/moon_dashboard/moon/static/moon/pdp/pdp.html b/moon_dashboard/moon/static/moon/pdp/pdp.html
new file mode 100644
index 00000000..2456a261
--- /dev/null
+++ b/moon_dashboard/moon/static/moon/pdp/pdp.html
@@ -0,0 +1,41 @@
+<div ng-controller="moon.pdp.controller as ctrl">
+ <div class="clearfix list-group">
+ <div class="pull-right">
+ <input type="search" class="form-control filter" placeholder="Filter" ng-model="filterText">
+ <button type="button" class="btn btn-default" ng-click="ctrl.createPdp()">
+ <span class="fa fa-plus"></span>
+ <translate>Create PDP</translate>
+ </button>
+ </div>
+ </div>
+ <div class="list-group">
+ <div ng-repeat="pdp in ctrl.model.pdps | orderBy:'name' | filter:filterText " class="list-group-item">
+ <h3 class="list-group-item-heading inline">{$ pdp.name $}</h3>
+ <div class="pull-right">
+ <button type="button" class="fa fa-trash" ng-click="ctrl.removePdp(pdp)" title="{$ 'Remove PDP' | translate $}"></button>
+ <button type="button" class="fa fa-edit" ng-click="ctrl.updatePdp(pdp)" title="{$ 'Edit PDP' | translate $}"></button>
+ </div>
+ <p class="list-group-item-text">{$ pdp.description $}</p>
+ <h4 class="list-group-item-text">
+ <translate>Project: {$ pdp.project ? pdp.project.name : 'none' $}</translate>
+ <button type="button" class="fa fa-edit" ng-click="ctrl.changeProject(pdp)" title="{$ 'Change project' | translate $}"></button>
+ </h4>
+
+ <details class="list-group-item-text">
+ <summary>
+ <h4 class="inline">{$ pdp.security_pipeline.length $}
+ <translate>policy(ies)</translate>
+ </h4>
+ <button type="button" class="fa fa-plus " ng-click="ctrl.addPolicy(pdp)" title="{$ 'Add Policy' | translate $}"></button>
+ </summary>
+ <div class="list-group">
+ <div ng-repeat="policy in pdp.security_pipeline | orderBy:'name'" class="list-group-item">
+ <h3 class="list-group-item-heading inline">{$ policy.name $}</h3>
+ <button type="button" class="fa fa-trash pull-right" ng-click="ctrl.removePolicyFromPdp(pdp, policy)" title="{$ 'Remove Policy' | translate $}"></button>
+ <p class="list-group-item-text">{$ policy.description $}</p>
+ </div>
+ </div>
+ </details>
+ </div>
+ </div>
+</div> \ No newline at end of file
diff --git a/moon_dashboard/moon/static/moon/pdp/pdp.service.js b/moon_dashboard/moon/static/moon/pdp/pdp.service.js
new file mode 100755
index 00000000..e18971be
--- /dev/null
+++ b/moon_dashboard/moon/static/moon/pdp/pdp.service.js
@@ -0,0 +1,123 @@
+(function () {
+
+ 'use strict';
+
+ angular
+ .module('moon')
+ .factory('moon.pdp.service', pdpService);
+
+ pdpService.$inject = ['moon.util.service', '$resource', 'moon.URI', '$q', 'horizon.app.core.openstack-service-api.keystone'];
+
+ function pdpService(util, $resource, URI, $q, keystone) {
+ var host = URI.API;
+
+ var pdpResource = $resource(host + '/pdp/' + ':id', {}, {
+ get: { method: 'GET' },
+ query: { method: 'GET' },
+ create: { method: 'POST' },
+ remove: { method: 'DELETE' },
+ update: { method: 'PATCH' }
+ });
+
+ var policyResource = $resource(host + '/policies/' + ':id', {}, {
+ query: { method: 'GET' },
+ });
+
+ var pdpsMap = {};
+ var pdps = [];
+ var policiesMap = {};
+ var policies = [];
+ var projectsMap = {};
+ var projects = [];
+
+ function loadPdps() {
+ var queries = {
+ pdps: pdpResource.query().$promise,
+ policies: policyResource.query().$promise,
+ projects: keystone.getProjects()
+ }
+
+ $q.all(queries).then(function (result) {
+ createPdps(result.pdps, result.policies, result.projects.data)
+ console.log('moon', 'pdps initialized', pdps)
+ })
+ }
+
+ function createPdps(pdpsData, policiesData, projectsData) {
+ pdps.splice(0, pdps.length);
+ policies.splice(0, policies.length);
+ projects.splice(0, projects.length);
+ util.cleanObject(pdpsMap);
+ util.cleanObject(policiesMap);
+ util.cleanObject(projectsMap)
+
+ util.createInternal(policiesData.policies, policies, policiesMap);
+ util.pushAll(projects, projectsData.items);
+ util.addToMap(projects, projectsMap);
+ createPdpInternal(pdpsData.pdps);
+ }
+
+ function mapPdp(pdp) {
+ util.mapIdToItem(pdp.security_pipeline, policiesMap);
+ pdp.project = null;
+ if (pdp.keystone_project_id) {
+ pdp.project = projectsMap[pdp.keystone_project_id];
+ }
+ }
+
+ function createPdpInternal(data) {
+ return util.createInternal(data, pdps, pdpsMap, mapPdp);
+ }
+
+ function updatePdpInternal(data) {
+ return util.updateInternal(data, pdpsMap, mapPdp);
+ }
+
+ function removePdpInternal(id) {
+ return util.removeInternal(id, pdps, pdpsMap);
+ }
+
+ return {
+ initialize: loadPdps,
+ createPdps: createPdps,
+ pdps: pdps,
+ policies: policies,
+ projects: projects,
+ createPdp: function createPdp(pdp) {
+ pdp.keystone_project_id = null;
+ pdp.security_pipeline = [];
+ pdpResource.create(null, pdp, success, util.displayErrorFunction('Unable to create PDP'));
+
+ function success(data) {
+ createPdpInternal(data.pdps);
+ util.displaySuccess('PDP created');
+ }
+ },
+ removePdp: function removePdp(pdp) {
+ pdpResource.remove({ id: pdp.id }, null, success, util.displayErrorFunction('Unable to remove PDP'));
+
+ function success(data) {
+ removePdpInternal(pdp.id);
+ util.displaySuccess('PDP removed');
+ }
+ },
+ updatePdp: function updatePdp(pdp) {
+ util.mapItemToId(pdp.security_pipeline);
+ pdp.keystone_project_id = pdp.project ? pdp.project.id : null;
+ pdpResource.update({ id: pdp.id }, pdp, success, util.displayErrorFunction('Unable to update PDP'));
+
+ function success(data) {
+ updatePdpInternal(data.pdps)
+ util.displaySuccess('PDP updated');
+ }
+ },
+ getPolicy: function getPolicy(id) {
+ return policiesMap[id];
+ },
+ getProject: function getProject(id) {
+ return projectsMap[id];
+ },
+ }
+
+ }
+})(); \ No newline at end of file
diff --git a/moon_dashboard/moon/static/moon/pdp/pdp.service.spec.js b/moon_dashboard/moon/static/moon/pdp/pdp.service.spec.js
new file mode 100755
index 00000000..4208467f
--- /dev/null
+++ b/moon_dashboard/moon/static/moon/pdp/pdp.service.spec.js
@@ -0,0 +1,143 @@
+(function () {
+ 'use strict';
+
+ describe('moon.pdp.service', function () {
+ var service, $httpBackend, URI;
+ var pdpsData, policiesData, projectsData;
+
+
+ function initData() {
+ pdpsData = {
+ pdps:
+ { 'pdpId1': { name: 'pdp1', description: 'pdpDescription1', security_pipeline: ['policyId1'], keystone_project_id: 'projectId1' } }
+ };
+
+ policiesData = {
+ policies:
+ {
+ 'policyId1': { name: 'policy1', description: 'pDescription1' },
+ 'policyId2': { name: 'policy2', description: 'pDescription2' }
+ }
+ };
+
+ projectsData = {
+ items: [
+ { name: "project1", id: "projectId1" },
+ { name: "project2", id: "projectId2" }
+ ]
+ };
+
+ }
+
+ beforeEach(module('horizon.app.core'));
+ beforeEach(module('horizon.framework'));
+ beforeEach(module('moon'));
+
+ beforeEach(inject(function ($injector) {
+ service = $injector.get('moon.pdp.service');
+ $httpBackend = $injector.get('$httpBackend');
+ URI = $injector.get('moon.URI');
+ }));
+
+ afterEach(function () {
+ $httpBackend.verifyNoOutstandingExpectation();
+ $httpBackend.verifyNoOutstandingRequest();
+ });
+
+ it('should initialize', function () {
+ initData();
+ $httpBackend.expectGET(URI.API + '/pdp').respond(200, pdpsData);
+ $httpBackend.expectGET(URI.API + '/policies').respond(200, policiesData);
+ $httpBackend.expectGET('/api/keystone/projects/').respond(200, projectsData);
+
+
+ service.initialize();
+ $httpBackend.flush();
+
+ expect(service.pdps.length).toBe(1);
+ var pdp = service.pdps[0];
+ expect(pdp.id).toBe('pdpId1');
+ expect(pdp.name).toBe('pdp1');
+ expect(pdp.description).toBe('pdpDescription1');
+ expect(pdp.security_pipeline.length).toBe(1);
+ expect(pdp.security_pipeline[0].id).toBe('policyId1');
+ expect(pdp.keystone_project_id).toBe('projectId1');
+ expect(pdp.project.id).toBe('projectId1');
+
+ expect(service.policies.length).toBe(2);
+ var policy = service.policies[0];
+ expect(policy.id).toBe('policyId1');
+ expect(policy.name).toBe('policy1');
+ expect(policy.description).toBe('pDescription1');
+
+
+ expect(service.projects.length).toBe(2);
+ var project = service.projects[0];
+ expect(project.id).toBe('projectId1');
+ expect(project.name).toBe('project1');
+
+ });
+
+
+
+ it('should create pdp', function () {
+ var pdpCreatedData = {
+ pdps:
+ { 'pdpId1': { name: 'pdp1', description: 'pdpDescription1', security_pipeline: [], keystone_project_id: null } }
+ };
+
+ $httpBackend.expectPOST(URI.API + '/pdp').respond(200, pdpCreatedData);
+
+ service.createPdp({ name: 'pdp1', description: 'pdpDescription1' });
+ $httpBackend.flush();
+
+ expect(service.pdps.length).toBe(1);
+ var pdp = service.pdps[0];
+ expect(pdp.id).toBe('pdpId1');
+ expect(pdp.name).toBe('pdp1');
+ expect(pdp.description).toBe('pdpDescription1');
+ expect(pdp.project).toBe(null);
+ expect(pdp.security_pipeline.length).toBe(0);
+ });
+
+ it('should remove pdp', function () {
+ initData();
+ service.createPdps(pdpsData, policiesData, projectsData);
+
+ $httpBackend.expectDELETE(URI.API + '/pdp/pdpId1').respond(200);
+
+ service.removePdp({ id: 'pdpId1' });
+ $httpBackend.flush();
+
+ expect(service.pdps.length).toBe(0);
+ });
+
+ it('should update pdp', function () {
+ initData();
+ var pdpUpdatedData = {
+ pdps:
+ { 'pdpId1': { name: 'pdp2', description: 'pdpDescription2', security_pipeline: ['policyId2'], keystone_project_id: 'projectId2' } }
+ };
+ service.createPdps(pdpsData, policiesData, projectsData);
+
+ $httpBackend.expectPATCH(URI.API + '/pdp/pdpId1').respond(200, pdpUpdatedData);
+
+ service.updatePdp({ id: 'pdpId1', name: 'pdp2', description: 'pdpDescription2', security_pipeline: [service.getPolicy('policyId2')], project: service.getProject('projectId2') });
+ $httpBackend.flush();
+
+ expect(service.pdps.length).toBe(1);
+ var pdp = service.pdps[0];
+ expect(pdp.id).toBe('pdpId1');
+ expect(pdp.name).toBe('pdp2');
+ expect(pdp.description).toBe('pdpDescription2');
+ expect(pdp.project.id).toBe('projectId2');
+ expect(pdp.security_pipeline.length).toBe(1);
+ expect(pdp.security_pipeline[0].id).toBe('policyId2');
+
+ });
+
+
+ });
+
+
+})(); \ No newline at end of file
diff --git a/moon_dashboard/moon/static/moon/policy/policy.controller.js b/moon_dashboard/moon/static/moon/policy/policy.controller.js
new file mode 100644
index 00000000..6c6631cf
--- /dev/null
+++ b/moon_dashboard/moon/static/moon/policy/policy.controller.js
@@ -0,0 +1,295 @@
+(function () {
+ 'use strict';
+
+ angular
+ .module('moon')
+ .controller('moon.policy.controller',
+ controller);
+
+ controller.$inject = ['moon.util.service', 'moon.policy.service', 'moon.model.service', 'horizon.framework.widgets.form.ModalFormService'];
+
+ function controller(util, policyService, modelService, ModalFormService) {
+ var self = this;
+ var genres = [{ value: 'admin', name: gettext('admin') }, { value: 'authz', name: gettext('authz') }];
+ self.model = policyService;
+ self.selectedRule = null;
+ self.currentData = null;
+ policyService.initialize();
+
+ var dataTitleMaps = {};
+
+ var categoryMap = {
+ subject: {
+ perimeterId: 'subject_id'
+ },
+ object: {
+ perimeterId: 'object_id'
+ },
+ action: {
+ perimeterId: 'action_id'
+ },
+ }
+
+ function createAddDataButton(type, index, category, config, policy) {
+ config.form.push({
+ "key": type + index + "Button",
+ "type": "button",
+ "title": "Add",
+ onClick: createDataFunction(type, category, policy)
+ })
+ }
+
+ function createDataFunction(type, category, policy) {
+ return function () {
+ var schema = {
+ type: "object",
+ properties: {
+ name: { type: "string", minLength: 2, title: gettext("Name") },
+ description: { type: "string", minLength: 2, title: gettext("Description") },
+ }
+ };
+ var data = { name: '', description: '' };
+ var config = {
+ title: gettext('Create Data of ' + category.name + ' category'),
+ schema: schema,
+ form: ['name', { key: 'description', type: 'textarea' }],
+ model: data
+ };
+ ModalFormService.open(config).then(submit);
+
+ function submit(form) {
+ policyService.createData(type, policy, category, form.model).then(
+ function (data) {
+ util.pushAll(dataTitleMaps[category.id], util.arrayToTitleMap(data));
+ }
+ );
+ }
+ }
+ }
+
+ function getOrCreateDataTitleMap(category, data, policy) {
+ var result = dataTitleMaps[category.id];
+ if (!result) {
+ result = util.arrayToTitleMap(data);
+ dataTitleMaps[category.id] = result;
+ }
+ return result;
+ }
+
+ function createDataSelect(type, categories, data, config, policy) {
+ for (var i = 0; i < categories.length; i++) {
+ var category = categories[i];
+ var titleMap = getOrCreateDataTitleMap(category, data, policy);
+ config.schema.properties[type + i] = { type: "string", title: gettext('Select ' + type + ' data of ' + category.name + ' category') };
+ config.form.push({ key: type + i, type: 'select', titleMap: titleMap });
+ createAddDataButton(type, i, category, config, policy);
+ }
+ }
+
+ function pushData(type, model, array) {
+ var i = 0;
+ while ((type + i) in model) {
+ array.push(model[type + i]);
+ i++;
+ }
+ }
+
+ self.createPolicy = function createPolicy() {
+ var schema = {
+ type: "object",
+ properties: {
+ name: { type: "string", minLength: 2, title: gettext("Name") },
+ description: { type: "string", minLength: 2, title: gettext("Description") },
+ genre: { type: "string", title: gettext("genre") },
+ model_id: { type: "string", title: gettext("Select a Model:") }
+ }
+ };
+ var policy = { name: '', description: '', model_id: null, genre: '' };
+ var titleMap = util.arrayToTitleMap(modelService.models)
+ var config = {
+ title: gettext('Create Policy'),
+ schema: schema,
+ form: ['name', { key: 'description', type: 'textarea' }, { key: 'genre', type: 'select', titleMap: genres }, { key: 'model_id', type: 'select', titleMap: titleMap }],
+ model: policy
+ };
+ ModalFormService.open(config).then(submit);
+
+ function submit(form) {
+ policyService.createPolicy(form.model);
+ }
+ }
+
+ self.updatePolicy = function updatePolicy(policy) {
+ var schema = {
+ type: "object",
+ properties: {
+ name: { type: "string", minLength: 2, title: gettext("Name") },
+ description: { type: "string", minLength: 2, title: gettext("Description") },
+ genre: { type: "string", title: gettext("Genre") },
+ }
+ };
+ var config = {
+ title: gettext('Update Policy'),
+ schema: schema,
+ form: ['name', { key: 'description', type: 'textarea' }, { key: 'genre', type: 'select', titleMap: genres }],
+ model: { name: policy.name, description: policy.description, model_id: policy.model_id, id: policy.id, genre: policy.genre }
+ };
+ ModalFormService.open(config).then(submit);
+
+ function submit(form) {
+ policyService.updatePolicy(form.model);
+ }
+ }
+
+ self.addRuleWithMetaRule = function addRuleWithMetaRule(policy, metaRule) {
+ var schema = {
+ type: "object",
+ properties: {
+ instructions: { type: "string", title: gettext("Instructions") }
+ }
+ };
+
+ var config = {
+ title: gettext('Add Rule'),
+ schema: schema,
+ form: [],
+ model: {
+ instructions: '[{"decision": "grant"}]'
+ }
+ };
+ dataTitleMaps = {};
+ createDataSelect('subject', metaRule.subject_categories, policy.subjectData, config, policy);
+ createDataSelect('object', metaRule.object_categories, policy.objectData, config, policy);
+ createDataSelect('action', metaRule.action_categories, policy.actionData, config, policy);
+ config.form.push({ key: 'instructions', type: 'textarea' })
+
+ ModalFormService.open(config).then(submit);
+
+ function submit(form) {
+ var rule = { enabled: true };
+ rule.instructions = JSON.parse(form.model.instructions);
+ rule.meta_rule_id = metaRule.id;
+ rule.policy_id = policy.id;
+ rule.rule = [];
+ pushData('subject', form.model, rule.rule);
+ pushData('object', form.model, rule.rule);
+ pushData('action', form.model, rule.rule);
+ policyService.addRuleToPolicy(policy, rule);
+ }
+ }
+
+ self.addRule = function addRule(policy) {
+ var schema = {
+ type: "object",
+ properties: {
+ metaRuleId: { type: "string", title: gettext("Select a Metarule:") }
+ }
+ };
+ var rule = { metaRuleId: null };
+ var titleMap = util.arrayToTitleMap(policy.model.meta_rules);
+ var config = {
+ title: gettext('Add Rule'),
+ schema: schema,
+ form: [{ key: 'metaRuleId', type: 'select', titleMap: titleMap }],
+ model: rule
+ };
+ ModalFormService.open(config).then(submit);
+
+ function submit(form) {
+ self.addRuleWithMetaRule(policy, modelService.getMetaRule(form.model.metaRuleId));
+ }
+ }
+
+ self.removePolicy = function removePolicy(policy) {
+ if (confirm(gettext('Are you sure to delete this Policy?')))
+ policyService.removePolicy(policy);
+ }
+
+ self.populatePolicy = function populatePolicy(policy) {
+ policyService.populatePolicy(policy);
+ }
+
+ self.removeRuleFromPolicy = function removeRuleFromPolicy(policy, rule) {
+ if (confirm(gettext('Are you sure to delete this Rule?')))
+ policyService.removeRuleFromPolicy(policy, rule);
+ }
+
+ self.showRule = function showRule(rule) {
+ self.selectedRule = rule;
+ }
+
+ self.hideRule = function hideRule() {
+ self.selectedRule = null;
+ self.currentData = null;
+ }
+
+ self.assignData = function assignData(type, policy, data) {
+ self.currentData = {
+ data: data,
+ type: type,
+ loading: true,
+ perimeters: [],
+ assignments: []
+ }
+
+ policyService.loadPerimetersAndAssignments(type, policy).then(function (values) {
+ var category = categoryMap[type];
+ self.currentData.loading = false;
+ self.currentData.perimeters = values.perimeters;
+ for (var index = 0; index < values.assignments.length; index++) {
+ var assignment = values.assignments[index];
+ if (assignment.assignments.indexOf(data.id) >= 0) {
+ var perimeter = values.perimetersMap[assignment[category.perimeterId]];
+ self.currentData.assignments.push(perimeter);
+ self.currentData.perimeters.splice(self.currentData.perimeters.indexOf(perimeter), 1);
+ }
+ }
+ })
+ }
+
+ self.createPerimeter = function createPerimeter(type, policy) {
+ var schema = {
+ type: "object",
+ properties: {
+ name: { type: "string", minLength: 2, title: gettext("Name") },
+ description: { type: "string", minLength: 2, title: gettext("Description") },
+ }
+ };
+ if (type == 'subject') {
+ schema.properties.email = { type: "email", "type": "string", "pattern": "^\\S+@\\S+$", title: gettext("Email") }
+ }
+ var perimeter = { name: '', description: '' };
+ var config = {
+ title: gettext('Create Perimeter'),
+ schema: schema,
+ form: ['name', { key: 'description', type: 'textarea' }],
+ model: perimeter
+ };
+ if (type == 'subject') {
+ config.form.push('email');
+ }
+
+ ModalFormService.open(config).then(submit);
+
+ function submit(form) {
+ policyService.createPerimeter(type, policy, form.model).then(function (perimeters) {
+ util.pushAll(self.currentData.perimeters, perimeters);
+ })
+ }
+ }
+
+ self.assign = function assign(type, policy, perimeter, data) {
+ policyService.createAssignment(type, policy, perimeter, data).then(function () {
+ self.currentData.assignments.push(perimeter);
+ self.currentData.perimeters.splice(self.currentData.perimeters.indexOf(perimeter), 1);
+ })
+ }
+
+ self.unassign = function unassign(type, policy, perimeter, data) {
+ policyService.removeAssignment(type, policy, perimeter, data).then(function () {
+ self.currentData.perimeters.push(perimeter);
+ self.currentData.assignments.splice(self.currentData.assignments.indexOf(perimeter), 1);
+ })
+ }
+ }
+})(); \ No newline at end of file
diff --git a/moon_dashboard/moon/static/moon/policy/policy.html b/moon_dashboard/moon/static/moon/policy/policy.html
new file mode 100644
index 00000000..70789fbb
--- /dev/null
+++ b/moon_dashboard/moon/static/moon/policy/policy.html
@@ -0,0 +1,158 @@
+<div ng-controller="moon.policy.controller as ctrl">
+ <div class="clearfix list-group">
+ <div class="pull-right">
+ <input type="search" class="form-control filter" placeholder="Filter" ng-model="filterText">
+ <button type="button" class="btn btn-default" ng-click="ctrl.createPolicy()">
+ <span class="fa fa-plus"></span>
+ <translate>Create Policy</translate>
+ </button>
+ </div>
+ </div>
+
+ <div class="list-group">
+ <div ng-repeat="policy in ctrl.model.policies | orderBy:'name' | filter:filterText" class="list-group-item">
+ <h3 class="list-group-item-heading inline">{$ policy.name $}</h3>
+ <div class="pull-right">
+ <button type="button" class="fa fa-trash" title="{$ 'Remove Policy' | translate $}" ng-click="ctrl.removePolicy(policy)"></button>
+ <button type="button" class="fa fa-edit" title="{$ 'Edit Policy' | translate $}" ng-click="ctrl.updatePolicy(policy)"></button>
+ </div>
+ <p class="list-group-item-text">{$ policy.description $}</p>
+ <h4 class="list-group-item-text">
+ <translate>Model: {$ policy.model ? policy.model.name : 'none' $}</translate>
+ </h4>
+ <h4 class="list-group-item-text">
+ <translate>Genre:</translate>
+ <translate>{$ policy.genre ? policy.genre : 'none' $}</translate>
+ </h4>
+ <details class="list-group-item-text">
+ <summary ng-click="ctrl.populatePolicy(policy)">
+ <h4 class="inline" translate>Rules</h4>
+ <button type="button" class="fa fa-plus " ng-click="ctrl.addRule(policy)" title="{$ 'Add Rule' | translate $}"></button>
+ </summary>
+ <div class="list-group">
+ <p ng-if="!policy.rules" class="list-group-item-text" translate>Loading rules...</p>
+ <div ng-if="policy.rules" ng-repeat="rule in policy.rules | orderBy:'name'" class="list-group-item">
+ <div class="list-group-item-heading" ng-if="ctrl.selectedRule != rule">
+ <div class="inline-block width-200">
+ <b>
+ <translate>Metarule: </translate>
+ </b> {$ rule.metaRule.name $}
+ </div>
+ <b>
+ <translate>Rule: </translate>
+ </b>
+ <span ng-repeat="data in rule.subjectData">
+ <span>{$ data.name $}{$ $last ? '' : ', ' $}</span>
+ </span> |
+ <span ng-repeat="data in rule.actionData">
+ <span>{$ data.name $}{$ $last ? '' : ', ' $}</span>
+ </span> |
+ <span ng-repeat="data in rule.objectData">
+ <span>{$ data.name $}{$ $last ? '' : ', ' $}</span>
+ </span>
+ <div class="pull-right">
+ <button type="button" class="fa fa-trash pull-right" ng-click="ctrl.removeRuleFromPolicy(policy, rule)" title="{$ 'Remove Rule' | translate $}"></button>
+ <button type="button" class="fa fa-eye pull-right" ng-click="ctrl.showRule(rule)" title="{$ 'Show Rule' | translate $}"></button>
+ </div>
+ </div>
+
+ <div ng-if="ctrl.selectedRule == rule">
+ <h3 class="list-group-item-heading inline">
+ <translate>Metarule: </translate> {$ rule.metaRule.name $}</h3>
+ <div class="pull-right">
+ <button type="button" class="fa fa-trash pull-right" ng-click="ctrl.removeRuleFromPolicy(policy, rule)" title="{$ 'Remove Rule' | translate $}"></button>
+ <button type="button" class="fa fa-eye-slash pull-right" ng-click="ctrl.hideRule()" title="{$ 'Hide Rule' | translate $}"></button>
+ </div>
+ <p class="list-group-item-text">
+ <table class="table">
+ <thead>
+ <tr>
+ <th>
+ <span translate>Subjects</span>
+ </th>
+ <th>
+ <span translate>Objects</span>
+ </th>
+ <th>
+ <span translate>Actions</span>
+ </th>
+ <th>
+ <span translate>Instructions</span>
+ </th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr>
+ <td>
+ <p ng-repeat="data in rule.subjectData">
+ <span ng-class="{'text-primary': ctrl.currentData.data == data}">{$ data.name $}</span>
+ <button ng-if="ctrl.currentData.data != data" type="button" class="fa fa-exchange pull-right" ng-click="ctrl.assignData('subject', policy, data)"
+ title="{$ 'Assign to perimeters' | translate $}"></button>
+ <button ng-if="ctrl.currentData.data == data" type="button" class="fa fa-times pull-right" ng-click="ctrl.currentData = null"
+ title="{$ 'Close' | translate $}"></button>
+ </p>
+ </td>
+ <td>
+ <p ng-repeat="data in rule.objectData">
+ <span ng-class="{'text-primary': ctrl.currentData.data == data}">{$ data.name $}</span>
+ <button ng-if="ctrl.currentData.data != data" type="button" class="fa fa-exchange pull-right" ng-click="ctrl.assignData('object', policy, data)"
+ title="{$ 'Assign to perimeters' | translate $}"></button>
+ <button ng-if="ctrl.currentData.data == data" type="button" class="fa fa-times pull-right" ng-click="ctrl.currentData = null"
+ title="{$ 'Close' | translate $}"></button>
+ </p>
+ </td>
+ <td>
+ <p ng-repeat="data in rule.actionData">
+ <span ng-class="{'text-primary': ctrl.currentData.data == data}">{$ data.name $}</span>
+ <button ng-if="ctrl.currentData.data != data" type="button" class="fa fa-exchange pull-right" ng-click="ctrl.assignData('action', policy, data)"
+ title="{$ 'Assign to perimeters' | translate $}"></button>
+ <button ng-if="ctrl.currentData.data == data" type="button" class="fa fa-times pull-right" ng-click="ctrl.currentData = null"
+ title="{$ 'Close' | translate $}"></button>
+ </p>
+ </td>
+ <td>
+ <pre ng-bind="rule.instructions | json "></pre>
+ </td>
+ </tr>
+ </tbody>
+ </table>
+ <div ng-if="ctrl.currentData && ctrl.currentData.loading" class="row padding-10">
+ <h4 translate>Loading...</h4>
+ </div>
+ <div ng-if="ctrl.currentData && !ctrl.currentData.loading" class="row">
+ <div class="padding-10">
+ <h3>
+ <translate>Assign perimeters to</translate> {$ ctrl.currentData.data.name $}</h3>
+ <input type="search" class="form-control filter" placeholder="Filter" ng-model="filterPerimeter">
+ <button type="button" class="btn btn-default" ng-click="ctrl.createPerimeter(ctrl.currentData.type, policy)">
+ <span class="fa fa-plus"></span>
+ <translate>Create Perimeter</translate>
+ </button>
+ </div>
+ <div>
+ <div class="col-lg-4">
+ <h4 translate>Available perimeters</h4>
+ <div class="w-100 height-200 scroll list-group border">
+ <button class="list-group-item" ng-repeat="perimeter in ctrl.currentData.perimeters | orderBy:'name' | filter:filterPerimeter" title="{$ perimeter.description $}"
+ ng-click="ctrl.assign(ctrl.currentData.type, policy, perimeter, ctrl.currentData.data)">{$ perimeter.name $}</button>
+ </div>
+ <p translate class="mt-5">Click to assign</p>
+ </div>
+ <div class="col-lg-4">
+ <h4 translate>Assigned perimeters</h4>
+ <div class="w-100 list-group border height-200 scroll">
+ <button class="list-group-item" ng-repeat="perimeter in ctrl.currentData.assignments | orderBy:'name' | filter:filterPerimeter" title="{$ perimeter.description $}"
+ ng-click="ctrl.unassign(ctrl.currentData.type, policy, perimeter, ctrl.currentData.data)">{$ perimeter.name $}</button>
+ </div>
+ <p translate class="mt-5">Click to unassign</p>
+ </div>
+ </div>
+ </div>
+ </p>
+ </div>
+ </div>
+ </div>
+ </details>
+ </div>
+ </div>
+</div> \ No newline at end of file
diff --git a/moon_dashboard/moon/static/moon/policy/policy.service.js b/moon_dashboard/moon/static/moon/policy/policy.service.js
new file mode 100755
index 00000000..87250b2e
--- /dev/null
+++ b/moon_dashboard/moon/static/moon/policy/policy.service.js
@@ -0,0 +1,330 @@
+(function () {
+
+ 'use strict';
+
+ angular
+ .module('moon')
+ .factory('moon.policy.service', policyService);
+
+ policyService.$inject = ['moon.util.service', 'moon.model.service', '$resource', 'moon.URI', '$q', 'horizon.framework.widgets.toast.service'];
+
+ function policyService(util, modelService, $resource, URI, $q, toast) {
+ var host = URI.API;
+
+ var policyResource = $resource(host + '/policies/' + ':id', {}, {
+ get: { method: 'GET' },
+ query: { method: 'GET' },
+ create: { method: 'POST' },
+ remove: { method: 'DELETE' },
+ update: { method: 'PATCH' }
+ });
+
+ var policyRulesResource = $resource(host + '/policies/' + ':policy_id' + '/rules/' + ':rule_id', {}, {
+ get: { method: 'GET' },
+ query: { method: 'GET' },
+ create: { method: 'POST' },
+ remove: { method: 'DELETE' }
+ });
+
+ var policySubjectDataResource = $resource(host + '/policies/' + ':policy_id' + '/subject_data/' + ':category_id', {}, {
+ query: {method: 'GET'},
+ create: { method: 'POST' },
+ })
+
+ var policyObjectDataResource = $resource(host + '/policies/' + ':policy_id' + '/object_data/' + ':category_id', {}, {
+ query: {method: 'GET'},
+ create: { method: 'POST' },
+ })
+
+ var policyActionDataResource = $resource(host + '/policies/' + ':policy_id' + '/action_data/' + ':category_id', {}, {
+ query: {method: 'GET'},
+ create: { method: 'POST' },
+ })
+
+ var policySubjectPerimetersResource = $resource(host + '/policies/' + ':policy_id' + '/subjects', {}, {
+ query: {method: 'GET'},
+ create: { method: 'POST' },
+ })
+
+ var policyObjectPerimetersResource = $resource(host + '/policies/' + ':policy_id' + '/objects', {}, {
+ query: {method: 'GET'},
+ create: { method: 'POST' },
+ })
+
+ var policyActionPerimetersResource = $resource(host + '/policies/' + ':policy_id' + '/actions', {}, {
+ query: {method: 'GET'},
+ create: { method: 'POST' },
+ })
+
+ var policySubjectAssignmentsResource = $resource(host + '/policies/' + ':policy_id' + '/subject_assignments/' + ':perimeter_id' + '/' + ':category_id' + '/' + ':data_id', {}, {
+ query: {method: 'GET'},
+ create: { method: 'POST' },
+ remove: { method: 'DELETE' }
+ })
+
+ var policyObjectAssignmentsResource = $resource(host + '/policies/' + ':policy_id' + '/object_assignments/' + ':perimeter_id' + '/' + ':category_id' + '/' + ':data_id', {}, {
+ query: {method: 'GET'},
+ create: { method: 'POST' },
+ remove: { method: 'DELETE' }
+ })
+
+ var policyActionAssignmentsResource = $resource(host + '/policies/' + ':policy_id' + '/action_assignments/' + ':perimeter_id' + '/' + ':category_id' + '/' + ':data_id', {}, {
+ query: {method: 'GET'},
+ create: { method: 'POST' },
+ remove: { method: 'DELETE' }
+ })
+
+
+ var categoryMap = {
+ 'subject': {
+ resource: policySubjectDataResource,
+ arrayName: "subjectData",
+ mapName: "subjectDataMap",
+ responseName: "subject_data",
+ perimeterResource: policySubjectPerimetersResource,
+ assignmentResource: policySubjectAssignmentsResource,
+ perimeterResponseName: "subjects",
+ assignmentResponseName: "subject_assignments",
+ },
+ 'object': {
+ resource: policyObjectDataResource,
+ arrayName: "objectData",
+ mapName: "objectDataMap",
+ responseName: "object_data",
+ perimeterResource: policyObjectPerimetersResource,
+ assignmentResource: policyObjectAssignmentsResource,
+ perimeterResponseName: "objects",
+ assignmentResponseName: "object_assignments",
+ },
+ 'action': {
+ resource: policyActionDataResource,
+ arrayName: "actionData",
+ mapName: "actionDataMap",
+ responseName: "action_data",
+ perimeterResource: policyActionPerimetersResource,
+ assignmentResource: policyActionAssignmentsResource,
+ perimeterResponseName: "actions",
+ assignmentResponseName: "action_assignments",
+ }
+ }
+
+ var policiesMap = {};
+ var policies = [];
+
+ function loadPolicies() {
+ var queries = {
+ policies: policyResource.query().$promise,
+ models: modelService.initialize(),
+ }
+
+ $q.all(queries).then(function (result) {
+ createPolicies(result.policies);
+ console.log('moon', 'policies initialized')
+ })
+ }
+
+ function createPolicies(policiesData) {
+ policies.splice(0, policies.length);
+ util.cleanObject(policiesMap);
+ createPolicyInternal(policiesData.policies);
+ }
+
+ function mapPolicy(policy) {
+ if (policy.model_id) {
+ policy.model = modelService.getModel(policy.model_id);
+ }
+ }
+
+ function createPolicyInternal(data) {
+ return util.createInternal(data, policies, policiesMap, mapPolicy);
+ }
+
+ function removePolicyInternal(id) {
+ return util.removeInternal(id, policies, policiesMap);
+ }
+
+ function updatePolicyInternal(data) {
+ return util.updateInternal(data, policiesMap, mapPolicy);
+ }
+
+ function removeRuleInternal(policy, rule) {
+ policy.rules.splice(policy.rules.indexOf(rule), 1);
+ }
+
+ function loadPolicyRule(policy) {
+ if (!policy.rules) {
+ var queries = {
+ rules: policyRulesResource.query({ policy_id: policy.id }).$promise,
+ subjectData: policySubjectDataResource.query({ policy_id: policy.id }).$promise,
+ objectData: policyObjectDataResource.query({ policy_id: policy.id }).$promise,
+ actionData: policyActionDataResource.query({ policy_id: policy.id }).$promise,
+ }
+
+ $q.all(queries).then(function (result) {
+ createRules(policy, result.rules, result.subjectData, result.objectData, result.actionData)
+ }, util.displayErrorFunction('Unable to load rules'))
+ }
+ }
+
+ function createRules(policy, rulesData, subjectsData, objectsData, actionsData) {
+ policy.rules = rulesData ? rulesData.rules.rules : [];
+ policy.subjectDataMap = subjectsData.subject_data.length > 0 ? subjectsData.subject_data[0].data : [];
+ policy.subjectData = util.mapToArray(policy.subjectDataMap);
+ policy.objectDataMap = objectsData.object_data.length > 0 ? objectsData.object_data[0].data : [];
+ policy.objectData = util.mapToArray(policy.objectDataMap);
+ policy.actionDataMap = actionsData.action_data.length > 0 ? actionsData.action_data[0].data : [];
+ policy.actionData = util.mapToArray(policy.actionDataMap);
+ for (var i = 0; i < policy.rules.length; i++) {
+ var rule = policy.rules[i];
+ populateRule(policy, rule);
+ }
+ }
+
+ function populateRule(policy, rule) {
+ if (rule.meta_rule_id) {
+ rule.metaRule = modelService.getMetaRule(rule.meta_rule_id);
+ }
+ if (rule.metaRule) {
+ var j = 0;
+ var k, id;
+ rule.subjectData = [];
+ rule.objectData = [];
+ rule.actionData = [];
+ for (k = 0; k < rule.metaRule.subject_categories.length; k++) {
+ id = rule.rule[j + k];
+ rule.subjectData.push(policy.subjectDataMap[id]);
+ }
+ j += k;
+ for (k = 0; k < rule.metaRule.object_categories.length; k++) {
+ id = rule.rule[j + k];
+ rule.objectData.push(policy.objectDataMap[id]);
+ }
+ j += k;
+ for (k = 0; k < rule.metaRule.action_categories.length; k++) {
+ id = rule.rule[j + k];
+ rule.actionData.push(policy.actionDataMap[id]);
+ }
+ }
+ return rule;
+ }
+
+ return {
+ initialize: loadPolicies,
+ createPolicies: createPolicies,
+ policies: policies,
+ getPolicy: function getPolicy(id) {
+ return policiesMap[id];
+ },
+ createPolicy: function createPolicy(policy) {
+ policyResource.create(null, policy, success, util.displayErrorFunction('Unable to create Policy'));
+
+ function success(data) {
+ createPolicyInternal(data.policies);
+ util.displaySuccess('Policy created');
+ }
+ },
+ removePolicy: function removePolicy(policy) {
+ policyResource.remove({ id: policy.id }, null, success, util.displayErrorFunction('Unable to remove Policy'));
+
+ function success(data) {
+ removePolicyInternal(policy.id);
+ util.displaySuccess('Policy removed');
+ }
+ },
+ updatePolicy: function updatePolicy(policy) {
+ policyResource.update({ id: policy.id }, policy, success, util.displayErrorFunction('Unable to update Policy'));
+
+ function success(data) {
+ updatePolicyInternal(data.policies)
+ util.displaySuccess('Policy updated');
+ }
+ },
+ populatePolicy: loadPolicyRule,
+ createRules: createRules,
+ addRuleToPolicy: function addRuleToPolicy(policy, rule) {
+ policyRulesResource.create({ policy_id: policy.id }, rule, success, util.displayErrorFunction('Unable to create Rule'));
+
+ function success(data) {
+ var rules = util.mapToArray(data.rules);
+ for (var i = 0; i < rules.length; i++) {
+ var rule = rules[i];
+ policy.rules.push(populateRule(policy, rule))
+ }
+ util.displaySuccess('Rule created');
+ }
+ },
+ removeRuleFromPolicy: function removeRuleFromPolicy(policy, rule) {
+ policyRulesResource.remove({ policy_id: policy.id, rule_id: rule.id }, null, success, util.displayErrorFunction('Unable to remove Rule'));
+
+ function success(data) {
+ removeRuleInternal(policy, rule);
+ util.displaySuccess('Rule removed');
+ }
+ },
+ createData: function createData(type, policy, category, dataCategory) {
+ var categoryValue = categoryMap[type];
+ return categoryValue.resource.create({ policy_id: policy.id, category_id: category.id }, dataCategory).$promise.then(
+ function (data) {
+ var result = util.createInternal(data[categoryValue.responseName].data, policy[categoryValue.arrayName], policy[categoryValue.mapName]);
+ util.displaySuccess('Data created');
+ return result;
+ },
+ util.displayErrorFunction('Unable to create Data')
+ );
+ },
+ createPerimeter: function createPerimeter(type, policy, perimeter) {
+ var categoryValue = categoryMap[type];
+ return categoryValue.perimeterResource.create({ policy_id: policy.id }, perimeter).$promise.then(
+ function (data) {
+ util.displaySuccess('Perimeter created');
+ return util.mapToArray(data[categoryValue.perimeterResponseName]);
+ },
+ util.displayErrorFunction('Unable to create Perimeter')
+ );
+ },
+ loadPerimetersAndAssignments: function loadPerimetersAndAssignments(type, policy) {
+ var categoryValue = categoryMap[type];
+ var queries = {
+ perimeters: categoryValue.perimeterResource.query({ policy_id: policy.id }).$promise,
+ assignments: categoryValue.assignmentResource.query({ policy_id: policy.id }).$promise,
+ }
+
+ return $q.all(queries).then(function (data) {
+ var result = {};
+ result.assignments = util.mapToArray(data.assignments[categoryValue.assignmentResponseName]);
+ result.perimetersMap = data.perimeters[categoryValue.perimeterResponseName];
+ result.perimeters = util.mapToArray(result.perimetersMap);
+ return result;
+ }, util.displayErrorFunction('Unable to load Perimeters'))
+
+ },
+ createAssignment: function createAssignment(type, policy, perimeter, data) {
+ var categoryValue = categoryMap[type];
+ var assignment = {
+ "id": perimeter.id,
+ "category_id": data.category_id,
+ "data_id": data.id,
+ "policy_id": policy.id
+ }
+ return categoryValue.assignmentResource.create({ policy_id: policy.id }, assignment).$promise.then(
+ function (data) {
+ util.displaySuccess('Assignment created');
+ return util.mapToArray(data[categoryValue.assignmentResponseName]);
+ },
+ util.displayErrorFunction('Unable to create Assignment')
+ )
+ },
+ removeAssignment: function removeAssignment(type, policy, perimeter, data) {
+ var categoryValue = categoryMap[type];
+
+ return categoryValue.assignmentResource.remove({ policy_id: policy.id, perimeter_id: perimeter.id, category_id: data.category_id, data_id: data.id }, null).$promise.then(
+ function (data) {
+ util.displaySuccess('Assignment removed');
+ },
+ util.displayErrorFunction('Unable to remove Assignment')
+ )
+ },
+ }
+
+ }
+})(); \ No newline at end of file
diff --git a/moon_dashboard/moon/static/moon/policy/policy.service.spec.js b/moon_dashboard/moon/static/moon/policy/policy.service.spec.js
new file mode 100755
index 00000000..045bf9b3
--- /dev/null
+++ b/moon_dashboard/moon/static/moon/policy/policy.service.spec.js
@@ -0,0 +1,336 @@
+(function () {
+ 'use strict';
+
+ describe('moon.policy.service', function () {
+ var service, modelService, $httpBackend, URI;
+ var policiesData;
+ var modelsData, metaRulesData, subjectCategoriesData, objectCategoriesData, actionCategoriesData;
+ var rulesData, subjectsData, objectsData, actionsData;
+
+
+ function initData() {
+ policiesData = {
+ policies:
+ {
+ 'policyId1': { name: 'policy1', description: 'pDescription1', genre: 'genre1', model_id: 'modelId1' },
+ }
+ };
+
+ modelsData = {
+ models:
+ { 'modelId1': { name: 'model1', description: 'mDescription1', meta_rules: ['metaRuleId1'] } }
+ };
+
+ subjectCategoriesData = {
+ subject_categories:
+ {
+ 'subjectCategoryId1': { name: 'subjectCategory1', description: 'scDescription1' },
+ 'subjectCategoryId2': { name: 'subjectCategory2', description: 'scDescription2' }
+ },
+ };
+ objectCategoriesData = {
+ object_categories:
+ {
+ 'objectCategoryId1': { name: 'objectCategory1', description: 'ocDescription1' },
+ 'objectCategoryId2': { name: 'objectCategory2', description: 'ocDescription2' }
+ }
+ };
+ actionCategoriesData = {
+ action_categories:
+ {
+ 'actionCategoryId1': { name: 'actionCategory1', description: 'acDescription1' },
+ 'actionCategoryId2': { name: 'actionCategory2', description: 'acDescription2' }
+ }
+ };
+ metaRulesData = {
+ meta_rules:
+ {
+ 'metaRuleId1': { name: 'metaRule1', description: 'mrDescription1', subject_categories: ['subjectCategoryId1'], object_categories: ['objectCategoryId1'], action_categories: ['actionCategoryId1'] },
+ 'metaRuleId2': { name: 'metaRule2', description: 'mrDescription2', subject_categories: [], object_categories: [], action_categories: [] }
+ }
+ };
+ }
+
+ function initRuleData() {
+ rulesData = {
+ rules: {
+ rules: [
+ { meta_rule_id: 'metaRuleId1', rule: ['subjectId1', 'objectId1', 'actionId1'], id: 'ruleId1', instructions: { test: 'test' } }
+ ]
+ }
+ };
+
+ subjectsData = {
+ subject_data:
+ [
+ {
+ data: {
+ 'subjectId1': { name: 'subject1', description: 'sDescription1' },
+ }
+ }
+ ]
+ };
+ objectsData = {
+ object_data:
+ [
+ {
+ data: {
+ 'objectId1': { name: 'object1', description: 'oDescription1' },
+ }
+ }
+ ]
+ };
+ actionsData = {
+ action_data:
+ [
+ {
+ data: {
+ 'actionId1': { name: 'action1', description: 'aDescription1' },
+ }
+ }
+ ]
+ };
+ }
+
+ beforeEach(module('horizon.app.core'));
+ beforeEach(module('horizon.framework'));
+ beforeEach(module('moon'));
+
+ beforeEach(inject(function ($injector) {
+ service = $injector.get('moon.policy.service');
+ modelService = $injector.get('moon.model.service');
+ $httpBackend = $injector.get('$httpBackend');
+ URI = $injector.get('moon.URI');
+ }));
+
+ afterEach(function () {
+ $httpBackend.verifyNoOutstandingExpectation();
+ $httpBackend.verifyNoOutstandingRequest();
+ });
+
+ it('should initialize', function () {
+ initData();
+ $httpBackend.expectGET(URI.API + '/policies').respond(200, policiesData);
+ $httpBackend.expectGET(URI.API + '/subject_categories').respond(200, subjectCategoriesData);
+ $httpBackend.expectGET(URI.API + '/object_categories').respond(200, objectCategoriesData);
+ $httpBackend.expectGET(URI.API + '/action_categories').respond(200, actionCategoriesData);
+ $httpBackend.expectGET(URI.API + '/meta_rules').respond(200, metaRulesData);
+ $httpBackend.expectGET(URI.API + '/models').respond(200, modelsData);
+
+
+ service.initialize();
+ $httpBackend.flush();
+
+ expect(service.policies.length).toBe(1);
+ var policy = service.policies[0];
+ expect(policy.id).toBe('policyId1');
+ expect(policy.name).toBe('policy1');
+ expect(policy.description).toBe('pDescription1');
+ expect(policy.genre).toBe('genre1');
+ expect(policy.model.id).toBe('modelId1');
+
+ });
+
+
+
+ it('should create policy', function () {
+ initData();
+ modelService.createModels(modelsData, metaRulesData, subjectCategoriesData, objectCategoriesData, actionCategoriesData);
+
+ var policyCreatedData = {
+ policies:
+ { 'policyId1': { name: 'policy1', description: 'pDescription1', genre: 'genre1', model_id: 'modelId1' } }
+ };
+
+ $httpBackend.expectPOST(URI.API + '/policies').respond(200, policyCreatedData);
+
+ service.createPolicy({ name: 'policy1', description: 'pDescription1', genre: 'genre1', model: modelService.getModel('modelId1') });
+ $httpBackend.flush();
+
+ expect(service.policies.length).toBe(1);
+ var policy = service.policies[0];
+ expect(policy.id).toBe('policyId1');
+ expect(policy.name).toBe('policy1');
+ expect(policy.description).toBe('pDescription1');
+ expect(policy.genre).toBe('genre1');
+ expect(policy.model.id).toBe('modelId1');
+ });
+
+ it('should remove policy', function () {
+ initData();
+ modelService.createModels(modelsData, metaRulesData, subjectCategoriesData, objectCategoriesData, actionCategoriesData);
+ service.createPolicies(policiesData);
+
+ $httpBackend.expectDELETE(URI.API + '/policies/policyId1').respond(200);
+
+ service.removePolicy({ id: 'policyId1' });
+ $httpBackend.flush();
+
+ expect(service.policies.length).toBe(0);
+ });
+
+ it('should update policy', function () {
+ initData();
+ var policyUpdatedData = {
+ policies:
+ { 'policyId1': { name: 'policy2', description: 'pDescription2', genre: 'genre2', model_id: 'modelId1' } }
+ };
+ modelService.createModels(modelsData, metaRulesData, subjectCategoriesData, objectCategoriesData, actionCategoriesData);
+ service.createPolicies(policiesData);
+
+ $httpBackend.expectPATCH(URI.API + '/policies/policyId1').respond(200, policyUpdatedData);
+
+ service.updatePolicy({ id: 'policyId1', name: 'policy2', description: 'pDescription2', genre: 'genre2', model: modelService.getModel('modelId1') });
+ $httpBackend.flush();
+
+ expect(service.policies.length).toBe(1);
+ var policy = service.policies[0];
+ expect(policy.id).toBe('policyId1');
+ expect(policy.name).toBe('policy2');
+ expect(policy.description).toBe('pDescription2');
+ expect(policy.genre).toBe('genre2');
+ expect(policy.model.id).toBe('modelId1');
+
+ });
+
+
+ it('should populate policy', function () {
+ initData();
+ initRuleData();
+ modelService.createModels(modelsData, metaRulesData, subjectCategoriesData, objectCategoriesData, actionCategoriesData);
+ service.createPolicies(policiesData);
+
+ var policy = service.getPolicy('policyId1')
+
+ $httpBackend.expectGET(URI.API + '/policies/policyId1/rules').respond(200, rulesData);
+ $httpBackend.expectGET(URI.API + '/policies/policyId1/subject_data').respond(200, subjectsData);
+ $httpBackend.expectGET(URI.API + '/policies/policyId1/object_data').respond(200, objectsData);
+ $httpBackend.expectGET(URI.API + '/policies/policyId1/action_data').respond(200, actionsData);
+
+ service.populatePolicy(policy);
+ $httpBackend.flush();
+
+ expect(policy.rules.length).toBe(1);
+ var rule = policy.rules[0];
+ expect(rule.id).toBe('ruleId1');
+ expect(rule.metaRule.id).toBe('metaRuleId1');
+ expect(rule.instructions.test).toBe('test');
+ expect(rule.subjectData.length).toBe(1);
+ expect(rule.subjectData[0].id).toBe('subjectId1');
+ expect(rule.objectData.length).toBe(1);
+ expect(rule.objectData[0].id).toBe('objectId1');
+ expect(rule.actionData.length).toBe(1);
+ expect(rule.actionData[0].id).toBe('actionId1');
+
+ expect(policy.subjectData.length).toBe(1);
+ var subjectData = policy.subjectData[0];
+ expect(subjectData.id).toBe('subjectId1');
+ expect(subjectData.name).toBe('subject1');
+ expect(subjectData.description).toBe('sDescription1');
+
+ expect(policy.objectData.length).toBe(1);
+ var objectData = policy.objectData[0];
+ expect(objectData.id).toBe('objectId1');
+ expect(objectData.name).toBe('object1');
+ expect(objectData.description).toBe('oDescription1');
+
+ expect(policy.actionData.length).toBe(1);
+ var actionData = policy.actionData[0];
+ expect(actionData.id).toBe('actionId1');
+ expect(actionData.name).toBe('action1');
+ expect(actionData.description).toBe('aDescription1');
+
+ });
+
+
+ it('should add rule to policy', function () {
+ initData();
+ initRuleData();
+ modelService.createModels(modelsData, metaRulesData, subjectCategoriesData, objectCategoriesData, actionCategoriesData);
+ service.createPolicies(policiesData);
+
+
+ var ruleCreatedData = {
+ rules: {
+ 'ruleId1': { meta_rule_id: 'metaRuleId1', rule: ['subjectId1', 'objectId1', 'actionId1'], instructions: { test: 'test' } }
+ }
+ };
+
+ var policy = service.getPolicy('policyId1');
+
+ service.createRules(policy, null, subjectsData, objectsData, actionsData);
+
+ $httpBackend.expectPOST(URI.API + '/policies/policyId1/rules').respond(200, ruleCreatedData);
+
+ service.addRuleToPolicy(policy, { meta_rule_id: 'metaRuleId1', rule: ['subjectId1', 'objectId1', 'actionId1'], instructions: { test: 'test' } });
+ $httpBackend.flush();
+
+ expect(policy.rules.length).toBe(1);
+ var rule = policy.rules[0];
+ expect(rule.id).toBe('ruleId1');
+ expect(rule.metaRule.id).toBe('metaRuleId1');
+ expect(rule.subjectData.length).toBe(1);
+ expect(rule.subjectData[0].id).toBe('subjectId1');
+ expect(rule.objectData.length).toBe(1);
+ expect(rule.objectData[0].id).toBe('objectId1');
+ expect(rule.actionData.length).toBe(1);
+ expect(rule.actionData[0].id).toBe('actionId1');
+
+ });
+
+ it('should remove rule from policy', function () {
+ initData();
+ initRuleData();
+ modelService.createModels(modelsData, metaRulesData, subjectCategoriesData, objectCategoriesData, actionCategoriesData);
+ service.createPolicies(policiesData);
+
+ var policy = service.getPolicy('policyId1');
+
+ service.createRules(policy, rulesData, subjectsData, objectsData, actionsData);
+
+ $httpBackend.expectDELETE(URI.API + '/policies/policyId1/rules/ruleId1').respond(200);
+
+ service.removeRuleFromPolicy(policy, { id: 'ruleId1' });
+ $httpBackend.flush();
+
+ expect(policy.rules.length).toBe(0);
+ });
+
+
+ it('should create data', function () {
+ initData();
+ initRuleData();
+ modelService.createModels(modelsData, metaRulesData, subjectCategoriesData, objectCategoriesData, actionCategoriesData);
+ service.createPolicies(policiesData);
+
+
+ var dataCreatedData = {
+ subject_data: {
+ data: {
+ 'subjectId1': { name: 'subject1', description: 'sDescription1' },
+ }
+ }
+ };
+
+ var policy = service.getPolicy('policyId1');
+ policy.subjectData = [];
+ policy.subjectDataMap = {};
+
+ $httpBackend.expectPOST(URI.API + '/policies/policyId1/subject_data/subjectCategoryId1').respond(200, dataCreatedData);
+
+ service.createData('subject', policy, modelService.getCategory('subject', 'subjectCategoryId1'), { name: 'subject1', description: 'sDescription1' });
+ $httpBackend.flush();
+
+ expect(policy.subjectData.length).toBe(1);
+ var subjectData = policy.subjectData[0];
+ expect(subjectData.id).toBe('subjectId1');
+ expect(subjectData.name).toBe('subject1');
+ expect(subjectData.description).toBe('sDescription1');
+
+ });
+
+
+ });
+
+
+})(); \ No newline at end of file
diff --git a/moon_dashboard/moon/static/moon/scss/moon.scss b/moon_dashboard/moon/static/moon/scss/moon.scss
new file mode 100644
index 00000000..20bf6c41
--- /dev/null
+++ b/moon_dashboard/moon/static/moon/scss/moon.scss
@@ -0,0 +1,54 @@
+.inline {
+ display: inline;
+}
+
+.inline-block {
+ display: inline-block;
+}
+
+summary{
+ outline:none;
+ margin-bottom: 10px;
+}
+
+details {
+ cursor: default;
+}
+
+.filter {
+ display: inline-block;
+ width: auto;
+ vertical-align: middle;
+}
+
+.categories td {
+ width: 33%;
+}
+
+.width-200 {
+ width: 200px;
+}
+
+.height-200 {
+ height: 200px;
+}
+
+.border {
+ border: 1px #DDD solid;
+}
+
+.padding-10 {
+ padding: 10px;
+}
+
+.scroll {
+ overflow-y: auto;
+}
+
+.mt-5 {
+ margin-top: 5px;
+}
+
+.input-file {
+ display: none !important;
+} \ No newline at end of file
diff --git a/moon_dashboard/moon/templates/moon/base.html b/moon_dashboard/moon/templates/moon/base.html
new file mode 100644
index 00000000..f07a01ba
--- /dev/null
+++ b/moon_dashboard/moon/templates/moon/base.html
@@ -0,0 +1,11 @@
+{% load horizon %}{% jstemplate %}[% extends 'base.html' %]
+
+[% block sidebar %]
+ [% include 'horizon/common/_sidebar.html' %]
+[% endblock %]
+
+[% block main %]
+ [% include "horizon/_messages.html" %]
+ [% block {{ dash_name }}_main %][% endblock %]
+[% endblock %]
+{% endjstemplate %}
diff --git a/moon_dashboard/run.sh b/moon_dashboard/run.sh
new file mode 100644
index 00000000..bf18faa2
--- /dev/null
+++ b/moon_dashboard/run.sh
@@ -0,0 +1,26 @@
+#!/bin/sh
+# sudo docker run -ti --rm -p 8000:8000 -e MANAGER_HOST=localhost -e MANAGER_PORT=30001 -e KEYSTONE_HOST=localhost -e KEYSTONE_PORT=30005 moonplatform/dashboard:dev
+
+CONSTANT_FILE=/root/horizon/openstack_dashboard/dashboards/moon/static/moon/js/moon.module.js
+
+sed "s/{{MANAGER_HOST}}/$MANAGER_HOST/g" -i $CONSTANT_FILE
+sed "s/{{MANAGER_PORT}}/$MANAGER_PORT/g" -i $CONSTANT_FILE
+sed "s/{{KEYSTONE_HOST}}/$KEYSTONE_HOST/g" -i $CONSTANT_FILE
+sed "s/{{KEYSTONE_PORT}}/$KEYSTONE_PORT/g" -i $CONSTANT_FILE
+
+cd /root/horizon
+
+LOCAL_SETTINGS=/root/horizon/openstack_dashboard/local/local_settings.py
+sed "s/OPENSTACK_HOST = \"127.0.0.1\"/OPENSTACK_HOST = \"${OPENSTACK_HOST}\"/" -i $LOCAL_SETTINGS
+sed "s#OPENSTACK_KEYSTONE_URL = \"http:\/\/%s:5000\/v2.0\" % OPENSTACK_HOST#OPENSTACK_KEYSTONE_URL = \"${OPENSTACK_KEYSTONE_URL}\"#" -i $LOCAL_SETTINGS
+
+echo -----------------
+grep OPENSTACK_HOST $LOCAL_SETTINGS
+grep OPENSTACK_KEYSTONE_URL LOCAL_SETTINGS
+echo -----------------
+
+echo "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ $CONSTANT_FILE"
+cat $CONSTANT_FILE
+echo "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"
+
+tox -e runserver -- 0.0.0.0:8000 \ No newline at end of file
diff --git a/moon_dashboard/setup.cfg b/moon_dashboard/setup.cfg
new file mode 100644
index 00000000..f68765dd
--- /dev/null
+++ b/moon_dashboard/setup.cfg
@@ -0,0 +1,24 @@
+[metadata]
+name = moon
+version=1.2.0
+summary = A dashboard plugin for Moon
+description-file =
+ README.rst
+author = Jonathan Gourdin
+author_email = jonathan.gourdin@orange.com
+home-page = https://docs.openstack.org/horizon/latest/
+classifiers = [
+ Environment :: OpenStack
+ Framework :: Django
+ Intended Audience :: Developers
+ 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 :: 3.5
+
+[files]
+packages =
+ moon \ No newline at end of file
diff --git a/moon_dashboard/setup.py b/moon_dashboard/setup.py
new file mode 100644
index 00000000..4794e334
--- /dev/null
+++ b/moon_dashboard/setup.py
@@ -0,0 +1,14 @@
+# THIS FILE IS MANAGED BY THE GLOBAL REQUIREMENTS REPO - DO NOT EDIT
+import setuptools
+
+# In python < 2.7.4, a lazy loading of package `pbr` will break
+# setuptools if some other modules registered functions in `atexit`.
+# solution from: http://bugs.python.org/issue15881#msg170215
+try:
+ import multiprocessing # noqa
+except ImportError:
+ pass
+
+setuptools.setup(
+ setup_requires=['pbr>=1.8'],
+ pbr=True) \ No newline at end of file
diff --git a/moon_forming/Changelog b/moon_forming/Changelog
new file mode 100644
index 00000000..a107efd9
--- /dev/null
+++ b/moon_forming/Changelog
@@ -0,0 +1,11 @@
+CHANGES
+=======
+
+1.4.0
+-----
+- Update the python_moondb version to 1.2.10
+
+1.4.1
+-----
+- Update the python_moondb version to 1.2.16
+
diff --git a/moon_forming/Dockerfile b/moon_forming/Dockerfile
index 74616c89..3a39880b 100644
--- a/moon_forming/Dockerfile
+++ b/moon_forming/Dockerfile
@@ -1,11 +1,17 @@
FROM python:3
+
+LABEL Name=Forming
+LABEL Description="Configuration job for the Moon platform"
+LABEL Maintainer="Thomas Duval"
+LABEL Url="https://wiki.opnfv.org/display/moon/Moon+Project+Proposal"
+
+USER root
+
WORKDIR /usr/src/app
RUN pip install --no-cache-dir --upgrade requests pytest pyyaml python_moonutilities python_moondb python_moonclient
-ENV COMMAND "config"
-
ADD . /root
WORKDIR /root
-CMD /bin/bash /root/switch.sh ${COMMAND}
+CMD /bin/bash /root/config_moon.sh
diff --git a/moon_forming/conf2consul.py b/moon_forming/conf2consul.py
index 148bf923..df7a6b18 100644
--- a/moon_forming/conf2consul.py
+++ b/moon_forming/conf2consul.py
@@ -6,6 +6,8 @@ import logging
import json
import base64
+__version__ = "1.4.1"
+
logging.basicConfig(level=logging.INFO)
log = logging.getLogger("moon.conf2consul")
requests_log = logging.getLogger("requests.packages.urllib3")
diff --git a/moon_forming/switch.sh b/moon_forming/switch.sh
deleted file mode 100644
index adb1ebe9..00000000
--- a/moon_forming/switch.sh
+++ /dev/null
@@ -1,19 +0,0 @@
-#!/usr/bin/env bash
-
-CMD=$1
-
-echo "COMMAND IS ${CMD}"
-
-if [ "${CMD}" = "functest" ]; then
- echo "FUNCTIONAL TESTS"
- ls -l /data
- ls -l /data/tests
- sh /data/tests/functional_pod/run_functional_tests.sh
-#elif [ $CMD == "unittest" ]; then
-# sh /data/tests/functional_pod/run_functional_tests.sh
-else
- echo "CONFIGURATION"
- bash config_moon.sh
-fi
-
-echo "<END OF JOB>" \ No newline at end of file
diff --git a/moon_gui/package.json b/moon_gui/package.json
index 599452e4..45157e5e 100644
--- a/moon_gui/package.json
+++ b/moon_gui/package.json
@@ -50,5 +50,5 @@
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
- "license": "ISC"
+ "license": "Apache-2.0"
}
diff --git a/moon_interface/Changelog b/moon_interface/Changelog
new file mode 100644
index 00000000..cea475f2
--- /dev/null
+++ b/moon_interface/Changelog
@@ -0,0 +1,32 @@
+# Copyright 2018 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
+=======
+
+1.0.0
+-----
+- First version of the manager
+
+2.0.0
+-----
+- Version built inside the Keystone component
+
+3.0.0
+-----
+- Version built outside the Keystone component
+
+4.0.0
+-----
+- First micro-architecture version
+
+4.3.3
+-----
+- use the threading capability of Flask app
+
+4.3.3-1
+-----
+- Fix a bug in authz_requests
diff --git a/moon_interface/Dockerfile b/moon_interface/Dockerfile
index f4de15eb..00880496 100644
--- a/moon_interface/Dockerfile
+++ b/moon_interface/Dockerfile
@@ -1,8 +1,15 @@
FROM python:3
+LABEL Name=Interface
+LABEL Description="Interface component for the Moon platform"
+LABEL Maintainer="Thomas Duval"
+LABEL Url="https://wiki.opnfv.org/display/moon/Moon+Project+Proposal"
+
+USER root
+
ADD . /root
WORKDIR /root/
-RUN pip3 install -r requirements.txt
-RUN pip3 install .
+RUN pip3 install --no-cache-dir -r requirements.txt
+RUN pip3 install --no-cache-dir .
CMD ["python3", "-m", "moon_interface"] \ No newline at end of file
diff --git a/moon_interface/moon_interface/__init__.py b/moon_interface/moon_interface/__init__.py
index 6f964a63..a8cd9455 100644
--- a/moon_interface/moon_interface/__init__.py
+++ b/moon_interface/moon_interface/__init__.py
@@ -3,4 +3,4 @@
# license which can be found in the file 'LICENSE' in this package distribution
# or at 'http://www.apache.org/licenses/LICENSE-2.0'.
-__version__ = "4.3.2"
+__version__ = "4.3.3-1"
diff --git a/moon_interface/moon_interface/authz_requests.py b/moon_interface/moon_interface/authz_requests.py
index 2ef0e0a1..c809053b 100644
--- a/moon_interface/moon_interface/authz_requests.py
+++ b/moon_interface/moon_interface/authz_requests.py
@@ -65,6 +65,7 @@ class AuthzRequest:
"(with address - {})".format(req.status_code)
)
success = True
+ break
except requests.exceptions.ConnectionError:
logger.error("Cannot connect to {}".format(
"http://{}:{}/authz".format(
diff --git a/moon_interface/moon_interface/http_server.py b/moon_interface/moon_interface/http_server.py
index a2e25377..1e0858c0 100644
--- a/moon_interface/moon_interface/http_server.py
+++ b/moon_interface/moon_interface/http_server.py
@@ -133,4 +133,4 @@ class HTTPServer(Server):
)
def run(self):
- self.app.run(host=self._host, port=self._port) # nosec
+ self.app.run(host=self._host, port=self._port, threaded=True) # nosec
diff --git a/moon_interface/tests/unit_python/api/test_authz.py b/moon_interface/tests/unit_python/api/test_authz.py
index 052bc9c9..a227a303 100644
--- a/moon_interface/tests/unit_python/api/test_authz.py
+++ b/moon_interface/tests/unit_python/api/test_authz.py
@@ -23,7 +23,8 @@ def test_authz_true(context):
assert "result" in data
assert data['result'] is True
-def test_authz_False(context):
+
+def test_authz_false(context):
import moon_interface.server
server = moon_interface.server.create_server()
client = server.app.test_client()
@@ -48,7 +49,7 @@ def test_authz_effect_unset(context, set_consul_and_db):
set_consul_and_db.register_uri(
'POST', 'http://127.0.0.1:8081/authz',
- content = conftest.get_pickled_context_invalid()
+ content=conftest.get_pickled_context_invalid()
)
req = client.get("/authz/{p_id}/{s_id}/{o_id}/{a_id}".format(
@@ -63,6 +64,7 @@ def test_authz_effect_unset(context, set_consul_and_db):
assert "result" in data
assert data['result'] is False
+
def test_authz_invalid_ip(context, set_consul_and_db):
import moon_interface.server
server = moon_interface.server.create_server()
diff --git a/moon_interface/tests/unit_python/conftest.py b/moon_interface/tests/unit_python/conftest.py
index 893a8637..f6b204e6 100644
--- a/moon_interface/tests/unit_python/conftest.py
+++ b/moon_interface/tests/unit_python/conftest.py
@@ -400,7 +400,7 @@ def set_consul_and_db(monkeypatch):
"name": "testuser",
"email": "mail",
"id": "89ba91c18dd54abfbfde7a66936c51a6",
- "partner_id": ""
+ "extra": {}
},
"31fd15ad14784a9696fcc887dddbfaf9": {
"description": "test",
@@ -411,7 +411,7 @@ def set_consul_and_db(monkeypatch):
"name": "adminuser",
"email": "mail",
"id": "31fd15ad14784a9696fcc887dddbfaf9",
- "partner_id": ""
+ "extra": {}
}
}
}
@@ -424,7 +424,7 @@ def set_consul_and_db(monkeypatch):
"name": "vm1",
"description": "test",
"id": "67b8008a3f8d4f8e847eb628f0f7ca0e",
- "partner_id": "",
+ "extra": {},
"policy_list": [
"f8f49a779ceb47b3ac810f01ef71b4e0",
"636cd473324f4c0bbd9102cb5b62a16d"
@@ -434,7 +434,7 @@ def set_consul_and_db(monkeypatch):
"name": "vm0",
"description": "test",
"id": "9089b3d2ce5b4e929ffc7e35b55eba1a",
- "partner_id": "",
+ "extra": {},
"policy_list": [
"f8f49a779ceb47b3ac810f01ef71b4e0",
"636cd473324f4c0bbd9102cb5b62a16d"
@@ -451,7 +451,7 @@ def set_consul_and_db(monkeypatch):
"name": "boot",
"description": "test",
"id": "cdb3df220dc04a6ea3334b994827b068",
- "partner_id": "",
+ "extra": {},
"policy_list": [
"f8f49a779ceb47b3ac810f01ef71b4e0",
"636cd473324f4c0bbd9102cb5b62a16d"
@@ -461,7 +461,7 @@ def set_consul_and_db(monkeypatch):
"name": "stop",
"description": "test",
"id": "cdb3df220dc04a6ea3334b994827b068",
- "partner_id": "",
+ "extra": {},
"policy_list": [
"f8f49a779ceb47b3ac810f01ef71b4e0",
"636cd473324f4c0bbd9102cb5b62a16d"
@@ -471,7 +471,7 @@ def set_consul_and_db(monkeypatch):
"name": "start",
"description": "test",
"id": "9f5112afe9b34a6c894eb87246ccb7aa",
- "partner_id": "",
+ "extra": {},
"policy_list": [
"f8f49a779ceb47b3ac810f01ef71b4e0",
"636cd473324f4c0bbd9102cb5b62a16d"
diff --git a/moon_manager/Changelog b/moon_manager/Changelog
new file mode 100644
index 00000000..56521a0e
--- /dev/null
+++ b/moon_manager/Changelog
@@ -0,0 +1,42 @@
+# Copyright 2018 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
+=======
+
+1.0.0
+-----
+- First version of the manager
+
+2.0.0
+-----
+- Version built inside the Keystone component
+
+3.0.0
+-----
+- Version built outside the Keystone component
+
+4.0.0
+-----
+- First micro-architecture version
+
+4.5.2
+-----
+- use the threading capability of Flask app
+- set the number of manager to 1
+- update to the latest version of the python-moondb library
+
+4.5.2-1
+-----
+integrating validtion to send mandatory key names
+
+4.5.3
+-----
+- Removing try catch from all requets to allow raised exception to be passed to http server, to send actual error to client side
+- fixing test cases to assert on the expected exception after removing try-catch
+- allow 404 to be catched from our side instead of flask itself
+- revert the params in the get/post/patch/delete to be by default = None, so that we could catch the param if it was None
+instead of having not found url if the param is mandatory \ No newline at end of file
diff --git a/moon_manager/Dockerfile b/moon_manager/Dockerfile
index b5eb4e02..d264a113 100644
--- a/moon_manager/Dockerfile
+++ b/moon_manager/Dockerfile
@@ -1,8 +1,15 @@
FROM python:3
+LABEL Name=Manager
+LABEL Description="Manager component for the Moon platform"
+LABEL Maintainer="Thomas Duval"
+LABEL Url="https://wiki.opnfv.org/display/moon/Moon+Project+Proposal"
+
+USER root
+
ADD . /root
WORKDIR /root/
-RUN pip3 install -r requirements.txt
-RUN pip3 install .
+RUN pip3 install --no-cache-dir -r requirements.txt
+RUN pip3 install --no-cache-dir .
CMD ["python3", "-m", "moon_manager"] \ No newline at end of file
diff --git a/moon_manager/MANIFEST.in b/moon_manager/MANIFEST.in
index 1f674d50..cf4d2e4e 100644
--- a/moon_manager/MANIFEST.in
+++ b/moon_manager/MANIFEST.in
@@ -3,7 +3,7 @@
# license which can be found in the file 'LICENSE' in this package distribution
# or at 'http://www.apache.org/licenses/LICENSE-2.0'.
-include README.rst
+include README.md
include LICENSE
include setup.py
include requirements.txt
diff --git a/moon_manager/moon_manager/__init__.py b/moon_manager/moon_manager/__init__.py
index 85c245e0..205f6d8c 100644
--- a/moon_manager/moon_manager/__init__.py
+++ b/moon_manager/moon_manager/__init__.py
@@ -3,4 +3,4 @@
# license which can be found in the file 'LICENSE' in this package distribution
# or at 'http://www.apache.org/licenses/LICENSE-2.0'.
-__version__ = "4.4.0"
+__version__ = "4.5.3"
diff --git a/moon_manager/moon_manager/api/assignments.py b/moon_manager/moon_manager/api/assignments.py
index 0b2cd20b..426789e6 100644
--- a/moon_manager/moon_manager/api/assignments.py
+++ b/moon_manager/moon_manager/api/assignments.py
@@ -12,6 +12,7 @@ from flask_restful import Resource
import logging
from python_moonutilities.security_functions import check_auth
from python_moondb.core import PolicyManager
+from python_moonutilities.security_functions import validate_input
__version__ = "4.3.2"
@@ -31,15 +32,16 @@ class SubjectAssignments(Resource):
"/policies/<string:uuid>/subject_assignments/<string:perimeter_id>/<string:category_id>/<string:data_id>",
)
+ @validate_input("get", kwargs_state=[True, False, False,False,False])
@check_auth
- def get(self, uuid=None, perimeter_id=None, category_id=None,
+ def get(self, uuid, perimeter_id=None, category_id=None,
data_id=None, user_id=None):
"""Retrieve all subject assignments or a specific one for a given policy
:param uuid: uuid of the policy
:param perimeter_id: uuid of the subject
:param category_id: uuid of the subject category
- :param data_id: uuid of the subject scope
+ :param data_id: uuid of the subject scope (not used here)
:param user_id: user ID who do the request
:return: {
"subject_data_id": {
@@ -51,18 +53,16 @@ class SubjectAssignments(Resource):
}
:internal_api: get_subject_assignments
"""
- try:
- data = PolicyManager.get_subject_assignments(
- user_id=user_id, policy_id=uuid,
- subject_id=perimeter_id, category_id=category_id)
- except Exception as e:
- logger.error(e, exc_info=True)
- return {"result": False,
- "error": str(e)}, 500
+
+ data = PolicyManager.get_subject_assignments(
+ user_id=user_id, policy_id=uuid,
+ subject_id=perimeter_id, category_id=category_id)
+
return {"subject_assignments": data}
+ @validate_input("post", kwargs_state=[True, False, False, False, False], body_state={"id":True, "category_id":True, "data_id":True})
@check_auth
- def post(self, uuid=None, perimeter_id=None, category_id=None,
+ def post(self, uuid, perimeter_id=None, category_id=None,
data_id=None, user_id=None):
"""Create a subject assignment.
@@ -72,36 +72,32 @@ class SubjectAssignments(Resource):
:param data_id: uuid of the subject scope (not used here)
:param user_id: user ID who do the request
:request body: {
- "id": "UUID of the subject",
- "category_id": "UUID of the category"
- "data_id": "UUID of the scope"
+ "id": "UUID of the subject (mandatory)",
+ "category_id": "UUID of the category (mandatory)"
+ "data_id": "UUID of the scope (mandatory)"
}
:return: {
"subject_data_id": {
"policy_id": "ID of the policy",
- "subject_id": "ID of the subject",
- "category_id": "ID of the category",
+ "subject_id": "ID of the subject (mandatory)",
+ "category_id": "ID of the category (mandatory)",
"assignments": "Assignments list (list of data_id)",
}
}
:internal_api: update_subject_assignment
"""
- try:
- data_id = request.json.get("data_id")
- category_id = request.json.get("category_id")
- perimeter_id = request.json.get("id")
- data = PolicyManager.add_subject_assignment(
- user_id=user_id, policy_id=uuid,
- subject_id=perimeter_id, category_id=category_id,
- data_id=data_id)
- except Exception as e:
- logger.error(e, exc_info=True)
- return {"result": False,
- "error": str(e)}, 500
+ data_id = request.json.get("data_id")
+ category_id = request.json.get("category_id")
+ perimeter_id = request.json.get("id")
+ data = PolicyManager.add_subject_assignment(
+ user_id=user_id, policy_id=uuid,
+ subject_id=perimeter_id, category_id=category_id,
+ data_id=data_id)
return {"subject_assignments": data}
+ @validate_input("delete", kwargs_state=[True, True, True, True, False])
@check_auth
- def delete(self, uuid=None, perimeter_id=None, category_id=None,
+ def delete(self, uuid, perimeter_id=None, category_id=None,
data_id=None, user_id=None):
"""Delete a subject assignment for a given policy
@@ -116,15 +112,12 @@ class SubjectAssignments(Resource):
}
:internal_api: delete_subject_assignment
"""
- try:
- data = PolicyManager.delete_subject_assignment(
- user_id=user_id, policy_id=uuid,
- subject_id=perimeter_id, category_id=category_id,
- data_id=data_id)
- except Exception as e:
- logger.error(e, exc_info=True)
- return {"result": False,
- "error": str(e)}, 500
+
+ data = PolicyManager.delete_subject_assignment(
+ user_id=user_id, policy_id=uuid,
+ subject_id=perimeter_id, category_id=category_id,
+ data_id=data_id)
+
return {"result": True}
@@ -141,15 +134,16 @@ class ObjectAssignments(Resource):
"/policies/<string:uuid>/object_assignments/<string:perimeter_id>/<string:category_id>/<string:data_id>",
)
+ @validate_input("get", kwargs_state=[True, False, False,False,False])
@check_auth
- def get(self, uuid=None, perimeter_id=None, category_id=None,
+ def get(self, uuid, perimeter_id=None, category_id=None,
data_id=None, user_id=None):
"""Retrieve all object assignment or a specific one for a given policy
:param uuid: uuid of the policy
:param perimeter_id: uuid of the object
:param category_id: uuid of the object category
- :param data_id: uuid of the object scope
+ :param data_id: uuid of the object scope (not used here)
:param user_id: user ID who do the request
:return: {
"object_data_id": {
@@ -161,18 +155,16 @@ class ObjectAssignments(Resource):
}
:internal_api: get_object_assignments
"""
- try:
- data = PolicyManager.get_object_assignments(
- user_id=user_id, policy_id=uuid,
- object_id=perimeter_id, category_id=category_id)
- except Exception as e:
- logger.error(e, exc_info=True)
- return {"result": False,
- "error": str(e)}, 500
+
+ data = PolicyManager.get_object_assignments(
+ user_id=user_id, policy_id=uuid,
+ object_id=perimeter_id, category_id=category_id)
+
return {"object_assignments": data}
+ @validate_input("post", kwargs_state=[True, False, False, False, False], body_state={"id":True, "category_id":True, "data_id":True})
@check_auth
- def post(self, uuid=None, perimeter_id=None, category_id=None,
+ def post(self, uuid, perimeter_id=None, category_id=None,
data_id=None, user_id=None):
"""Create an object assignment.
@@ -182,9 +174,9 @@ class ObjectAssignments(Resource):
:param data_id: uuid of the object scope (not used here)
:param user_id: user ID who do the request
:request body: {
- "id": "UUID of the action",
- "category_id": "UUID of the category"
- "data_id": "UUID of the scope"
+ "id": "UUID of the action (mandatory)",
+ "category_id": "UUID of the category (mandatory)",
+ "data_id": "UUID of the scope (mandatory)"
}
:return: {
"object_data_id": {
@@ -196,22 +188,20 @@ class ObjectAssignments(Resource):
}
:internal_api: update_object_assignment
"""
- try:
- data_id = request.json.get("data_id")
- category_id = request.json.get("category_id")
- perimeter_id = request.json.get("id")
- data = PolicyManager.add_object_assignment(
- user_id=user_id, policy_id=uuid,
- object_id=perimeter_id, category_id=category_id,
- data_id=data_id)
- except Exception as e:
- logger.error(e, exc_info=True)
- return {"result": False,
- "error": str(e)}, 500
+
+ data_id = request.json.get("data_id")
+ category_id = request.json.get("category_id")
+ perimeter_id = request.json.get("id")
+ data = PolicyManager.add_object_assignment(
+ user_id=user_id, policy_id=uuid,
+ object_id=perimeter_id, category_id=category_id,
+ data_id=data_id)
+
return {"object_assignments": data}
+ @validate_input("delete", kwargs_state=[True, True, True, True, False])
@check_auth
- def delete(self, uuid=None, perimeter_id=None, category_id=None,
+ def delete(self, uuid, perimeter_id=None, category_id=None,
data_id=None, user_id=None):
"""Delete a object assignment for a given policy
@@ -226,15 +216,11 @@ class ObjectAssignments(Resource):
}
:internal_api: delete_object_assignment
"""
- try:
- data = PolicyManager.delete_object_assignment(
- user_id=user_id, policy_id=uuid,
- object_id=perimeter_id, category_id=category_id,
- data_id=data_id)
- except Exception as e:
- logger.error(e, exc_info=True)
- return {"result": False,
- "error": str(e)}, 500
+ data = PolicyManager.delete_object_assignment(
+ user_id=user_id, policy_id=uuid,
+ object_id=perimeter_id, category_id=category_id,
+ data_id=data_id)
+
return {"result": True}
@@ -251,8 +237,9 @@ class ActionAssignments(Resource):
"/policies/<string:uuid>/action_assignments/<string:perimeter_id>/<string:category_id>/<string:data_id>",
)
+ @validate_input("get", kwargs_state=[True, False, False,False,False])
@check_auth
- def get(self, uuid=None, perimeter_id=None, category_id=None,
+ def get(self, uuid, perimeter_id=None, category_id=None,
data_id=None, user_id=None):
"""Retrieve all action assignment or a specific one for a given policy
@@ -271,18 +258,15 @@ class ActionAssignments(Resource):
}
:internal_api: get_action_assignments
"""
- try:
- data = PolicyManager.get_action_assignments(
- user_id=user_id, policy_id=uuid,
- action_id=perimeter_id, category_id=category_id)
- except Exception as e:
- logger.error(e, exc_info=True)
- return {"result": False,
- "error": str(e)}, 500
+ data = PolicyManager.get_action_assignments(
+ user_id=user_id, policy_id=uuid,
+ action_id=perimeter_id, category_id=category_id)
+
return {"action_assignments": data}
+ @validate_input("post", kwargs_state=[True, False, False, False, False], body_state={"id":True, "category_id":True, "data_id":True})
@check_auth
- def post(self, uuid=None, perimeter_id=None, category_id=None,
+ def post(self, uuid, perimeter_id=None, category_id=None,
data_id=None, user_id=None):
"""Create an action assignment.
@@ -292,9 +276,9 @@ class ActionAssignments(Resource):
:param data_id: uuid of the action scope (not used here)
:param user_id: user ID who do the request
:request body: {
- "id": "UUID of the action",
- "category_id": "UUID of the category",
- "data_id": "UUID of the scope"
+ "id": "UUID of the action (mandatory)",
+ "category_id": "UUID of the category (mandatory)",
+ "data_id": "UUID of the scope (mandatory)"
}
:return: {
"action_data_id": {
@@ -306,22 +290,20 @@ class ActionAssignments(Resource):
}
:internal_api: update_action_assignment
"""
- try:
- data_id = request.json.get("data_id")
- category_id = request.json.get("category_id")
- perimeter_id = request.json.get("id")
- data = PolicyManager.add_action_assignment(
- user_id=user_id, policy_id=uuid,
- action_id=perimeter_id, category_id=category_id,
- data_id=data_id)
- except Exception as e:
- logger.error(e, exc_info=True)
- return {"result": False,
- "error": str(e)}, 500
+
+ data_id = request.json.get("data_id")
+ category_id = request.json.get("category_id")
+ perimeter_id = request.json.get("id")
+ data = PolicyManager.add_action_assignment(
+ user_id=user_id, policy_id=uuid,
+ action_id=perimeter_id, category_id=category_id,
+ data_id=data_id)
+
return {"action_assignments": data}
+ @validate_input("delete", kwargs_state=[True, True, True, True, False])
@check_auth
- def delete(self, uuid=None, perimeter_id=None, category_id=None,
+ def delete(self, uuid, perimeter_id=None, category_id=None,
data_id=None, user_id=None):
"""Delete a action assignment for a given policy
@@ -336,13 +318,10 @@ class ActionAssignments(Resource):
}
:internal_api: delete_action_assignment
"""
- try:
- data = PolicyManager.delete_action_assignment(
- user_id=user_id, policy_id=uuid,
- action_id=perimeter_id, category_id=category_id,
- data_id=data_id)
- except Exception as e:
- logger.error(e, exc_info=True)
- return {"result": False,
- "error": str(e)}, 500
+
+ data = PolicyManager.delete_action_assignment(
+ user_id=user_id, policy_id=uuid,
+ action_id=perimeter_id, category_id=category_id,
+ data_id=data_id)
+
return {"result": True}
diff --git a/moon_manager/moon_manager/api/base_exception.py b/moon_manager/moon_manager/api/base_exception.py
new file mode 100644
index 00000000..0af3b6d0
--- /dev/null
+++ b/moon_manager/moon_manager/api/base_exception.py
@@ -0,0 +1,18 @@
+
+class BaseException(Exception):
+ def __init__(self, message):
+ self._code = 500
+ self._message = message
+ # Call the base class constructor with the parameters it needs
+ super(BaseException, self).__init__(message)
+
+ @property
+ def code(self):
+ return self._code
+
+ @property
+ def message(self):
+ return self._message
+
+ def __str__(self):
+ return "Error " + str(self._code) + " " + self.__class__.__name__ + ': ' + self.message \ No newline at end of file
diff --git a/moon_manager/moon_manager/api/data.py b/moon_manager/moon_manager/api/data.py
index b74ca385..d887ac2b 100644
--- a/moon_manager/moon_manager/api/data.py
+++ b/moon_manager/moon_manager/api/data.py
@@ -12,6 +12,7 @@ from flask_restful import Resource
import logging
from python_moonutilities.security_functions import check_auth
from python_moondb.core import PolicyManager
+from python_moonutilities.security_functions import validate_input
__version__ = "4.3.2"
@@ -31,9 +32,10 @@ class SubjectData(Resource):
"<string:data_id>",
)
+ @validate_input("get", kwargs_state=[True, False, False, False])
@check_auth
- def get(self, uuid=None, category_id=None, data_id=None, user_id=None):
- """Retrieve all subject categories or a specific one if sid is given
+ def get(self, uuid, category_id=None, data_id=None, user_id=None):
+ """Retrieve all subject categories or a specific one if data_id is given
for a given policy
:param uuid: uuid of the policy
@@ -46,60 +48,56 @@ class SubjectData(Resource):
"data": {
"subject_data_id": {
"name": "name of the data",
- "description": "description of the data"
+ "description": "description of the data (optional)"
}
}
}]
:internal_api: get_subject_data
"""
- try:
- data = PolicyManager.get_subject_data(user_id=user_id,
- policy_id=uuid,
- category_id=category_id,
- data_id=data_id)
- except Exception as e:
- logger.error(e, exc_info=True)
- return {"result": False,
- "error": str(e)}, 500
+ logger.info("api.get {} {} {}".format(uuid, category_id, data_id))
+ data = PolicyManager.get_subject_data(user_id=user_id,
+ policy_id=uuid,
+ category_id=category_id,
+ data_id=data_id)
+ logger.info("api.get data = {}".format(data))
+
return {"subject_data": data}
+ @validate_input("post", kwargs_state=[True, True, False, False], body_state={"name":True})
@check_auth
- def post(self, uuid=None, category_id=None, data_id=None, user_id=None):
+ def post(self, uuid, category_id=None, data_id=None, user_id=None):
"""Create or update a subject.
:param uuid: uuid of the policy
:param category_id: uuid of the subject category
- :param data_id: uuid of the subject data
+ :param data_id: uuid of the subject data (not used here)
:param user_id: user ID who do the request
:request body: {
- "name": "name of the data",
- "description": "description of the data"
+ "name": "name of the data (mandatory)",
+ "description": "description of the data (optional)"
}
:return: {
"policy_id": "policy_id1",
"category_id": "category_id1",
"data": {
"subject_data_id": {
- "name": "name of the data",
- "description": "description of the data"
+ "name": "name of the data (mandatory)",
+ "description": "description of the data (optional)"
}
}
}
:internal_api: add_subject_data
"""
- try:
- data = PolicyManager.set_subject_data(user_id=user_id,
- policy_id=uuid,
+ data = PolicyManager.set_subject_data(user_id=user_id,
+ policy_id=uuid,
category_id=category_id,
value=request.json)
- except Exception as e:
- logger.error(e, exc_info=True)
- return {"result": False,
- "error": str(e)}, 500
+
return {"subject_data": data}
+ @validate_input("delete", kwargs_state=[True, False, False, False])
@check_auth
- def delete(self, uuid=None, category_id=None, data_id=None, user_id=None):
+ def delete(self, uuid, category_id=None, data_id=None, user_id=None):
"""Delete a subject for a given policy
:param uuid: uuid of the policy
@@ -108,18 +106,15 @@ class SubjectData(Resource):
:param user_id: user ID who do the request
:return: [{
"result": "True or False",
- "message": "optional message"
+ "message": "optional message (optional)"
}]
:internal_api: delete_subject_data
"""
- try:
- data = PolicyManager.delete_subject_data(user_id=user_id,
- policy_id=uuid,
- data_id=data_id)
- except Exception as e:
- logger.error(e, exc_info=True)
- return {"result": False,
- "error": str(e)}, 500
+ logger.info("api.delete {} {}".format(uuid, data_id))
+ data = PolicyManager.delete_subject_data(user_id=user_id,
+ policy_id=uuid,
+ data_id=data_id)
+
return {"result": True}
@@ -136,8 +131,9 @@ class ObjectData(Resource):
"<string:data_id>",
)
+ @validate_input("get", kwargs_state=[True, False, False, False])
@check_auth
- def get(self, uuid=None, category_id=None, data_id=None, user_id=None):
+ def get(self, uuid, category_id=None, data_id=None, user_id=None):
"""Retrieve all object categories or a specific one if sid is given
for a given policy
@@ -151,34 +147,31 @@ class ObjectData(Resource):
"data": {
"object_data_id": {
"name": "name of the data",
- "description": "description of the data"
+ "description": "description of the data (optional)"
}
}
}]
:internal_api: get_object_data
"""
- try:
- data = PolicyManager.get_object_data(user_id=user_id,
- policy_id=uuid,
- category_id=category_id,
- data_id=data_id)
- except Exception as e:
- logger.error(e, exc_info=True)
- return {"result": False,
- "error": str(e)}, 500
+ data = PolicyManager.get_object_data(user_id=user_id,
+ policy_id=uuid,
+ category_id=category_id,
+ data_id=data_id)
+
return {"object_data": data}
+ @validate_input("post", kwargs_state=[True, True, False, False], body_state={"name":True})
@check_auth
- def post(self, uuid=None, category_id=None, data_id=None, user_id=None):
+ def post(self, uuid, category_id=None, data_id=None, user_id=None):
"""Create or update a object.
:param uuid: uuid of the policy
:param category_id: uuid of the object category
- :param data_id: uuid of the object data
+ :param data_id: uuid of the object data (not used here)
:param user_id: user ID who do the request
:request body: {
- "name": "name of the data",
- "description": "description of the data"
+ "name": "name of the data (mandatory)",
+ "description": "description of the data (optional)"
}
:return: {
"policy_id": "policy_id1",
@@ -186,25 +179,22 @@ class ObjectData(Resource):
"data": {
"object_data_id": {
"name": "name of the data",
- "description": "description of the data"
+ "description": "description of the data (optional)"
}
}
}
:internal_api: add_object_data
"""
- try:
- data = PolicyManager.add_object_data(user_id=user_id,
- policy_id=uuid,
- category_id=category_id,
- value=request.json)
- except Exception as e:
- logger.error(e, exc_info=True)
- return {"result": False,
- "error": str(e)}, 500
+ data = PolicyManager.add_object_data(user_id=user_id,
+ policy_id=uuid,
+ category_id=category_id,
+ value=request.json)
+
return {"object_data": data}
+ @validate_input("delete", kwargs_state=[True, False, False, False])
@check_auth
- def delete(self, uuid=None, category_id=None, data_id=None, user_id=None):
+ def delete(self, uuid, category_id=None, data_id=None, user_id=None):
"""Delete a object for a given policy
:param uuid: uuid of the policy
@@ -213,18 +203,14 @@ class ObjectData(Resource):
:param user_id: user ID who do the request
:return: {
"result": "True or False",
- "message": "optional message"
+ "message": "optional message (optional)"
}
:internal_api: delete_object_data
"""
- try:
- data = PolicyManager.delete_object_data(user_id=user_id,
- policy_id=uuid,
- data_id=data_id)
- except Exception as e:
- logger.error(e, exc_info=True)
- return {"result": False,
- "error": str(e)}, 500
+ data = PolicyManager.delete_object_data(user_id=user_id,
+ policy_id=uuid,
+ data_id=data_id)
+
return {"result": True}
@@ -241,8 +227,9 @@ class ActionData(Resource):
"<string:data_id>",
)
+ @validate_input("get", kwargs_state=[True, False, False, False])
@check_auth
- def get(self, uuid=None, category_id=None, data_id=None, user_id=None):
+ def get(self, uuid, category_id=None, data_id=None, user_id=None):
"""Retrieve all action categories or a specific one if sid is given
for a given policy
@@ -256,25 +243,22 @@ class ActionData(Resource):
"data": {
"action_data_id": {
"name": "name of the data",
- "description": "description of the data"
+ "description": "description of the data (optional)"
}
}
}]
:internal_api: get_action_data
"""
- try:
- data = PolicyManager.get_action_data(user_id=user_id,
- policy_id=uuid,
- category_id=category_id,
- data_id=data_id)
- except Exception as e:
- logger.error(e, exc_info=True)
- return {"result": False,
- "error": str(e)}, 500
+ data = PolicyManager.get_action_data(user_id=user_id,
+ policy_id=uuid,
+ category_id=category_id,
+ data_id=data_id)
+
return {"action_data": data}
+ @validate_input("post", kwargs_state=[True, True, False, False], body_state={"name":True})
@check_auth
- def post(self, uuid=None, category_id=None, data_id=None, user_id=None):
+ def post(self, uuid, category_id=None, data_id=None, user_id=None):
"""Create or update a action.
:param uuid: uuid of the policy
@@ -282,8 +266,8 @@ class ActionData(Resource):
:param data_id: uuid of the action data
:param user_id: user ID who do the request
:request body: {
- "name": "name of the data",
- "description": "description of the data"
+ "name": "name of the data (mandatory)",
+ "description": "description of the data (optional)"
}
:return: {
"policy_id": "policy_id1",
@@ -291,25 +275,21 @@ class ActionData(Resource):
"data": {
"action_data_id": {
"name": "name of the data",
- "description": "description of the data"
+ "description": "description of the data (optional)"
}
}
}
:internal_api: add_action_data
"""
- try:
- data = PolicyManager.add_action_data(user_id=user_id,
- policy_id=uuid,
- category_id=category_id,
- value=request.json)
- except Exception as e:
- logger.error(e, exc_info=True)
- return {"result": False,
- "error": str(e)}, 500
+ data = PolicyManager.add_action_data(user_id=user_id,
+ policy_id=uuid,
+ category_id=category_id,
+ value=request.json)
return {"action_data": data}
+ @validate_input("delete", kwargs_state=[True, False, False, False])
@check_auth
- def delete(self, uuid=None, category_id=None, data_id=None, user_id=None):
+ def delete(self, uuid, category_id=None, data_id=None, user_id=None):
"""Delete a action for a given policy
:param uuid: uuid of the policy
@@ -318,18 +298,14 @@ class ActionData(Resource):
:param user_id: user ID who do the request
:return: {
"result": "True or False",
- "message": "optional message"
+ "message": "optional message (optional)"
}
:internal_api: delete_action_data
"""
- try:
- data = PolicyManager.delete_action_data(user_id=user_id,
- policy_id=uuid,
- data_id=data_id)
- except Exception as e:
- logger.error(e, exc_info=True)
- return {"result": False,
- "error": str(e)}, 500
+ data = PolicyManager.delete_action_data(user_id=user_id,
+ policy_id=uuid,
+ data_id=data_id)
+
return {"result": True}
diff --git a/moon_manager/moon_manager/api/json_export.py b/moon_manager/moon_manager/api/json_export.py
new file mode 100644
index 00000000..1d3643e7
--- /dev/null
+++ b/moon_manager/moon_manager/api/json_export.py
@@ -0,0 +1,238 @@
+# Copyright 2018 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 flask_restful import Resource
+from python_moonutilities.security_functions import check_auth
+from python_moondb.core import PDPManager
+from python_moondb.core import PolicyManager
+from python_moondb.core import ModelManager
+from moon_manager.api.json_utils import JsonUtils, BaseException
+
+__version__ = "4.5.0"
+
+logger = logging.getLogger("moon.manager.api." + __name__)
+
+
+class JsonExport(Resource):
+
+ __urls__ = (
+ "/export",
+ "/export/",
+ )
+
+ def _export_rules(self, json_content):
+ policies = PolicyManager.get_policies(self._user_id)
+ rules_array = []
+
+ for policy_key in policies:
+ rules = PolicyManager.get_rules(self._user_id, policy_key)
+ rules = rules["rules"]
+ # logger.info(rules)
+ for rule in rules:
+ rule_dict = dict()
+ JsonUtils.copy_field_if_exists(rule, rule_dict, "instructions", dict)
+ JsonUtils.copy_field_if_exists(rule, rule_dict, "enabled", True)
+ JsonUtils.convert_id_to_name(rule["meta_rule_id"], rule_dict, "meta_rule", "meta_rule", ModelManager, self._user_id)
+ JsonUtils.convert_id_to_name(policy_key, rule_dict, "policy", "policy", PolicyManager, self._user_id)
+ ids = rule["rule"]
+ rule_description = dict()
+ meta_rule = ModelManager.get_meta_rules(self._user_id, rule["meta_rule_id"])
+ meta_rule = [v for v in meta_rule.values()]
+ meta_rule = meta_rule[0]
+ index_subject_data = len(meta_rule["subject_categories"])-1
+ index_object_data = len(meta_rule["subject_categories"]) + len(meta_rule["object_categories"])-1
+ index_action_data = len(meta_rule["subject_categories"]) + len(meta_rule["object_categories"]) + len(meta_rule["action_categories"])-1
+ ids_subject_data = [ids[0]] if len(meta_rule["subject_categories"]) == 1 else ids[0:index_subject_data]
+ ids_object_data = [ids[index_object_data]] if len(meta_rule["object_categories"]) == 1 else ids[index_subject_data+1:index_object_data]
+ ids_action_date = [ids[index_action_data]] if len(meta_rule["action_categories"]) == 1 else ids[index_object_data+1:index_action_data]
+ JsonUtils.convert_ids_to_names(ids_subject_data, rule_description, "subject_data", "subject_data", PolicyManager, self._user_id, policy_key)
+ JsonUtils.convert_ids_to_names(ids_object_data, rule_description, "object_data", "object_data", PolicyManager, self._user_id, policy_key)
+ JsonUtils.convert_ids_to_names(ids_action_date, rule_description, "action_data", "action_data", PolicyManager, self._user_id, policy_key)
+ rule_dict["rule"] = rule_description
+ rules_array.append(rule_dict)
+
+ if len(rules_array) > 0:
+ json_content['rules'] = rules_array
+
+ def _export_meta_rules(self, json_content):
+ meta_rules = ModelManager.get_meta_rules(self._user_id)
+ meta_rules_array = []
+ # logger.info(meta_rules)
+ for meta_rule_key in meta_rules:
+ #logger.info(meta_rules[meta_rule_key])
+ meta_rule_dict = dict()
+ JsonUtils.copy_field_if_exists(meta_rules[meta_rule_key], meta_rule_dict, "name", str)
+ JsonUtils.copy_field_if_exists(meta_rules[meta_rule_key], meta_rule_dict, "description", str)
+ JsonUtils.convert_ids_to_names(meta_rules[meta_rule_key]["subject_categories"], meta_rule_dict, "subject_categories", "subject_category", ModelManager, self._user_id)
+ JsonUtils.convert_ids_to_names(meta_rules[meta_rule_key]["object_categories"], meta_rule_dict, "object_categories", "object_category", ModelManager, self._user_id)
+ JsonUtils.convert_ids_to_names(meta_rules[meta_rule_key]["action_categories"], meta_rule_dict, "action_categories", "action_category", ModelManager, self._user_id)
+ logger.info("Exporting meta rule {}".format(meta_rule_dict))
+ meta_rules_array.append(meta_rule_dict)
+ if len(meta_rules_array) > 0:
+ json_content['meta_rules'] = meta_rules_array
+
+ def _export_subject_object_action_assignments(self, type_element, json_content):
+ export_method_data = getattr(PolicyManager, 'get_' + type_element + '_assignments')
+ policies = PolicyManager.get_policies(self._user_id)
+ element_assignments_array = []
+ for policy_key in policies:
+ assignments = export_method_data(self._user_id, policy_key)
+ #logger.info(assignments)
+ for assignment_key in assignments:
+ assignment_dict = dict()
+ JsonUtils.convert_id_to_name(assignments[assignment_key][type_element + "_id"], assignment_dict, type_element, type_element , PolicyManager, self._user_id, policy_key)
+ JsonUtils.convert_id_to_name(assignments[assignment_key]["category_id"], assignment_dict, "category", type_element + "_category", ModelManager, self._user_id, policy_key)
+ JsonUtils.convert_ids_to_names(assignments[assignment_key]["assignments"], assignment_dict, "assignments", type_element + "_data", PolicyManager, self._user_id, policy_key)
+ element_assignments_array.append(assignment_dict)
+ logger.info("Exporting {} assignment {}".format(type_element, assignment_dict))
+ if len(element_assignments_array) > 0:
+ json_content[type_element + '_assignments'] = element_assignments_array
+
+ def _export_subject_object_action_datas(self, type_element, json_content):
+ export_method_data = getattr(PolicyManager, 'get_' + type_element + '_data')
+ policies = PolicyManager.get_policies(self._user_id)
+ element_datas_array = []
+ for policy_key in policies:
+ datas = export_method_data(self._user_id, policy_key)
+ #logger.info("data found : {}".format(datas))
+ for data_group in datas:
+ policy_id = data_group["policy_id"]
+ category_id = data_group["category_id"]
+ # logger.info(data_group["data"])
+ for data_key in data_group["data"]:
+ data_dict = dict()
+ if type_element == 'subject':
+ JsonUtils.copy_field_if_exists(data_group["data"][data_key], data_dict, "name", str)
+ JsonUtils.copy_field_if_exists(data_group["data"][data_key], data_dict, "description", str)
+ else:
+ JsonUtils.copy_field_if_exists(data_group["data"][data_key], data_dict, "name", str)
+ JsonUtils.copy_field_if_exists(data_group["data"][data_key], data_dict, "description", str)
+
+ JsonUtils.convert_id_to_name(policy_id, data_dict, "policy", "policy", PolicyManager, self._user_id)
+ JsonUtils.convert_id_to_name(category_id, data_dict, "category", type_element + "_category", ModelManager, self._user_id, policy_key)
+ logger.info("Exporting {} data {}".format(type_element, data_dict))
+ element_datas_array.append(data_dict)
+
+ if len(element_datas_array) > 0:
+ json_content[type_element + '_data'] = element_datas_array
+
+ def _export_subject_object_action_categories(self, type_element, json_content):
+ export_method = getattr(ModelManager, 'get_' + type_element + '_categories')
+ element_categories = export_method(self._user_id)
+ element_categories_array = []
+ for element_category_key in element_categories:
+ element_category = dict()
+ JsonUtils.copy_field_if_exists(element_categories[element_category_key], element_category, "name", str)
+ JsonUtils.copy_field_if_exists(element_categories[element_category_key], element_category, "description", str)
+ element_categories_array.append(element_category)
+ logger.info("Exporting {} category {}".format(type_element, element_category))
+ if len(element_categories_array) > 0:
+ json_content[type_element + '_categories'] = element_categories_array
+
+ def _export_subject_object_action(self, type_element, json_content):
+ export_method = getattr(PolicyManager, 'get_' + type_element + 's')
+ policies = PolicyManager.get_policies(self._user_id)
+ element_dict = dict()
+ elements_array = []
+ for policy_key in policies:
+ elements = export_method(self._user_id, policy_key)
+ for element_key in elements:
+ #logger.info("Exporting {}".format(elements[element_key]))
+ element = dict()
+ JsonUtils.copy_field_if_exists(elements[element_key], element, "name", str)
+ JsonUtils.copy_field_if_exists(elements[element_key], element, "description", str)
+ JsonUtils.copy_field_if_exists(elements[element_key], element, "extra", dict)
+ if element["name"] not in element_dict:
+ element["policies"] = []
+ element_dict[element["name"]] = element
+ current_element = element_dict[element["name"]]
+ current_element["policies"].append({"name": JsonUtils.convert_id_to_name_string(policy_key, "policy", PolicyManager, self._user_id)})
+
+ for key in element_dict:
+ logger.info("Exporting {} {}".format(type_element, element_dict[key]))
+ elements_array.append(element_dict[key])
+
+ if len(elements_array) > 0:
+ json_content[type_element + 's'] = elements_array
+
+ def _export_policies(self, json_content):
+ policies = PolicyManager.get_policies(self._user_id)
+ policies_array = []
+ for policy_key in policies:
+ policy = dict()
+ JsonUtils.copy_field_if_exists(policies[policy_key], policy, "name", str)
+ JsonUtils.copy_field_if_exists(policies[policy_key], policy, "genre", str)
+ JsonUtils.copy_field_if_exists(policies[policy_key], policy, "description", str)
+ JsonUtils.convert_id_to_name(policies[policy_key]["model_id"], policy, "model", "model", ModelManager, self._user_id)
+ logger.info("Exporting policy {}".format(policy))
+ policies_array.append(policy)
+ if len(policies_array) > 0:
+ json_content["policies"] = policies_array
+
+ def _export_models(self, json_content):
+ models = ModelManager.get_models(self._user_id)
+ models_array = []
+ for model_key in models:
+ model = dict()
+ JsonUtils.copy_field_if_exists(models[model_key], model, "name", str)
+ JsonUtils.copy_field_if_exists(models[model_key], model, "description", str)
+ # logger.info(models[model_key]["meta_rules"])
+ JsonUtils.convert_ids_to_names(models[model_key]["meta_rules"], model, "meta_rules", "meta_rule", ModelManager, self._user_id)
+ logger.info("Exporting model {}".format(model))
+ models_array.append(model)
+ if len(models_array) > 0:
+ json_content["models"] = models_array
+
+ def _export_pdps(self, json_content):
+ pdps = PDPManager.get_pdp(self._user_id)
+ pdps_array = []
+ for pdp_key in pdps:
+ logger.info("Exporting pdp {}".format(pdps[pdp_key]))
+ pdps_array.append(pdps[pdp_key])
+ if len(pdps_array) > 0:
+ json_content["pdps"] = pdps_array
+
+ def _export_json(self, user_id):
+ self._user_id = user_id
+ json_content = dict()
+
+ logger.info("Exporting pdps...")
+ self._export_pdps(json_content)
+ logger.info("Exporting policies...")
+ self._export_policies(json_content)
+ logger.info("Exporting models...")
+ self._export_models(json_content)
+ # export subjects, subject_data, subject_categories, subject_assignements idem for object and action
+ list_element = [{"key": "subject"}, {"key": "object"}, {"key": "action"}]
+ for elt in list_element:
+ logger.info("Exporting {}s...".format(elt["key"]))
+ self._export_subject_object_action(elt["key"], json_content)
+ logger.info("Exporting {} categories...".format(elt["key"]))
+ self._export_subject_object_action_categories(elt["key"], json_content)
+ logger.info("Exporting {} data...".format(elt["key"]))
+ self._export_subject_object_action_datas(elt["key"], json_content)
+ logger.info("Exporting {} assignments...".format(elt["key"]))
+ self._export_subject_object_action_assignments(elt["key"], json_content)
+ logger.info("Exporting meta rules...")
+ self._export_meta_rules(json_content)
+ logger.info("Exporting rules...")
+ self._export_rules(json_content)
+
+ return json_content
+
+ @check_auth
+ def get(self, user_id=None):
+ """Import file.
+
+ :param user_id: user ID who do the request
+ :return: {
+
+ }
+ :internal_api:
+ """
+ json_file = self._export_json(user_id)
+ logger.info(json_file)
+ return {"content": json_file}
diff --git a/moon_manager/moon_manager/api/json_import.py b/moon_manager/moon_manager/api/json_import.py
new file mode 100644
index 00000000..e57a27c1
--- /dev/null
+++ b/moon_manager/moon_manager/api/json_import.py
@@ -0,0 +1,524 @@
+# 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'.
+
+from flask import request
+from flask_restful import Resource
+import flask_restful
+from flask import abort
+
+from python_moonutilities.security_functions import check_auth
+from python_moonutilities import exceptions
+import logging
+import json
+
+from moon_manager.api.base_exception import BaseException
+from moon_manager.api.json_utils import JsonUtils, UnknownName
+from python_moondb.core import PDPManager
+from python_moondb.core import PolicyManager
+from python_moondb.core import ModelManager
+
+
+__version__ = "4.5.0"
+
+logger = logging.getLogger("moon.manager.api." + __name__)
+
+INST_CALLBACK = 0
+DATA_CALLBACK = 1
+ASSIGNMENT_CALLBACK = 2
+CATEGORIES_CALLBACK = 3
+
+
+class ForbiddenOverride(BaseException):
+ def __init__(self, message):
+
+ # Call the base class constructor with the parameters it needs
+ super(ForbiddenOverride, self).__init__(message)
+
+
+class UnknownPolicy(BaseException):
+ def __init__(self, message):
+
+ # Call the base class constructor with the parameters it needs
+ super(UnknownPolicy, self).__init__(message)
+
+
+class UnknownModel(BaseException):
+ def __init__(self, message):
+
+ # Call the base class constructor with the parameters it needs
+ super(UnknownModel, self).__init__(message)
+
+
+class UnknownData(BaseException):
+ def __init__(self, message):
+
+ # Call the base class constructor with the parameters it needs
+ super(UnknownData, self).__init__(message)
+
+
+class MissingPolicy(BaseException):
+ def __init__(self, message):
+
+ # Call the base class constructor with the parameters it needs
+ super(MissingPolicy, self).__init__(message)
+
+
+class InvalidJson(BaseException):
+ def __init__(self, message):
+
+ # Call the base class constructor with the parameters it needs
+ super(InvalidJson, self).__init__(message)
+
+
+class JsonImport(Resource):
+
+ __urls__ = (
+ "/import",
+ "/import/",
+ )
+
+ def _reorder_rules_ids(self, rule, ordered_perimeter_categories_ids, json_data_ids, policy_id, get_function):
+ ordered_json_ids = [None]*len(ordered_perimeter_categories_ids)
+ for json_id in json_data_ids:
+ data = get_function(self._user_id, policy_id, data_id=json_id)
+ data = data[0]
+ if data["category_id"] not in ordered_perimeter_categories_ids:
+ raise InvalidJson("The category id {} of the rule {} does not match the meta rule".format(
+ data["category_id"], rule))
+ if ordered_json_ids[ordered_perimeter_categories_ids.index(data["category_id"])] is not None:
+ raise InvalidJson("The category id {} of the rule {} shall not be used twice in the same rule".format(
+ data["category_id"], rule))
+ ordered_json_ids[ordered_perimeter_categories_ids.index(data["category_id"])] = json_id
+ logger.info(ordered_json_ids)
+ return ordered_json_ids
+
+ def _import_rules(self, json_rules):
+ if not isinstance(json_rules, list):
+ raise InvalidJson("rules shall be a list!")
+
+ for json_rule in json_rules:
+ json_to_use = dict()
+ JsonUtils.copy_field_if_exists(json_rule, json_to_use, "instructions", str)
+ JsonUtils.copy_field_if_exists(json_rule, json_to_use, "enabled", bool, default_value=True)
+
+ json_ids = dict()
+ JsonUtils.convert_name_to_id(json_rule, json_ids, "policy", "policy_id", "policy",
+ PolicyManager, self._user_id)
+ JsonUtils.convert_name_to_id(json_rule, json_to_use, "meta_rule", "meta_rule_id", "meta_rule", ModelManager, self._user_id)
+ json_subject_ids = dict()
+ json_object_ids = dict()
+ json_action_ids = dict()
+ JsonUtils.convert_names_to_ids(json_rule["rule"], json_subject_ids, "subject_data", "subject", "subject_data", PolicyManager, self._user_id, json_ids["policy_id"])
+ JsonUtils.convert_names_to_ids(json_rule["rule"], json_object_ids, "object_data", "object", "object_data", PolicyManager, self._user_id, json_ids["policy_id"])
+ JsonUtils.convert_names_to_ids(json_rule["rule"], json_action_ids, "action_data", "action", "action_data", PolicyManager, self._user_id, json_ids["policy_id"])
+
+ meta_rule = ModelManager.get_meta_rules(self._user_id, json_to_use["meta_rule_id"])
+ meta_rule = [v for v in meta_rule.values()]
+ meta_rule = meta_rule[0]
+
+ json_to_use_rule = self._reorder_rules_ids(json_rule, meta_rule["subject_categories"], json_subject_ids["subject"], json_ids["policy_id"], PolicyManager.get_subject_data)
+ json_to_use_rule = json_to_use_rule + self._reorder_rules_ids(json_rule, meta_rule["object_categories"], json_object_ids["object"], json_ids["policy_id"], PolicyManager.get_object_data)
+ json_to_use_rule = json_to_use_rule + self._reorder_rules_ids(json_rule, meta_rule["action_categories"], json_action_ids["action"], json_ids["policy_id"], PolicyManager.get_action_data)
+ json_to_use["rule"] = json_to_use_rule
+ try:
+ logger.debug("Adding / updating a rule from json {}".format(json_to_use))
+ PolicyManager.add_rule(self._user_id, json_ids["policy_id"], json_to_use["meta_rule_id"], json_to_use)
+ except exceptions.RuleExisting:
+ pass
+ except exceptions.PolicyUnknown:
+ raise UnknownPolicy("Unknown policy with id {}".format(json_ids["policy_id"]))
+
+ def _import_meta_rules(self, json_meta_rules):
+ logger.info("Input meta rules : {}".format(json_meta_rules))
+ for json_meta_rule in json_meta_rules:
+ json_to_use = dict()
+ JsonUtils.copy_field_if_exists(json_meta_rule, json_to_use, "name", str)
+ JsonUtils.copy_field_if_exists(json_meta_rule, json_to_use, "description", str)
+ JsonUtils.convert_names_to_ids(json_meta_rule, json_to_use, "subject_categories", "subject_categories", "subject_category", ModelManager, self._user_id)
+ JsonUtils.convert_names_to_ids(json_meta_rule, json_to_use, "object_categories", "object_categories", "object_category", ModelManager, self._user_id)
+ JsonUtils.convert_names_to_ids(json_meta_rule, json_to_use, "action_categories", "action_categories", "action_category", ModelManager, self._user_id)
+ logger.debug("Adding / updating a metarule from json {}".format(json_meta_rule))
+ meta_rule = ModelManager.add_meta_rule(self._user_id, meta_rule_id=None, value=json_to_use)
+ logger.debug("Added / updated meta rule : {}".format(meta_rule))
+
+ def _import_subject_object_action_assignments(self, json_item_assignments, type_element):
+ import_method = getattr(PolicyManager, 'add_' + type_element + '_assignment')
+ get_method = getattr(PolicyManager, 'get_' + type_element + '_data')
+
+ if not isinstance(json_item_assignments, list):
+ raise InvalidJson(type_element + " assignments shall be a list!")
+
+ # get the policy id related to the user
+ policies = PolicyManager.get_policies(self._user_id)
+
+ for json_item_assignment in json_item_assignments:
+ item_override = JsonUtils.get_override(json_item_assignment)
+ if item_override is True:
+ raise ForbiddenOverride("{} assignments do not support override flag !".format(type_element))
+
+ json_assignment = dict()
+ JsonUtils.convert_name_to_id(json_item_assignment, json_assignment, "category", "category_id", type_element + "_category", ModelManager, self._user_id)
+
+ has_found_data = False
+ # loop over policies
+ for policy_id in policies:
+ json_data = dict()
+ try:
+ JsonUtils.convert_name_to_id(json_item_assignment, json_assignment, type_element, "id", type_element, PolicyManager, self._user_id, policy_id)
+ JsonUtils.convert_names_to_ids(json_item_assignment, json_data, "assignments", "data_id", type_element + "_data", PolicyManager, self._user_id, policy_id, json_assignment["category_id"])
+ has_found_data = True
+ except UnknownName:
+ # the category or data has not been found in this policy : we look into the next one
+ continue
+ for data_id in json_data["data_id"]:
+ # find the policy related to the current data
+ data = get_method(self._user_id, policy_id, data_id, json_assignment["category_id"])
+ if data is not None and len(data) == 1:
+ logger.debug("Adding / updating a {} assignment from json {}".format(type_element,
+ json_assignment))
+ import_method(self._user_id, policy_id, json_assignment["id"], json_assignment["category_id"],
+ data_id)
+ else:
+ raise UnknownData("Unknown data with id {}".format(data_id))
+
+ # case the data has not been found in any policies
+ if has_found_data is False:
+ raise InvalidJson("The json contains unknown {} data or category : {}".format(
+ type_element,
+ json_item_assignment))
+
+ def _import_subject_object_action_datas(self, json_items_data, mandatory_policy_ids, type_element):
+ if type_element == "subject":
+ import_method = getattr(PolicyManager, 'set_' + type_element + '_data')
+ else:
+ import_method = getattr(PolicyManager, 'add_' + type_element + '_data')
+ # get_method = getattr(PolicyManager, 'get_' + type_element + '_data')
+
+ if not isinstance(json_items_data, list):
+ raise InvalidJson(type_element + " data shall be a list!")
+
+ for json_item_data in json_items_data:
+ item_override = JsonUtils.get_override(json_items_data)
+ if item_override is True:
+ raise ForbiddenOverride("{} datas do not support override flag !".format(type_element))
+ json_to_use = dict()
+ JsonUtils.copy_field_if_exists(json_item_data, json_to_use, "name", str)
+ JsonUtils.copy_field_if_exists(json_item_data, json_to_use, "description", str)
+ json_policy = dict()
+ # field_mandatory : not mandatory if there is some mandatory policies
+ JsonUtils.convert_names_to_ids(json_item_data, json_policy, "policies", "policy_id", "policy",
+ PolicyManager, self._user_id, field_mandatory=len(mandatory_policy_ids) == 0)
+ json_category = dict()
+ JsonUtils.convert_name_to_id(json_item_data, json_category, "category", "category_id", type_element+"_category",
+ ModelManager, self._user_id)
+ policy_ids = []
+ if "policy_id" in json_policy:
+ policy_ids = json_policy["policy_id"]
+
+ for policy_id in policy_ids:
+ if policy_id is not None and policy_id not in mandatory_policy_ids:
+ mandatory_policy_ids.append(policy_id)
+
+ if len(mandatory_policy_ids) == 0:
+ raise InvalidJson("Invalid data, the policy shall be set when importing {}".format(json_item_data))
+ category_id = None
+ if "category_id" in json_category:
+ category_id = json_category["category_id"]
+ if category_id is None:
+ raise InvalidJson("Invalid data, the category shall be set when importing {}".format(json_item_data))
+
+ for policy_id in mandatory_policy_ids:
+ try:
+ data = import_method(self._user_id, policy_id, category_id=category_id, value=json_to_use)
+ except exceptions.PolicyUnknown:
+ raise UnknownPolicy("Unknown policy with id {}".format(policy_id))
+ except Exception as e:
+ logger.exception(str(e))
+ raise e
+
+ def _import_subject_object_action_categories(self, json_item_categories, type_element):
+ import_method = getattr(ModelManager, 'add_' + type_element + '_category')
+ get_method = getattr(ModelManager, 'get_' + type_element + '_categories')
+
+ categories = get_method(self._user_id)
+
+ if not isinstance(json_item_categories, list):
+ raise InvalidJson(type_element + " categories shall be a list!")
+
+ for json_item_category in json_item_categories:
+ json_to_use = dict()
+ JsonUtils.copy_field_if_exists(json_item_category, json_to_use, "name", str)
+
+ # check if category with the same name exists : do this in moondb ?
+ existing_id = None
+ for category_key in categories:
+ if categories[category_key]["name"] == json_to_use["name"]:
+ existing_id = category_key
+
+ JsonUtils.copy_field_if_exists(json_item_category, json_to_use, "description", str)
+ item_override = JsonUtils.get_override(json_item_category)
+ if item_override is True:
+ raise ForbiddenOverride("{} categories do not support override flag !".format(type_element))
+
+ try:
+ category = import_method(self._user_id, existing_id, json_to_use)
+ except (exceptions.SubjectCategoryExisting, exceptions.ObjectCategoryExisting, exceptions.ActionCategoryExisting):
+ # it already exists: do nothing
+ logger.warning("Ignored {} category with name {} is already in the database".format(type_element, json_to_use["name"]))
+ except Exception as e:
+ logger.warning("Error while importing the category : {}".format(str(e)))
+ logger.exception(str(e))
+ raise e
+
+ def _import_subject_object_action(self, json_items, mandatory_policy_ids, type_element):
+ import_method = getattr(PolicyManager, 'add_' + type_element)
+ get_method = getattr(PolicyManager, 'get_' + type_element + 's')
+
+ if not isinstance(json_items, list):
+ raise InvalidJson(type_element + " items shall be a list!")
+
+ for json_item in json_items:
+ json_without_policy_name = dict()
+ JsonUtils.copy_field_if_exists(json_item, json_without_policy_name, "name", str)
+ JsonUtils.copy_field_if_exists(json_item, json_without_policy_name, "description", str)
+ JsonUtils.copy_field_if_exists(json_item, json_without_policy_name, "extra", dict)
+ JsonUtils.convert_names_to_ids(json_item, json_without_policy_name, "policies", "policy_list", "policy", PolicyManager, self._user_id, field_mandatory=False)
+ policy_ids = json_without_policy_name["policy_list"]
+ for mandatory_policy_id in mandatory_policy_ids:
+ if mandatory_policy_id not in policy_ids:
+ policy_ids.append(mandatory_policy_id)
+ # policy_ids and json_without_policy_name are references to the same array...
+ # json_without_policy_name["policy_list"].append(mandatory_policy_id)
+
+ item_override = JsonUtils.get_override(json_item)
+ if item_override is True:
+ raise ForbiddenOverride("{} does not support override flag !".format(type_element))
+
+ if len(policy_ids) == 0:
+ raise MissingPolicy("a {} needs at least one policy to be created or updated : {}".format(type_element, json.dumps(json_item)))
+
+ for policy_id in policy_ids:
+ try:
+ items_in_db = get_method(self._user_id, policy_id)
+ key = None
+ for key_in_db in items_in_db:
+ if items_in_db[key_in_db]["name"] == json_without_policy_name["name"]:
+ key = key_in_db
+ break
+ element = import_method(self._user_id, policy_id, perimeter_id=key, value=json_without_policy_name)
+ logger.debug("Added / updated {} : {}".format(type_element, element))
+
+ except exceptions.PolicyUnknown:
+ raise UnknownPolicy("Unknown policy when adding a {}!".format(type_element))
+ except Exception as e:
+ logger.exception(str(e))
+ raise BaseException(str(e))
+
+ def _import_policies(self, json_policies):
+ policy_mandatory_ids = []
+
+ if not isinstance(json_policies, list):
+ raise InvalidJson("policies shall be a list!")
+
+ for json_policy in json_policies:
+ # TODO put this in moondb
+ # policy_in_db = PolicyManager.get_policies_by_name(json_without_model_name["name"])
+ policies = PolicyManager.get_policies(self._user_id)
+ policy_in_db = None
+ policy_id = None
+ for policy_key in policies:
+ if policies[policy_key]["name"] == json_policy["name"]:
+ policy_in_db = policies[policy_key]
+ policy_id = policy_key
+ # end TODO
+ if policy_in_db is None:
+ policy_does_exist = False
+ else:
+ policy_does_exist = True
+
+ policy_override = JsonUtils.get_override(json_policy)
+ policy_mandatory = JsonUtils.get_mandatory(json_policy)
+
+ if policy_override is False and policy_does_exist:
+ if policy_id:
+ policy_mandatory_ids.append(policy_id)
+ logger.warning("Existing policy not updated because of the override option is not set !")
+ continue
+
+ json_without_model_name = dict()
+ JsonUtils.copy_field_if_exists(json_policy, json_without_model_name, "name", str)
+ JsonUtils.copy_field_if_exists(json_policy, json_without_model_name, "description", str)
+ JsonUtils.copy_field_if_exists(json_policy, json_without_model_name, "genre", str)
+ JsonUtils.convert_name_to_id(json_policy, json_without_model_name, "model", "model_id", "model", ModelManager, self._user_id, field_mandatory=False)
+
+ if not policy_does_exist:
+ logger.debug("Creating policy {} ".format(json_without_model_name))
+ added_policy = PolicyManager.add_policy(self._user_id, None, json_without_model_name)
+ if policy_mandatory is True:
+ keys = list(added_policy.keys())
+ policy_mandatory_ids.append(keys[0])
+ elif policy_override is True:
+ logger.debug("Updating policy {} ".format(json_without_model_name))
+ updated_policy = PolicyManager.update_policy(self._user_id, policy_id, json_without_model_name)
+ if policy_mandatory is True:
+ policy_mandatory_ids.append(policy_id)
+ return policy_mandatory_ids
+
+ def _import_models_with_new_meta_rules(self, json_models):
+ if not isinstance(json_models, list):
+ raise InvalidJson("models shall be a list!")
+
+ for json_model in json_models:
+ logger.debug("json_model {}".format(json_model))
+ models = ModelManager.get_models(self._user_id)
+ model_in_db = None
+ model_id = None
+ for model_key in models:
+ if ("id" in json_model and model_key == json_model["id"]) or ("name" in json_model and models[model_key]["name"] == json_model["name"]):
+ model_in_db = models[model_key]
+ model_id = model_key
+
+ # this should not occur as the model has been put in db previously in _import_models_without_new_meta_rules
+ if model_in_db is None:
+ raise UnknownModel("Unknown model ")
+
+ json_key = dict()
+ JsonUtils.convert_names_to_ids(json_model, json_key, "meta_rules", "meta_rule_id", "meta_rule", ModelManager, self._user_id)
+ for meta_rule_id in json_key["meta_rule_id"]:
+ if meta_rule_id not in model_in_db["meta_rules"]:
+ model_in_db["meta_rules"].append(meta_rule_id)
+
+ ModelManager.update_model(self._user_id, model_id, model_in_db)
+
+ def _import_models_without_new_meta_rules(self, json_models):
+ if not isinstance(json_models, list):
+ raise InvalidJson("models shall be a list!")
+
+ for json_model in json_models:
+ json_without_new_metarules = dict()
+ JsonUtils.copy_field_if_exists(json_model, json_without_new_metarules, "name", str)
+
+ # TODO put this in moondb
+ # model_in_db = ModelManager.get_models_by_name(json_without_new_metarules["name"])
+ models = ModelManager.get_models(self._user_id)
+ model_in_db = None
+ for model_key in models:
+ if models[model_key]["name"] == json_without_new_metarules["name"]:
+ model_in_db = models[model_key]
+ model_id = model_key
+ # end TODO
+
+ JsonUtils.copy_field_if_exists(json_model, json_without_new_metarules, "description", str)
+ if model_in_db is None:
+ model_does_exist = False
+ else:
+ json_without_new_metarules["meta_rule_id"] = model_in_db["meta_rules"]
+ model_does_exist = True
+ model_override = JsonUtils.get_override(json_model)
+ if not model_does_exist:
+ logger.debug("Creating model {} ".format(json_without_new_metarules))
+ ModelManager.add_model(self._user_id, None, json_without_new_metarules)
+ elif model_override is True:
+ logger.debug("Updating model with id {} : {} ".format(model_id, json_without_new_metarules))
+ ModelManager.update_model(self._user_id, model_id, json_without_new_metarules)
+
+ def _import_pdps(self, json_pdps):
+ if not isinstance(json_pdps, list):
+ raise InvalidJson("pdps shall be a list!")
+
+ for json_pdp in json_pdps:
+ json_to_use = dict()
+ JsonUtils.copy_field_if_exists(json_pdp, json_to_use, "name", str)
+ JsonUtils.copy_field_if_exists(json_pdp, json_to_use, "keystone_project_id", str)
+ JsonUtils.copy_field_if_exists(json_pdp, json_to_use, "security_pipeline", list)
+ JsonUtils.copy_field_if_exists(json_pdp, json_to_use, "description", str)
+
+ pdps = PDPManager.get_pdp(self._user_id)
+ exists = False
+ for pdp_key in pdps:
+ if pdps[pdp_key]["name"] == json_to_use["name"]:
+ PDPManager.update_pdp(self._user_id, pdp_id=pdp_key, value=json_to_use)
+ exists = True
+ if exists is False:
+ PDPManager.add_pdp(self._user_id, value=json_to_use)
+
+ def _import_json(self, user_id):
+ self._user_id = user_id
+ if 'file' in request.files:
+ file = request.files['file']
+ logger.debug("Importing {} file...".format(file))
+ json_content = json.load(file)
+ else:
+ json_content = request.json
+ logger.debug("Importing content: {} ...".format(json_content))
+
+ # first import the models without the meta rules as they are not yet defined
+ if "models" in json_content:
+ logger.info("Importing models...")
+ self._import_models_without_new_meta_rules(json_content["models"])
+
+ # import the policies that depends on the models
+ mandatory_policy_ids = []
+ if "policies" in json_content:
+ logger.info("Importing policies...")
+ mandatory_policy_ids = self._import_policies(json_content["policies"])
+
+ # import subjects, subject_data, subject_categories, idem for object and action
+ list_element = [{"key": "subject"}, {"key": "object"}, {"key": "action"}]
+ for elt in list_element:
+ in_key = elt["key"]
+ key = in_key + "s"
+ if key in json_content:
+ logger.info("Importing {}...".format(key))
+ self._import_subject_object_action(json_content[key], mandatory_policy_ids, in_key)
+ key = in_key + "_categories"
+ if key in json_content:
+ logger.info("Importing {}...".format(key))
+ self._import_subject_object_action_categories(json_content[key], in_key)
+ key = in_key + "_data"
+ if key in json_content:
+ logger.info("Importing {}...".format(key))
+ self._import_subject_object_action_datas(json_content[key], mandatory_policy_ids, in_key)
+
+ # import meta rules
+ if "meta_rules" in json_content:
+ logger.info("Importing meta rules...")
+ self._import_meta_rules(json_content["meta_rules"])
+
+ # add the metarule to model
+ if "models" in json_content:
+ logger.info("Updating models with meta rules...")
+ self._import_models_with_new_meta_rules(json_content["models"])
+
+ # import subjects assignments, idem for object and action
+ for elt in list_element:
+ in_key = elt["key"]
+ key = in_key + "_assignments"
+ if key in json_content:
+ logger.info("Importing {}...".format(key))
+ self._import_subject_object_action_assignments(json_content[key], in_key)
+
+ # import rules
+ if "rules" in json_content:
+ logger.info("Importing rules...")
+ self._import_rules(json_content["rules"])
+
+ # import pdps
+ if "pdps" in json_content:
+ logger.info("Importing pdps...")
+ self._import_pdps(json_content["pdps"])
+
+ @check_auth
+ def post(self, user_id=None):
+ """Import file.
+
+ :param user_id: user ID who do the request
+ :return: {
+
+ }
+ :internal_api:
+ """
+ self._import_json(user_id)
+ return "Import ok !"
diff --git a/moon_manager/moon_manager/api/json_utils.py b/moon_manager/moon_manager/api/json_utils.py
new file mode 100644
index 00000000..cc4c8b0f
--- /dev/null
+++ b/moon_manager/moon_manager/api/json_utils.py
@@ -0,0 +1,255 @@
+import logging
+from moon_manager.api.base_exception import BaseException
+
+logger = logging.getLogger("moon.manager.api." + __name__)
+
+
+class UnknownName(BaseException):
+ def __init__(self, message):
+
+ # Call the base class constructor with the parameters it needs
+ super(UnknownName, self).__init__(message)
+
+
+class UnknownId(BaseException):
+ def __init__(self, message):
+
+ # Call the base class constructor with the parameters it needs
+ super(UnknownId, self).__init__(message)
+
+
+class MissingIdOrName(BaseException):
+ def __init__(self, message):
+
+ # Call the base class constructor with the parameters it needs
+ super(MissingIdOrName, self).__init__(message)
+
+
+class UnknownField(BaseException):
+ def __init__(self, message):
+
+ # Call the base class constructor with the parameters it needs
+ super(UnknownField, self).__init__(message)
+
+
+class JsonUtils:
+ @staticmethod
+ def get_override(json_content):
+ if "override" in json_content:
+ return json_content["override"]
+ return False
+
+ @staticmethod
+ def get_mandatory(json_content):
+ if "mandatory" in json_content:
+ return json_content["mandatory"]
+ return False
+
+ @staticmethod
+ def copy_field_if_exists(json_in, json_out, field_name, type_field, default_value=None):
+ if field_name in json_in:
+ json_out[field_name] = json_in[field_name]
+ else:
+ if type_field is bool:
+ if default_value is None:
+ default_value = False
+ json_out[field_name] = default_value
+ if type_field is str:
+ if default_value is None:
+ default_value = ""
+ json_out[field_name] = default_value
+ if type_field is dict:
+ json_out[field_name] = dict()
+ if type_field is list:
+ json_out[field_name] = []
+
+ @staticmethod
+ def _get_element_in_db_from_id(element_type, element_id, user_id, policy_id, category_id, meta_rule_id, manager):
+ # the item is supposed to be in the db, we check it exists!
+ if element_type == "model":
+ data_db = manager.get_models(user_id, model_id=element_id)
+ elif element_type == "policy":
+ data_db = manager.get_policies(user_id, policy_id=element_id)
+ elif element_type == "subject":
+ data_db = manager.get_subjects(user_id, policy_id, perimeter_id=element_id)
+ elif element_type == "object":
+ data_db = manager.get_objects(user_id, policy_id, perimeter_id=element_id)
+ elif element_type == "action":
+ data_db = manager.get_actions(user_id, policy_id, perimeter_id=element_id)
+ elif element_type == "subject_category":
+ data_db = manager.get_subject_categories(user_id, category_id=element_id)
+ elif element_type == "object_category":
+ data_db = manager.get_object_categories(user_id, category_id=element_id)
+ elif element_type == "action_category":
+ data_db = manager.get_action_categories(user_id, category_id=element_id)
+ elif element_type == "meta_rule":
+ data_db = manager.get_meta_rules(user_id, meta_rule_id=element_id)
+ elif element_type == "subject_data":
+ data_db = manager.get_subject_data(user_id, policy_id, data_id=element_id, category_id=category_id)
+ elif element_type == "object_data":
+ data_db = manager.get_object_data(user_id, policy_id, data_id=element_id, category_id=category_id)
+ elif element_type == "action_data":
+ data_db = manager.get_action_data(user_id, policy_id, data_id=element_id, category_id=category_id)
+ elif element_type == "meta_rule":
+ data_db = manager.get_meta_rules(user_id, meta_rule_id=meta_rule_id)
+ else:
+ raise Exception("Conversion of {} not implemented yet!".format(element_type))
+
+ # logger.info(data_db)
+
+ # do some post processing ... the result should be {key : { .... .... } }
+ if element_type == "subject_data" or element_type == "object_data" or element_type == "action_data":
+ if data_db is not None and isinstance(data_db, list):
+ # TODO remove comments after fixing the bug on moondb when adding metarule : we can have several identical entries !
+ #if len(data_db) > 1:
+ # raise Exception("Several {} with the same id : {}".format(element_type, data_db))
+ data_db = data_db[0]
+
+ if data_db is not None and data_db["data"] is not None and isinstance(data_db["data"], dict):
+ # TODO remove comments after fixing the bug on moondb when adding metarule : we can have several identical entries !
+ #if len(data_db["data"].values()) != 1:
+ # raise Exception("Several {} with the same id : {}".format(element_type, data_db))
+ #data_db = data_db["data"]
+ # TODO remove these two lines after fixing the bug on moondb when adding metarule : we can have several identical entries !
+ list_values = list(data_db["data"].values())
+ data_db = list_values[0]
+ # logger.info("subject data after postprocessing {}".format(data_db))
+ return data_db
+
+ @staticmethod
+ def _get_element_id_in_db_from_name(element_type, element_name, user_id, policy_id, category_id, meta_rule_id, manager):
+ if element_type == "model":
+ data_db = manager.get_models(user_id)
+ elif element_type == "policy":
+ data_db = manager.get_policies(user_id)
+ elif element_type == "subject":
+ data_db = manager.get_subjects(user_id, policy_id)
+ elif element_type == "object":
+ data_db = manager.get_objects(user_id, policy_id)
+ elif element_type == "action":
+ data_db = manager.get_actions(user_id, policy_id)
+ elif element_type == "subject_category":
+ data_db = manager.get_subject_categories(user_id)
+ elif element_type == "object_category":
+ data_db = manager.get_object_categories(user_id)
+ elif element_type == "action_category":
+ data_db = manager.get_action_categories(user_id)
+ elif element_type == "meta_rule":
+ data_db = manager.get_meta_rules(user_id)
+ elif element_type == "subject_data":
+ data_db = manager.get_subject_data(user_id, policy_id, category_id=category_id)
+ elif element_type == "object_data":
+ data_db = manager.get_object_data(user_id, policy_id, category_id=category_id)
+ elif element_type == "action_data":
+ data_db = manager.get_action_data(user_id, policy_id, category_id=category_id)
+ elif element_type == "meta_rule":
+ data_db = manager.get_meta_rules(user_id)
+ elif element_type == "rule":
+ data_db = manager.get_rules(user_id, policy_id)
+ else:
+ raise BaseException("Conversion of {} not implemented yet!".format(element_type))
+
+ if isinstance(data_db, dict):
+ for key_id in data_db:
+ if isinstance(data_db[key_id], dict) and "name" in data_db[key_id]:
+ if data_db[key_id]["name"] == element_name:
+ return key_id
+ else:
+ for elt in data_db:
+ if isinstance(elt, dict) and "data" in elt: # we handle here subject_data, object_data and action_data...
+ for data_key in elt["data"]:
+ # logger.info("data from the db {} ".format(elt["data"][data_key]))
+ data = elt["data"][data_key]
+ if "name" in data and data["name"] == element_name:
+ return data_key
+ if "value" in data and data["value"]["name"] == element_name:
+ return data_key
+ return None
+
+ @staticmethod
+ def convert_name_to_id(json_in, json_out, field_name_in, field_name_out, element_type, manager, user_id, policy_id=None, category_id=None, meta_rule_id=None, field_mandatory=True):
+ if field_name_in not in json_in:
+ raise UnknownField("The field {} is not in the input json".format(field_name_in))
+
+ if "id" in json_in[field_name_in]:
+ data_db = JsonUtils._get_element_in_db_from_id(element_type, json_in[field_name_in]["id"], user_id, policy_id, category_id, meta_rule_id, manager)
+ if data_db is None:
+ raise UnknownId("No {} with id {} found in database".format(element_type, json_in[field_name_in]["id"]))
+ json_out[field_name_out] = json_in[field_name_in]["id"]
+
+ elif "name" in json_in[field_name_in]:
+ id_in_db = JsonUtils._get_element_id_in_db_from_name(element_type, json_in[field_name_in]["name"], user_id, policy_id, category_id, meta_rule_id, manager)
+ if id_in_db is None:
+ raise UnknownName("No {} with name {} found in database".format(element_type,json_in[field_name_in]["name"]))
+ json_out[field_name_out] = id_in_db
+ elif field_mandatory is True:
+ raise MissingIdOrName("No id or name found in the input json {}".format(json_in))
+
+ @staticmethod
+ def convert_id_to_name(id_, json_out, field_name_out, element_type, manager, user_id,
+ policy_id=None, category_id=None, meta_rule_id=None):
+ json_out[field_name_out] = {"name": JsonUtils.convert_id_to_name_string(id_, element_type, manager, user_id, policy_id, category_id, meta_rule_id)}
+
+ @staticmethod
+ def __convert_results_to_element(element):
+ if isinstance(element, dict) and "name" not in element and "value" not in element:
+ list_values = [v for v in element.values()]
+ elif isinstance(element, list):
+ list_values = element
+ else:
+ list_values = []
+ list_values.append(element)
+ return list_values[0]
+
+ @staticmethod
+ def convert_id_to_name_string(id_, element_type, manager, user_id,
+ policy_id=None, category_id=None, meta_rule_id=None):
+
+ element = JsonUtils._get_element_in_db_from_id(element_type, id_, user_id, policy_id, category_id, meta_rule_id, manager)
+ # logger.info(element)
+ if element is None:
+ raise UnknownId("No {} with id {} found in database".format(element_type, id_))
+ res = JsonUtils.__convert_results_to_element(element)
+ # logger.info(res)
+ if "name" in res:
+ return res["name"]
+ if "value" in res and "name" in res["value"]:
+ return res["value"]["name"]
+ return None
+
+ @staticmethod
+ def convert_names_to_ids(json_in, json_out, field_name_in, field_name_out, element_type, manager, user_id, policy_id=None, category_id=None, meta_rule_id=None, field_mandatory=True):
+ ids = []
+ if field_name_in not in json_in:
+ raise UnknownField("The field {} is not in the input json".format(field_name_in))
+
+ for elt in json_in[field_name_in]:
+ if "id" in elt:
+ data_db = JsonUtils._get_element_in_db_from_id(element_type, elt["id"], user_id, policy_id, category_id, meta_rule_id, manager)
+ if data_db is None:
+ raise UnknownId("No {} with id {} found in database".format(element_type, elt["id"]))
+ ids.append(elt["id"])
+ elif "name" in elt:
+ id_in_db = JsonUtils._get_element_id_in_db_from_name(element_type, elt["name"], user_id, policy_id, category_id, meta_rule_id, manager)
+ if id_in_db is None:
+ raise UnknownName("No {} with name {} found in database".format(element_type, elt["name"]))
+ ids.append(id_in_db)
+ elif field_mandatory is True:
+ raise MissingIdOrName("No id or name found in the input json {}".format(elt))
+ json_out[field_name_out] = ids
+
+ @staticmethod
+ def convert_ids_to_names(ids, json_out, field_name_out, element_type, manager, user_id, policy_id=None, category_id=None, meta_rule_id=None):
+ res_array = []
+ for id_ in ids:
+ element = JsonUtils._get_element_in_db_from_id(element_type, id_, user_id, policy_id, category_id, meta_rule_id, manager)
+ if element is None:
+ raise UnknownId("No {} with id {} found in database".format(element_type, id_))
+ res = JsonUtils.__convert_results_to_element(element)
+ # logger.info(res)
+ if "name" in res:
+ res_array.append({"name": res["name"]})
+ if "value" in res and "name" in res["value"]:
+ res_array.append({"name": res["value"]["name"]})
+ json_out[field_name_out] = res_array
+
diff --git a/moon_manager/moon_manager/api/meta_data.py b/moon_manager/moon_manager/api/meta_data.py
index 28aab445..62ca050f 100644
--- a/moon_manager/moon_manager/api/meta_data.py
+++ b/moon_manager/moon_manager/api/meta_data.py
@@ -12,6 +12,7 @@ from flask_restful import Resource
import logging
from python_moonutilities.security_functions import check_auth
from python_moondb.core import ModelManager
+from python_moonutilities.security_functions import validate_input
__version__ = "4.3.2"
@@ -29,6 +30,7 @@ class SubjectCategories(Resource):
"/subject_categories/<string:category_id>",
)
+ @validate_input("get",kwargs_state=[False,False])
@check_auth
def get(self, category_id=None, user_id=None):
"""Retrieve all subject categories or a specific one
@@ -38,20 +40,17 @@ class SubjectCategories(Resource):
:return: {
"subject_category_id": {
"name": "name of the category",
- "description": "description of the category"
+ "description": "description of the category (optional)"
}
}
:internal_api: get_subject_categories
"""
- try:
- data = ModelManager.get_subject_categories(
- user_id=user_id, category_id=category_id)
- except Exception as e:
- logger.error(e, exc_info=True)
- return {"result": False,
- "error": str(e)}, 500
+ data = ModelManager.get_subject_categories(
+ user_id=user_id, category_id=category_id)
+
return {"subject_categories": data}
+ @validate_input("post",body_state={"name":True})
@check_auth
def post(self, category_id=None, user_id=None):
"""Create or update a subject category.
@@ -59,26 +58,23 @@ class SubjectCategories(Resource):
:param category_id: must not be used here
:param user_id: user ID who do the request
:request body: {
- "name": "name of the category",
- "description": "description of the category"
+ "name": "name of the category (mandatory)",
+ "description": "description of the category (optional)"
}
:return: {
"subject_category_id": {
"name": "name of the category",
- "description": "description of the category"
+ "description": "description of the category (optional)"
}
}
:internal_api: add_subject_category
"""
- try:
- data = ModelManager.add_subject_category(
- user_id=user_id, value=request.json)
- except Exception as e:
- logger.error(e, exc_info=True)
- return {"result": False,
- "error": str(e)}, 500
+ data = ModelManager.add_subject_category(
+ user_id=user_id, value=request.json)
+
return {"subject_categories": data}
+ @validate_input("delete",kwargs_state=[True,False])
@check_auth
def delete(self, category_id=None, user_id=None):
"""Delete a subject category
@@ -87,17 +83,14 @@ class SubjectCategories(Resource):
:param user_id: user ID who do the request
:return: {
"result": "True or False",
- "message": "optional message"
+ "message": "optional message (optional)"
}
:internal_api: delete_subject_category
"""
- try:
- data = ModelManager.delete_subject_category(
- user_id=user_id, category_id=category_id)
- except Exception as e:
- logger.error(e, exc_info=True)
- return {"result": False,
- "error": str(e)}, 500
+
+ data = ModelManager.delete_subject_category(
+ user_id=user_id, category_id=category_id)
+
return {"result": True}
@@ -112,6 +105,7 @@ class ObjectCategories(Resource):
"/object_categories/<string:category_id>",
)
+ @validate_input("get",kwargs_state=[False,False])
@check_auth
def get(self, category_id=None, user_id=None):
"""Retrieve all object categories or a specific one
@@ -121,20 +115,17 @@ class ObjectCategories(Resource):
:return: {
"object_category_id": {
"name": "name of the category",
- "description": "description of the category"
+ "description": "description of the category (optional)"
}
}
:internal_api: get_object_categories
"""
- try:
- data = ModelManager.get_object_categories(
- user_id=user_id, category_id=category_id)
- except Exception as e:
- logger.error(e, exc_info=True)
- return {"result": False,
- "error": str(e)}, 500
+ data = ModelManager.get_object_categories(
+ user_id=user_id, category_id=category_id)
+
return {"object_categories": data}
+ @validate_input("post", body_state={"name":True})
@check_auth
def post(self, category_id=None, user_id=None):
"""Create or update a object category.
@@ -142,26 +133,24 @@ class ObjectCategories(Resource):
:param category_id: must not be used here
:param user_id: user ID who do the request
:request body: {
- "name": "name of the category",
- "description": "description of the category"
+ "name": "name of the category (mandatory)",
+ "description": "description of the category (optional)"
}
:return: {
"object_category_id": {
"name": "name of the category",
- "description": "description of the category"
+ "description": "description of the category (optional)"
}
}
:internal_api: add_object_category
"""
- try:
- data = ModelManager.add_object_category(
- user_id=user_id, value=request.json)
- except Exception as e:
- logger.error(e, exc_info=True)
- return {"result": False,
- "error": str(e)}, 500
+
+ data = ModelManager.add_object_category(
+ user_id=user_id, value=request.json)
+
return {"object_categories": data}
+ @validate_input("delete", kwargs_state=[True, False])
@check_auth
def delete(self, category_id=None, user_id=None):
"""Delete an object category
@@ -170,17 +159,14 @@ class ObjectCategories(Resource):
:param user_id: user ID who do the request
:return: {
"result": "True or False",
- "message": "optional message"
+ "message": "optional message (optional)"
}
:internal_api: delete_object_category
"""
- try:
- data = ModelManager.delete_object_category(
- user_id=user_id, category_id=category_id)
- except Exception as e:
- logger.error(e, exc_info=True)
- return {"result": False,
- "error": str(e)}, 500
+
+ data = ModelManager.delete_object_category(
+ user_id=user_id, category_id=category_id)
+
return {"result": True}
@@ -195,6 +181,7 @@ class ActionCategories(Resource):
"/action_categories/<string:category_id>",
)
+ @validate_input("get", kwargs_state=[False, False])
@check_auth
def get(self, category_id=None, user_id=None):
"""Retrieve all action categories or a specific one
@@ -204,20 +191,18 @@ class ActionCategories(Resource):
:return: {
"action_category_id": {
"name": "name of the category",
- "description": "description of the category"
+ "description": "description of the category (optional)"
}
}
:internal_api: get_action_categories
"""
- try:
- data = ModelManager.get_action_categories(
- user_id=user_id, category_id=category_id)
- except Exception as e:
- logger.error(e, exc_info=True)
- return {"result": False,
- "error": str(e)}, 500
+
+ data = ModelManager.get_action_categories(
+ user_id=user_id, category_id=category_id)
+
return {"action_categories": data}
+ @validate_input("post", body_state={"name":True})
@check_auth
def post(self, category_id=None, user_id=None):
"""Create or update an action category.
@@ -225,26 +210,24 @@ class ActionCategories(Resource):
:param category_id: must not be used here
:param user_id: user ID who do the request
:request body: {
- "name": "name of the category",
- "description": "description of the category"
+ "name": "name of the category (mandatory)",
+ "description": "description of the category (optional)"
}
:return: {
"action_category_id": {
"name": "name of the category",
- "description": "description of the category"
+ "description": "description of the category (optional)"
}
}
:internal_api: add_action_category
"""
- try:
- data = ModelManager.add_action_category(
- user_id=user_id, value=request.json)
- except Exception as e:
- logger.error(e, exc_info=True)
- return {"result": False,
- "error": str(e)}, 500
+
+ data = ModelManager.add_action_category(
+ user_id=user_id, value=request.json)
+
return {"action_categories": data}
+ @validate_input("delete", kwargs_state=[True, False])
@check_auth
def delete(self, category_id=None, user_id=None):
"""Delete an action
@@ -253,15 +236,11 @@ class ActionCategories(Resource):
:param user_id: user ID who do the request
:return: {
"result": "True or False",
- "message": "optional message"
+ "message": "optional message (optional)"
}
:internal_api: delete_action_category
"""
- try:
- data = ModelManager.delete_action_category(
- user_id=user_id, category_id=category_id)
- except Exception as e:
- logger.error(e, exc_info=True)
- return {"result": False,
- "error": str(e)}, 500
+ data = ModelManager.delete_action_category(
+ user_id=user_id, category_id=category_id)
+
return {"result": True}
diff --git a/moon_manager/moon_manager/api/meta_rules.py b/moon_manager/moon_manager/api/meta_rules.py
index 25ae5aac..3dc9996b 100644
--- a/moon_manager/moon_manager/api/meta_rules.py
+++ b/moon_manager/moon_manager/api/meta_rules.py
@@ -12,6 +12,7 @@ from flask_restful import Resource
import logging
from python_moonutilities.security_functions import check_auth
from python_moondb.core import ModelManager
+from python_moonutilities.security_functions import validate_input
__version__ = "4.3.2"
@@ -30,6 +31,7 @@ class MetaRules(Resource):
"/meta_rules/<string:meta_rule_id>/"
)
+ @validate_input("get", kwargs_state=[False, False])
@check_auth
def get(self, meta_rule_id=None, user_id=None):
"""Retrieve all sub meta rules
@@ -40,7 +42,6 @@ class MetaRules(Resource):
"meta_rules": {
"meta_rule_id1": {
"name": "name of the meta rule",
- "algorithm": "name of the meta rule algorithm",
"subject_categories": ["subject_category_id1",
"subject_category_id2"],
"object_categories": ["object_category_id1"],
@@ -50,27 +51,25 @@ class MetaRules(Resource):
}
:internal_api: get_meta_rules
"""
- try:
- data = ModelManager.get_meta_rules(
- user_id=user_id, meta_rule_id=meta_rule_id)
- except Exception as e:
- logger.error(e, exc_info=True)
- return {"result": False,
- "error": str(e)}, 500
+
+ data = ModelManager.get_meta_rules(
+ user_id=user_id, meta_rule_id=meta_rule_id)
+
return {"meta_rules": data}
+ @validate_input("post", body_state={"name":True, "subject_categories":True, "object_categories":True, "action_categories":True})
@check_auth
def post(self, meta_rule_id=None, user_id=None):
"""Add a meta rule
- :param meta_rule_id: Meta rule ID
+ :param meta_rule_id: Meta rule ID (not used here)
:param user_id: user ID who do the request
:request body: post = {
- "name": "name of the meta rule",
- "subject_categories": ["subject_category_id1",
+ "name": "name of the meta rule (mandatory)",
+ "subject_categories": ["subject_category_id1 (mandatory)",
"subject_category_id2"],
- "object_categories": ["object_category_id1"],
- "action_categories": ["action_category_id1"]
+ "object_categories": ["object_category_id1 (mandatory)"],
+ "action_categories": ["action_category_id1 (mandatory)"]
}
:return: {
"meta_rules": {
@@ -85,15 +84,13 @@ class MetaRules(Resource):
}
:internal_api: add_meta_rules
"""
- try:
- data = ModelManager.add_meta_rule(
- user_id=user_id, meta_rule_id=None, value=request.json)
- except Exception as e:
- logger.error(e, exc_info=True)
- return {"result": False,
- "error": str(e)}, 500
+
+ data = ModelManager.add_meta_rule(
+ user_id=user_id, meta_rule_id=None, value=request.json)
+
return {"meta_rules": data}
+ @validate_input("patch", kwargs_state=[True, False], body_state={"name":True, "subject_categories":True, "object_categories":True, "action_categories":True})
@check_auth
def patch(self, meta_rule_id=None, user_id=None):
"""Update a meta rule
@@ -120,28 +117,18 @@ class MetaRules(Resource):
}
:internal_api: set_meta_rules
"""
- try:
- data = ModelManager.set_meta_rule(
- user_id=user_id, meta_rule_id=meta_rule_id, value=request.json)
- except Exception as e:
- logger.error(e, exc_info=True)
- return {"result": False,
- "error": str(e)}, 500
+ data = ModelManager.set_meta_rule(
+ user_id=user_id, meta_rule_id=meta_rule_id, value=request.json)
+
return {"meta_rules": data}
+ @validate_input("delete", kwargs_state=[True, False])
@check_auth
def delete(self, meta_rule_id=None, user_id=None):
"""Delete a meta rule
:param meta_rule_id: Meta rule ID
:param user_id: user ID who do the request
- :request body: delete = {
- "name": "name of the meta rule",
- "subject_categories": ["subject_category_id1",
- "subject_category_id2"],
- "object_categories": ["object_category_id1"],
- "action_categories": ["action_category_id1"]
- }
:return: {
"meta_rules": {
"meta_rule_id1": {
@@ -155,12 +142,9 @@ class MetaRules(Resource):
}
:internal_api: delete_meta_rules
"""
- try:
- data = ModelManager.delete_meta_rule(
- user_id=user_id, meta_rule_id=meta_rule_id)
- except Exception as e:
- logger.error(e, exc_info=True)
- return {"result": False,
- "error": str(e)}, 500
+
+ data = ModelManager.delete_meta_rule(
+ user_id=user_id, meta_rule_id=meta_rule_id)
+
return {"result": True}
diff --git a/moon_manager/moon_manager/api/models.py b/moon_manager/moon_manager/api/models.py
index 07b10d90..c3068367 100644
--- a/moon_manager/moon_manager/api/models.py
+++ b/moon_manager/moon_manager/api/models.py
@@ -11,6 +11,7 @@ from flask_restful import Resource
import logging
from python_moonutilities.security_functions import check_auth
from python_moondb.core import ModelManager
+from python_moonutilities.security_functions import validate_input
__version__ = "4.3.2"
@@ -29,6 +30,7 @@ class Models(Resource):
"/models/<string:uuid>/",
)
+ @validate_input("get", kwargs_state=[False, False])
@check_auth
def get(self, uuid=None, user_id=None):
"""Retrieve all models
@@ -38,20 +40,17 @@ class Models(Resource):
:return: {
"model_id1": {
"name": "...",
- "description": "...",
+ "description": "... (optional)",
"meta_rules": ["meta_rule_id1", ]
}
}
:internal_api: get_models
"""
- try:
- data = ModelManager.get_models(user_id=user_id, model_id=uuid)
- except Exception as e:
- logger.error(e, exc_info=True)
- return {"result": False,
- "error": str(e)}, 500
+ data = ModelManager.get_models(user_id=user_id, model_id=uuid)
+
return {"models": data}
+ @validate_input("post", body_state={"name":True, "meta_rules":True})
@check_auth
def post(self, uuid=None, user_id=None):
"""Create model.
@@ -59,28 +58,25 @@ class Models(Resource):
:param uuid: uuid of the model (not used here)
:param user_id: user ID who do the request
:request body: {
- "name": "...",
- "description": "...",
+ "name": "name of the model (mandatory)",
+ "description": "description of the model (optional)",
"meta_rules": ["meta_rule_id1", ]
}
:return: {
"model_id1": {
- "name": "...",
- "description": "...",
+ "name": "name of the model",
+ "description": "description of the model (optional)",
"meta_rules": ["meta_rule_id1", ]
}
}
:internal_api: add_model
"""
- try:
- data = ModelManager.add_model(
- user_id=user_id, model_id=uuid, value=request.json)
- except Exception as e:
- logger.error(e, exc_info=True)
- return {"result": False,
- "error": str(e)}, 500
+ data = ModelManager.add_model(
+ user_id=user_id, model_id=uuid, value=request.json)
+
return {"models": data}
+ @validate_input("delete", kwargs_state=[True, False])
@check_auth
def delete(self, uuid=None, user_id=None):
"""Delete a model
@@ -89,18 +85,16 @@ class Models(Resource):
:param user_id: user ID who do the request
:return: {
"result": "True or False",
- "message": "optional message"
+ "message": "optional message (optional)"
}
:internal_api: delete_model
"""
- try:
- data = ModelManager.delete_model(user_id=user_id, model_id=uuid)
- except Exception as e:
- logger.error(e, exc_info=True)
- return {"result": False,
- "error": str(e)}, 500
+
+ data = ModelManager.delete_model(user_id=user_id, model_id=uuid)
+
return {"result": True}
+ @validate_input("patch", kwargs_state=[True, False], body_state={"name":True, "meta_rules":True})
@check_auth
def patch(self, uuid=None, user_id=None):
"""Update a model
@@ -109,19 +103,15 @@ class Models(Resource):
:param user_id: user ID who do the request
:return: {
"model_id1": {
- "name": "...",
- "description": "...",
+ "name": "name of the model",
+ "description": "... (optional)",
"meta_rules": ["meta_rule_id1", ]
}
}
:internal_api: update_model
"""
- try:
- data = ModelManager.update_model(
- user_id=user_id, model_id=uuid, value=request.json)
- except Exception as e:
- logger.error(e, exc_info=True)
- return {"result": False,
- "error": str(e)}, 500
+ data = ModelManager.update_model(
+ user_id=user_id, model_id=uuid, value=request.json)
+
return {"models": data}
diff --git a/moon_manager/moon_manager/api/pdp.py b/moon_manager/moon_manager/api/pdp.py
index 4f11135e..a5d7c007 100644
--- a/moon_manager/moon_manager/api/pdp.py
+++ b/moon_manager/moon_manager/api/pdp.py
@@ -17,6 +17,7 @@ from python_moondb.core import PDPManager
from python_moondb.core import PolicyManager
from python_moondb.core import ModelManager
from python_moonutilities import configuration, exceptions
+from python_moonutilities.security_functions import validate_input
__version__ = "4.3.2"
@@ -73,7 +74,7 @@ def add_pod(uuid, data):
time.sleep(1)
else:
break
- logger.info(req.text)
+ logger.info("Pod add request answer : {}".format(req.text))
def check_keystone_pid(k_pid):
@@ -96,6 +97,7 @@ class PDP(Resource):
"/pdp/<string:uuid>/",
)
+ @validate_input("get", kwargs_state=[False, False])
@check_auth
def get(self, uuid=None, user_id=None):
"""Retrieve all pdp
@@ -107,19 +109,17 @@ class PDP(Resource):
"name": "...",
"security_pipeline": [...],
"keystone_project_id": "keystone_project_id1",
- "description": "...",
+ "description": "... (optional)",
}
}
:internal_api: get_pdp
"""
- try:
- data = PDPManager.get_pdp(user_id=user_id, pdp_id=uuid)
- except Exception as e:
- logger.error(e, exc_info=True)
- return {"result": False,
- "error": str(e)}, 500
+
+ data = PDPManager.get_pdp(user_id=user_id, pdp_id=uuid)
+
return {"pdps": data}
+ @validate_input("post", body_state={"name": True, "security_pipeline": True, "keystone_project_id": True})
@check_auth
def post(self, uuid=None, user_id=None):
"""Create pdp.
@@ -127,92 +127,84 @@ class PDP(Resource):
:param uuid: uuid of the pdp (not used here)
:param user_id: user ID who do the request
:request body: {
- "name": "...",
- "security_pipeline": [...],
- "keystone_project_id": "keystone_project_id1",
- "description": "...",
+ "name": "name of the PDP (mandatory)",
+ "security_pipeline": ["may be empty"],
+ "keystone_project_id": "keystone_project_id1 (may be empty)",
+ "description": "description of the PDP (optional)",
}
:return: {
"pdp_id1": {
"name": "...",
"security_pipeline": [...],
"keystone_project_id": "keystone_project_id1",
- "description": "...",
+ "description": "... (optional)",
}
}
:internal_api: add_pdp
"""
- try:
- data = dict(request.json)
- if not data.get("keystone_project_id"):
- data["keystone_project_id"] = None
- else:
- if check_keystone_pid(data.get("keystone_project_id")):
- raise exceptions.PdpKeystoneMappingConflict
- data = PDPManager.add_pdp(
- user_id=user_id, pdp_id=None, value=request.json)
- uuid = list(data.keys())[0]
- logger.debug("data={}".format(data))
- logger.debug("uuid={}".format(uuid))
- add_pod(uuid=uuid, data=data[uuid])
- except Exception as e:
- logger.error(e, exc_info=True)
- return {"result": False,
- "error": str(e)}, 500
+
+ data = dict(request.json)
+ if not data.get("keystone_project_id"):
+ data["keystone_project_id"] = None
+ else:
+ if check_keystone_pid(data.get("keystone_project_id")):
+ raise exceptions.PdpKeystoneMappingConflict
+ data = PDPManager.add_pdp(
+ user_id=user_id, pdp_id=None, value=request.json)
+ uuid = list(data.keys())[0]
+ logger.debug("data={}".format(data))
+ logger.debug("uuid={}".format(uuid))
+ add_pod(uuid=uuid, data=data[uuid])
+
return {"pdps": data}
+ @validate_input("delete", kwargs_state=[True, False])
@check_auth
- def delete(self, uuid=None, user_id=None):
+ def delete(self, uuid, user_id=None):
"""Delete a pdp
:param uuid: uuid of the pdp to delete
:param user_id: user ID who do the request
:return: {
"result": "True or False",
- "message": "optional message"
+ "message": "optional message (optional)"
}
:internal_api: delete_pdp
"""
- try:
- data = PDPManager.delete_pdp(user_id=user_id, pdp_id=uuid)
- delete_pod(uuid)
- except Exception as e:
- logger.error(e, exc_info=True)
- return {"result": False,
- "error": str(e)}, 500
+ data = PDPManager.delete_pdp(user_id=user_id, pdp_id=uuid)
+ delete_pod(uuid)
+
return {"result": True}
+ @validate_input("patch", kwargs_state=[True, False], body_state={"name": True, "security_pipeline": True, "keystone_project_id": True})
@check_auth
- def patch(self, uuid=None, user_id=None):
+ def patch(self, uuid, user_id=None):
"""Update a pdp
:param uuid: uuid of the pdp to update
:param user_id: user ID who do the request
:return: {
"pdp_id1": {
- "name": "...",
- "security_pipeline": [...],
- "keystone_project_id": "keystone_project_id1",
- "description": "...",
+ "name": "name of the PDP",
+ "security_pipeline": ["may be empty"],
+ "keystone_project_id": "keystone_project_id1 (may be empty)",
+ "description": "description of the PDP (optional)",
}
}
:internal_api: update_pdp
"""
- try:
- _data = dict(request.json)
- if not _data.get("keystone_project_id"):
- _data["keystone_project_id"] = None
- else:
- if check_keystone_pid(_data.get("keystone_project_id")):
- raise exceptions.PdpKeystoneMappingConflict
- data = PDPManager.update_pdp(
- user_id=user_id, pdp_id=uuid, value=_data)
- logger.debug("data={}".format(data))
- logger.debug("uuid={}".format(uuid))
- add_pod(uuid=uuid, data=data[uuid])
- except Exception as e:
- logger.error(e, exc_info=True)
- return {"result": False,
- "error": str(e)}, 500
+
+ _data = dict(request.json)
+ if not _data.get("keystone_project_id"):
+ _data["keystone_project_id"] = None
+ else:
+ if check_keystone_pid(_data.get("keystone_project_id")):
+ raise exceptions.PdpKeystoneMappingConflict
+ data = PDPManager.update_pdp(
+ user_id=user_id, pdp_id=uuid, value=_data)
+ logger.debug("data={}".format(data))
+ logger.debug("uuid={}".format(uuid))
+ add_pod(uuid=uuid, data=data[uuid])
+
return {"pdps": data}
diff --git a/moon_manager/moon_manager/api/perimeter.py b/moon_manager/moon_manager/api/perimeter.py
index d3948bc1..6c39c43d 100644
--- a/moon_manager/moon_manager/api/perimeter.py
+++ b/moon_manager/moon_manager/api/perimeter.py
@@ -15,6 +15,8 @@ from flask_restful import Resource
import logging
from python_moonutilities.security_functions import check_auth
from python_moondb.core import PolicyManager
+from python_moonutilities.security_functions import validate_input
+
__version__ = "4.3.2"
@@ -35,6 +37,7 @@ class Subjects(Resource):
"/policies/<string:uuid>/subjects/<string:perimeter_id>",
)
+ @validate_input("get", kwargs_state=[False, False, False])
@check_auth
def get(self, uuid=None, perimeter_id=None, user_id=None):
"""Retrieve all subjects or a specific one if perimeter_id is
@@ -47,67 +50,63 @@ class Subjects(Resource):
"subject_id": {
"name": "name of the subject",
"keystone_id": "keystone id of the subject",
- "description": "a description"
+ "description": "a description (optional)"
}
}
:internal_api: get_subjects
"""
- try:
- data = PolicyManager.get_subjects(
- user_id=user_id,
- policy_id=uuid,
- perimeter_id=perimeter_id
- )
- except Exception as e:
- logger.error(e, exc_info=True)
- return {"result": False,
- "error": str(e)}, 500
+
+ data = PolicyManager.get_subjects(
+ user_id=user_id,
+ policy_id=uuid,
+ perimeter_id=perimeter_id
+ )
+
return {"subjects": data}
+ @validate_input("post", body_state={"name":True})
@check_auth
- def post(self, uuid=None, perimeter_id=None, user_id=None):
+ def post(self, uuid, perimeter_id=None, user_id=None):
"""Create or update a subject.
:param uuid: uuid of the policy
:param perimeter_id: must not be used here
:param user_id: user ID who do the request
:request body: {
- "name": "name of the subject",
- "description": "description of the subject",
- "password": "password for the subject",
- "email": "email address of the subject"
+ "name": "name of the subject (mandatory)",
+ "description": "description of the subject (optional)",
+ "password": "password for the subject (optional)",
+ "email": "email address of the subject (optional)"
}
:return: {
"subject_id": {
"name": "name of the subject",
"keystone_id": "keystone id of the subject",
- "description": "description of the subject",
- "password": "password for the subject",
- "email": "email address of the subject"
+ "description": "description of the subject (optional)",
+ "password": "password for the subject (optional)",
+ "email": "email address of the subject (optional)"
}
}
:internal_api: set_subject
"""
- try:
- if not perimeter_id:
- data = PolicyManager.get_subjects(user_id=user_id,
- policy_id=None)
- if 'name' in request.json:
- for data_id, data_value in data.items():
- if data_value['name'] == request.json['name']:
- perimeter_id = data_id
- break
- data = PolicyManager.add_subject(
- user_id=user_id, policy_id=uuid,
- perimeter_id=perimeter_id, value=request.json)
- except Exception as e:
- logger.error(e, exc_info=True)
- return {"result": False,
- "error": str(e)}, 500
+
+ if not perimeter_id:
+ data = PolicyManager.get_subjects(user_id=user_id,
+ policy_id=uuid)
+ if 'name' in request.json:
+ for data_id, data_value in data.items():
+ if data_value['name'] == request.json['name']:
+ perimeter_id = data_id
+ break
+ data = PolicyManager.add_subject(
+ user_id=user_id, policy_id=uuid,
+ perimeter_id=perimeter_id, value=request.json)
+
return {"subjects": data}
+ @validate_input("patch", kwargs_state=[False, True, False], body_state={"name":True})
@check_auth
- def patch(self, uuid=None, perimeter_id=None, user_id=None):
+ def patch(self, uuid, perimeter_id=None, user_id=None):
"""Create or update a subject.
:param uuid: uuid of the policy
@@ -115,64 +114,59 @@ class Subjects(Resource):
:param user_id: user ID who do the request
:request body: {
"name": "name of the subject",
- "description": "description of the subject",
- "password": "password for the subject",
- "email": "email address of the subject"
+ "description": "description of the subject (optional)",
+ "password": "password for the subject (optional)",
+ "email": "email address of the subject (optional)"
}
:return: {
"subject_id": {
"name": "name of the subject",
"keystone_id": "keystone id of the subject",
- "description": "description of the subject",
- "password": "password for the subject",
- "email": "email address of the subject"
+ "description": "description of the subject (optional)",
+ "password": "password for the subject (optional)",
+ "email": "email address of the subject (optional)"
}
}
:internal_api: set_subject
"""
- try:
- if not perimeter_id:
- data = PolicyManager.get_subjects(user_id=user_id,
- policy_id=None)
- if 'name' in request.json:
- for data_id, data_value in data.items():
- if data_value['name'] == request.json['name']:
- perimeter_id = data_id
- break
- data = PolicyManager.add_subject(
- user_id=user_id, policy_id=uuid,
- perimeter_id=perimeter_id, value=request.json)
- except Exception as e:
- logger.error(e, exc_info=True)
- return {"result": False,
- "error": str(e)}, 500
+
+ if not perimeter_id:
+ data = PolicyManager.get_subjects(user_id=user_id,
+ policy_id=None)
+ if 'name' in request.json:
+ for data_id, data_value in data.items():
+ if data_value['name'] == request.json['name']:
+ perimeter_id = data_id
+ break
+ data = PolicyManager.add_subject(
+ user_id=user_id, policy_id=uuid,
+ perimeter_id=perimeter_id, value=request.json)
+
return {"subjects": data}
+ @validate_input("delete", kwargs_state=[False, True, False])
@check_auth
def delete(self, uuid=None, perimeter_id=None, user_id=None):
"""Delete a subject for a given policy
- :param uuid: uuid of the policy
- :param perimeter_id: uuid of the subject
+ :param uuid: uuid of the policy (mandatory if perimeter_id is not set)
+ :param perimeter_id: uuid of the subject (mandatory if uuid is not set)
:param user_id: user ID who do the request
:return: {
"subject_id": {
"name": "name of the subject",
"keystone_id": "keystone id of the subject",
- "description": "description of the subject",
- "password": "password for the subject",
- "email": "email address of the subject"
+ "description": "description of the subject (optional)",
+ "password": "password for the subject (optional)",
+ "email": "email address of the subject (optional)"
}
}
:internal_api: delete_subject
"""
- try:
- data = PolicyManager.delete_subject(
- user_id=user_id, policy_id=uuid, perimeter_id=perimeter_id)
- except Exception as e:
- logger.error(e, exc_info=True)
- return {"result": False,
- "error": str(e)}, 500
+
+ data = PolicyManager.delete_subject(
+ user_id=user_id, policy_id=uuid, perimeter_id=perimeter_id)
+
return {"result": True}
@@ -190,6 +184,7 @@ class Objects(Resource):
"/policies/<string:uuid>/objects/<string:perimeter_id>",
)
+ @validate_input("get", kwargs_state=[False, False, False])
@check_auth
def get(self, uuid=None, perimeter_id=None, user_id=None):
"""Retrieve all objects or a specific one if perimeter_id is
@@ -201,60 +196,56 @@ class Objects(Resource):
:return: {
"object_id": {
"name": "name of the object",
- "description": "description of the object"
+ "description": "description of the object (optional)"
}
}
:internal_api: get_objects
"""
- try:
- data = PolicyManager.get_objects(
- user_id=user_id,
- policy_id=uuid,
- perimeter_id=perimeter_id
- )
- except Exception as e:
- logger.error(e, exc_info=True)
- return {"result": False,
- "error": str(e)}, 500
+
+ data = PolicyManager.get_objects(
+ user_id=user_id,
+ policy_id=uuid,
+ perimeter_id=perimeter_id
+ )
+
return {"objects": data}
+ @validate_input("post", body_state={"name":True})
@check_auth
- def post(self, uuid=None, perimeter_id=None, user_id=None):
+ def post(self, uuid, perimeter_id=None, user_id=None):
"""Create or update a object.
:param uuid: uuid of the policy
:param perimeter_id: must not be used here
:param user_id: user ID who do the request
:request body: {
- "object_name": "name of the object",
- "object_description": "description of the object"
+ "object_name": "name of the object (mandatory)",
+ "object_description": "description of the object (optional)"
}
:return: {
"object_id": {
"name": "name of the object",
- "description": "description of the object"
+ "description": "description of the object (optional)"
}
}
:internal_api: set_object
"""
- try:
- data = PolicyManager.get_objects(user_id=user_id, policy_id=None)
- if 'name' in request.json:
- for data_id, data_value in data.items():
- if data_value['name'] == request.json['name']:
- perimeter_id = data_id
- break
- data = PolicyManager.add_object(
- user_id=user_id, policy_id=uuid,
- perimeter_id=perimeter_id, value=request.json)
- except Exception as e:
- logger.error(e, exc_info=True)
- return {"result": False,
- "error": str(e)}, 500
+
+ data = PolicyManager.get_objects(user_id=user_id, policy_id=uuid)
+ if 'name' in request.json:
+ for data_id, data_value in data.items():
+ if data_value['name'] == request.json['name']:
+ perimeter_id = data_id
+ break
+ data = PolicyManager.add_object(
+ user_id=user_id, policy_id=uuid,
+ perimeter_id=perimeter_id, value=request.json)
+
return {"objects": data}
+ @validate_input("patch", kwargs_state=[False, True, False], body_state={"name":True})
@check_auth
- def patch(self, uuid=None, perimeter_id=None, user_id=None):
+ def patch(self, uuid, perimeter_id=None, user_id=None):
"""Create or update a object.
:param uuid: uuid of the policy
@@ -262,54 +253,49 @@ class Objects(Resource):
:param user_id: user ID who do the request
:request body: {
"object_name": "name of the object",
- "object_description": "description of the object"
+ "object_description": "description of the object (optional)"
}
:return: {
"object_id": {
"name": "name of the object",
- "description": "description of the object"
+ "description": "description of the object (optional)"
}
}
:internal_api: set_object
"""
- try:
- data = PolicyManager.get_objects(user_id=user_id, policy_id=None)
- if 'name' in request.json:
- for data_id, data_value in data.items():
- if data_value['name'] == request.json['name']:
- perimeter_id = data_id
- break
- data = PolicyManager.add_object(
- user_id=user_id, policy_id=uuid,
- perimeter_id=perimeter_id, value=request.json)
- except Exception as e:
- logger.error(e, exc_info=True)
- return {"result": False,
- "error": str(e)}, 500
+
+ data = PolicyManager.get_objects(user_id=user_id, policy_id=uuid)
+ if 'name' in request.json:
+ for data_id, data_value in data.items():
+ if data_value['name'] == request.json['name']:
+ perimeter_id = data_id
+ break
+ data = PolicyManager.add_object(
+ user_id=user_id, policy_id=uuid,
+ perimeter_id=perimeter_id, value=request.json)
+
return {"objects": data}
+ @validate_input("delete", kwargs_state=[False, True, False])
@check_auth
def delete(self, uuid=None, perimeter_id=None, user_id=None):
"""Delete a object for a given policy
- :param uuid: uuid of the policy
- :param perimeter_id: uuid of the object
+ :param uuid: uuid of the policy (mandatory if perimeter_id is not set)
+ :param perimeter_id: uuid of the object (mandatory if uuid is not set)
:param user_id: user ID who do the request
:return: {
"object_id": {
"name": "name of the object",
- "description": "description of the object"
+ "description": "description of the object (optional)"
}
}
:internal_api: delete_object
"""
- try:
- data = PolicyManager.delete_object(
- user_id=user_id, policy_id=uuid, perimeter_id=perimeter_id)
- except Exception as e:
- logger.error(e, exc_info=True)
- return {"result": False,
- "error": str(e)}, 500
+
+ data = PolicyManager.delete_object(
+ user_id=user_id, policy_id=uuid, perimeter_id=perimeter_id)
+
return {"result": True}
@@ -327,6 +313,7 @@ class Actions(Resource):
"/policies/<string:uuid>/actions/<string:perimeter_id>",
)
+ @validate_input("get", kwargs_state=[False, False, False])
@check_auth
def get(self, uuid=None, perimeter_id=None, user_id=None):
"""Retrieve all actions or a specific one if perimeter_id
@@ -338,57 +325,53 @@ class Actions(Resource):
:return: {
"action_id": {
"name": "name of the action",
- "description": "description of the action"
+ "description": "description of the action (optional)"
}
}
:internal_api: get_actions
"""
- try:
- data = PolicyManager.get_actions(
- user_id=user_id, policy_id=uuid, perimeter_id=perimeter_id)
- except Exception as e:
- logger.error(e, exc_info=True)
- return {"result": False,
- "error": str(e)}, 500
+
+ data = PolicyManager.get_actions(
+ user_id=user_id, policy_id=uuid, perimeter_id=perimeter_id)
+
return {"actions": data}
+ @validate_input("post", body_state={"name":True})
@check_auth
- def post(self, uuid=None, perimeter_id=None, user_id=None):
+ def post(self, uuid, perimeter_id=None, user_id=None):
"""Create or update a action.
:param uuid: uuid of the policy
:param perimeter_id: must not be used here
:param user_id: user ID who do the request
:request body: {
- "name": "name of the action",
- "description": "description of the action"
+ "name": "name of the action (mandatory)",
+ "description": "description of the action (optional)"
}
:return: {
"action_id": {
"name": "name of the action",
- "description": "description of the action"
+ "description": "description of the action (optional)"
}
}
:internal_api: set_action
"""
- try:
- data = PolicyManager.get_actions(user_id=user_id, policy_id=None)
- if 'name' in request.json:
- for data_id, data_value in data.items():
- if data_value['name'] == request.json['name']:
- perimeter_id = data_id
- break
- data = PolicyManager.add_action(
- user_id=user_id, policy_id=uuid,
- perimeter_id=perimeter_id, value=request.json)
- except Exception as e:
- logger.error(e, exc_info=True)
- return {"result": False,
- "error": str(e)}, 500
+
+ data = PolicyManager.get_actions(user_id=user_id, policy_id=uuid)
+ if 'name' in request.json:
+ for data_id, data_value in data.items():
+ if data_value['name'] == request.json['name']:
+ perimeter_id = data_id
+ break
+ data = PolicyManager.add_action(
+ user_id=user_id, policy_id=uuid,
+ perimeter_id=perimeter_id, value=request.json)
+
return {"actions": data}
+ @validate_input("patch", kwargs_state=[False, True, False], body_state={"name":True})
@check_auth
- def patch(self, uuid=None, perimeter_id=None, user_id=None):
+ def patch(self, uuid, perimeter_id=None, user_id=None):
"""Create or update a action.
:param uuid: uuid of the policy
@@ -396,52 +379,47 @@ class Actions(Resource):
:param user_id: user ID who do the request
:request body: {
"name": "name of the action",
- "description": "description of the action"
+ "description": "description of the action (optional)"
}
:return: {
"action_id": {
"name": "name of the action",
- "description": "description of the action"
+ "description": "description of the action (optional)"
}
}
:internal_api: set_action
"""
- try:
- data = PolicyManager.get_actions(user_id=user_id, policy_id=None)
- if 'name' in request.json:
- for data_id, data_value in data.items():
- if data_value['name'] == request.json['name']:
- perimeter_id = data_id
- break
- data = PolicyManager.add_action(
- user_id=user_id, policy_id=uuid,
- perimeter_id=perimeter_id, value=request.json)
- except Exception as e:
- logger.error(e, exc_info=True)
- return {"result": False,
- "error": str(e)}, 500
+
+ data = PolicyManager.get_actions(user_id=user_id, policy_id=uuid)
+ if 'name' in request.json:
+ for data_id, data_value in data.items():
+ if data_value['name'] == request.json['name']:
+ perimeter_id = data_id
+ break
+ data = PolicyManager.add_action(
+ user_id=user_id, policy_id=uuid,
+ perimeter_id=perimeter_id, value=request.json)
+
return {"actions": data}
+ @validate_input("delete", kwargs_state=[False, True, False])
@check_auth
def delete(self, uuid=None, perimeter_id=None, user_id=None):
"""Delete a action for a given policy
- :param uuid: uuid of the policy
- :param perimeter_id: uuid of the action
+ :param uuid: uuid of the policy (mandatory if perimeter_id is not set)
+ :param perimeter_id: uuid of the action (mandatory if uuid is not set)
:param user_id: user ID who do the request
:return: {
"action_id": {
"name": "name of the action",
- "description": "description of the action"
+ "description": "description of the action (optional)"
}
}
:internal_api: delete_action
"""
- try:
- data = PolicyManager.delete_action(
- user_id=user_id, policy_id=uuid, perimeter_id=perimeter_id)
- except Exception as e:
- logger.error(e, exc_info=True)
- return {"result": False,
- "error": str(e)}, 500
+
+ data = PolicyManager.delete_action(
+ user_id=user_id, policy_id=uuid, perimeter_id=perimeter_id)
+
return {"result": True}
diff --git a/moon_manager/moon_manager/api/policies.py b/moon_manager/moon_manager/api/policies.py
index 0d7a52a9..9fe237b2 100644
--- a/moon_manager/moon_manager/api/policies.py
+++ b/moon_manager/moon_manager/api/policies.py
@@ -12,6 +12,8 @@ from flask_restful import Resource
import logging
from python_moonutilities.security_functions import check_auth
from python_moondb.core import PolicyManager
+from python_moonutilities.security_functions import validate_input
+
__version__ = "4.3.2"
@@ -30,6 +32,7 @@ class Policies(Resource):
"/policies/<string:uuid>/",
)
+ @validate_input("get", kwargs_state=[False, False])
@check_auth
def get(self, uuid=None, user_id=None):
"""Retrieve all policies
@@ -38,53 +41,49 @@ class Policies(Resource):
:param user_id: user ID who do the request
:return: {
"policy_id1": {
- "name": "...",
- "model_id": "...",
- "genre": "...",
- "description": "...",
+ "name": "name of the policy (mandatory)",
+ "model_id": "ID of the model linked to this policy",
+ "genre": "authz of admin (optional, default to authz)",
+ "description": "description of the policy (optional)",
}
}
:internal_api: get_policies
"""
- try:
- data = PolicyManager.get_policies(user_id=user_id, policy_id=uuid)
- except Exception as e:
- logger.error(e, exc_info=True)
- return {"result": False,
- "error": str(e)}, 500
+
+ data = PolicyManager.get_policies(user_id=user_id, policy_id=uuid)
+
return {"policies": data}
+ @validate_input("post", body_state={"name": True, "model_id":True})
@check_auth
def post(self, uuid=None, user_id=None):
"""Create policy.
- :param uuid: uuid of the policy (not used here)
+ :param uuid: uuid of the policy (not used here if a new policy is created)
:param user_id: user ID who do the request
:request body: {
- "name": "...",
- "model_id": "...",
- "genre": "...",
- "description": "...",
+ "name": "name of the policy (mandatory)",
+ "model_id": "ID of the model linked to this policy",
+ "genre": "authz of admin (optional, default to authz)",
+ "description": "description of the policy (optional)",
}
:return: {
"policy_id1": {
- "name": "...",
- "model_id": "...",
- "genre": "...",
- "description": "...",
+ "name": "name of the policy (mandatory)",
+ "model_id": "ID of the model linked to this policy",
+ "genre": "authz of admin (optional, default to authz)",
+ "description": "description of the policy (optional)",
}
}
:internal_api: add_policy
"""
- try:
- data = PolicyManager.add_policy(
- user_id=user_id, policy_id=uuid, value=request.json)
- except Exception as e:
- logger.error(e, exc_info=True)
- return {"result": False,
- "error": str(e)}, 500
+
+ data = PolicyManager.add_policy(
+ user_id=user_id, policy_id=uuid, value=request.json)
+
return {"policies": data}
+ @validate_input("delete", kwargs_state=[ True, False])
@check_auth
def delete(self, uuid=None, user_id=None):
"""Delete a policy
@@ -93,18 +92,16 @@ class Policies(Resource):
:param user_id: user ID who do the request
:return: {
"result": "True or False",
- "message": "optional message"
+ "message": "optional message (optional)"
}
:internal_api: delete_policy
"""
- try:
- data = PolicyManager.delete_policy(user_id=user_id, policy_id=uuid)
- except Exception as e:
- logger.error(e, exc_info=True)
- return {"result": False,
- "error": str(e)}, 500
+
+ data = PolicyManager.delete_policy(user_id=user_id, policy_id=uuid)
+
return {"result": True}
+ @validate_input("patch", kwargs_state=[True, False], body_state={"name": True, "model_id":True})
@check_auth
def patch(self, uuid=None, user_id=None):
"""Update a policy
@@ -113,20 +110,17 @@ class Policies(Resource):
:param user_id: user ID who do the request
:return: {
"policy_id1": {
- "name": "...",
- "model_id": "...",
- "genre": "...",
- "description": "...",
+ "name": "name of the policy (mandatory)",
+ "model_id": "ID of the model linked to this policy",
+ "genre": "authz of admin (optional, default to authz)",
+ "description": "description of the policy (optional)",
}
}
:internal_api: update_policy
"""
- try:
- data = PolicyManager.update_policy(
- user_id=user_id, policy_id=uuid, value=request.json)
- except Exception as e:
- logger.error(e, exc_info=True)
- return {"result": False,
- "error": str(e)}, 500
+
+ data = PolicyManager.update_policy(
+ user_id=user_id, policy_id=uuid, value=request.json)
+
return {"policies": data}
diff --git a/moon_manager/moon_manager/api/rules.py b/moon_manager/moon_manager/api/rules.py
index e6c46bf4..a0248097 100644
--- a/moon_manager/moon_manager/api/rules.py
+++ b/moon_manager/moon_manager/api/rules.py
@@ -11,6 +11,7 @@ from flask_restful import Resource
import logging
from python_moonutilities.security_functions import check_auth
from python_moondb.core import PolicyManager
+from python_moonutilities.security_functions import validate_input
__version__ = "4.3.2"
@@ -28,6 +29,7 @@ class Rules(Resource):
"/policies/<string:uuid>/rules/<string:rule_id>/",
)
+ @validate_input("get", kwargs_state=[False, False, False])
@check_auth
def get(self, uuid=None, rule_id=None, user_id=None):
"""Retrieve all rules or a specific one
@@ -40,34 +42,32 @@ class Rules(Resource):
"policy_id": "policy_id1",
"meta_rule_id": "meta_rule_id1",
"rule_id1":
- ["subject_data_id1", "object_data_id1", "action_data_id1"],
+ ["subject_data_id1", "subject_data_id2", "object_data_id1", "action_data_id1"],
"rule_id2":
- ["subject_data_id2", "object_data_id2", "action_data_id2"],
+ ["subject_data_id3", "subject_data_id4", "object_data_id2", "action_data_id2"],
]
}
:internal_api: get_rules
"""
- try:
- data = PolicyManager.get_rules(user_id=user_id,
+
+ data = PolicyManager.get_rules(user_id=user_id,
policy_id=uuid,
rule_id=rule_id)
- except Exception as e:
- logger.error(e, exc_info=True)
- return {"result": False,
- "error": str(e)}, 500
+
return {"rules": data}
+ @validate_input("post", kwargs_state=[True, False, False], body_state={"meta_rule_id": True, "rule": True, "instructions": True})
@check_auth
def post(self, uuid=None, rule_id=None, user_id=None):
"""Add a rule to a meta rule
:param uuid: policy ID
- :param rule_id: rule ID
+ :param rule_id: rule ID (not used here)
:param user_id: user ID who do the request
:request body: post = {
- "meta_rule_id": "meta_rule_id1",
- "rule": ["subject_data_id2", "object_data_id2", "action_data_id2"],
- "instructions": (
+ "meta_rule_id": "meta_rule_id1", # mandatory
+ "rule": ["subject_data_id2", "object_data_id2", "action_data_id2"], # mandatory
+ "instructions": ( # mandatory
{"decision": "grant"},
)
"enabled": True
@@ -108,17 +108,15 @@ class Rules(Resource):
:internal_api: add_rule
"""
args = request.json
- try:
- data = PolicyManager.add_rule(user_id=user_id,
- policy_id=uuid,
- meta_rule_id=args['meta_rule_id'],
- value=args)
- except Exception as e:
- logger.error(e, exc_info=True)
- return {"result": False,
- "error": str(e)}, 500
+
+ data = PolicyManager.add_rule(user_id=user_id,
+ policy_id=uuid,
+ meta_rule_id=args['meta_rule_id'],
+ value=args)
+
return {"rules": data}
+ @validate_input("delete", kwargs_state=[True, True, False])
@check_auth
def delete(self, uuid=None, rule_id=None, user_id=None):
"""Delete one rule linked to a specific sub meta rule
@@ -129,12 +127,9 @@ class Rules(Resource):
:return: { "result": true }
:internal_api: delete_rule
"""
- try:
- data = PolicyManager.delete_rule(
- user_id=user_id, policy_id=uuid, rule_id=rule_id)
- except Exception as e:
- logger.error(e, exc_info=True)
- return {"result": False,
- "error": str(e)}, 500
+
+ data = PolicyManager.delete_rule(
+ user_id=user_id, policy_id=uuid, rule_id=rule_id)
+
return {"result": True}
diff --git a/moon_manager/moon_manager/api/slaves.py b/moon_manager/moon_manager/api/slaves.py
index f5b3fa14..769b681f 100644
--- a/moon_manager/moon_manager/api/slaves.py
+++ b/moon_manager/moon_manager/api/slaves.py
@@ -11,12 +11,11 @@ from flask import request
from flask_restful import Resource
import logging
import requests
-import time
from python_moonutilities.security_functions import check_auth
-from python_moondb.core import PDPManager
-from python_moondb.core import PolicyManager
-from python_moondb.core import ModelManager
-from python_moonutilities import configuration, exceptions
+
+from python_moonutilities import configuration
+from python_moonutilities.security_functions import validate_input
+
__version__ = "4.3.0"
@@ -42,6 +41,7 @@ class Slaves(Resource):
self.orchestrator_port = conf["components/orchestrator"].get("port",
80)
+ @validate_input("get", kwargs_state=[False, False])
@check_auth
def get(self, uuid=None, user_id=None):
"""Retrieve all slaves
@@ -66,6 +66,8 @@ class Slaves(Resource):
))
return {"slaves": req.json().get("slaves", dict())}
+ @validate_input("patch", kwargs_state=[False, False],
+ body_state={"op": True, "variable": True, "value": True})
@check_auth
def patch(self, uuid=None, user_id=None):
"""Update a slave
diff --git a/moon_manager/moon_manager/http_server.py b/moon_manager/moon_manager/http_server.py
index a98cab43..204e7e04 100644
--- a/moon_manager/moon_manager/http_server.py
+++ b/moon_manager/moon_manager/http_server.py
@@ -2,9 +2,9 @@
# 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'.
-
-from flask import Flask, jsonify
+from flask import Flask, jsonify, Response, make_response
from flask_cors import CORS, cross_origin
+from json import dumps
from flask_restful import Resource, Api
import logging
import sqlalchemy.exc
@@ -21,7 +21,9 @@ from moon_manager.api.perimeter import Subjects, Objects, Actions
from moon_manager.api.data import SubjectData, ObjectData, ActionData
from moon_manager.api.assignments import SubjectAssignments, ObjectAssignments, ActionAssignments
from moon_manager.api.rules import Rules
-from python_moonutilities import configuration, exceptions
+from moon_manager.api.json_import import JsonImport
+from moon_manager.api.json_export import JsonExport
+from python_moonutilities import configuration
from python_moondb.core import PDPManager
@@ -33,7 +35,7 @@ __API__ = (
Subjects, Objects, Actions, Rules,
SubjectAssignments, ObjectAssignments, ActionAssignments,
SubjectData, ObjectData, ActionData,
- Models, Policies, PDP, Slaves
+ Models, Policies, PDP, Slaves, JsonImport, JsonExport
)
@@ -98,38 +100,41 @@ class Root(Resource):
if _method in dir(item):
_methods.append(_method)
tree[item.__name__]["methods"] = _methods
- tree[item.__name__]["description"] = item.__doc__.strip()
+ tree[item.__name__]["description"] = item.__doc__.strip() if item.__doc__ else ""
return {
"version": __version__,
"tree": tree
}
+class CustomApi(Api):
+
+ @staticmethod
+ def handle_error(e):
+ try:
+ error_message = dumps({"result": False, 'message': str(e), "code": getattr(e, "code", 500)})
+ logger.error(e, exc_info=True)
+ logger.error(error_message)
+ return make_response(error_message, getattr(e, "code", 500))
+ except Exception as e2: # unhandled exception in the api...
+ logger.exception(str(e2))
+ return make_response(error_message, 500)
+
+
class HTTPServer(Server):
def __init__(self, host="localhost", port=80, **kwargs):
super(HTTPServer, self).__init__(host=host, port=port, **kwargs)
self.app = Flask(__name__)
+ self.app.config['TRAP_HTTP_EXCEPTIONS'] = True
conf = configuration.get_configuration("components/manager")
self.manager_hostname = conf["components/manager"].get("hostname",
"manager")
self.manager_port = conf["components/manager"].get("port", 80)
# TODO : specify only few urls instead of *
CORS(self.app)
- self.api = Api(self.app)
+ self.api = CustomApi(self.app, catch_all_404s=True)
self.__set_route()
- self.__hook_errors()
-
- def __hook_errors(self):
-
- def get_404_json(e):
- return jsonify({"result": False, "code": 404, "description": str(e)}), 404
- self.app.register_error_handler(404, get_404_json)
-
- def get_400_json(e):
- return jsonify({"result": False, "code": 400, "description": str(e)}), 400
- self.app.register_error_handler(400, lambda e: get_400_json)
- self.app.register_error_handler(403, exceptions.AuthException)
def __set_route(self):
self.api.add_resource(Root, '/')
@@ -143,7 +148,7 @@ class HTTPServer(Server):
while True:
try:
PDPManager.get_pdp(user_id="admin", pdp_id=None)
- except sqlalchemy.exc.ProgrammingError:
+ except (sqlalchemy.exc.ProgrammingError, sqlalchemy.exc.InternalError):
time.sleep(1)
if first:
logger.warning("Waiting for the database...")
@@ -154,4 +159,4 @@ class HTTPServer(Server):
def run(self):
self.__check_if_db_is_up()
- self.app.run(debug=True, host=self._host, port=self._port) # nosec
+ self.app.run(host=self._host, port=self._port, threaded=True) # nosec
diff --git a/moon_manager/moon_manager/server.py b/moon_manager/moon_manager/server.py
index 70ddaee0..a8db8fd5 100644
--- a/moon_manager/moon_manager/server.py
+++ b/moon_manager/moon_manager/server.py
@@ -7,6 +7,7 @@ import logging
from python_moonutilities import configuration, exceptions
from moon_manager.http_server import HTTPServer
+
logger = logging.getLogger("moon.manager.server")
diff --git a/moon_manager/tests/functional_pod/json/mls.json b/moon_manager/tests/functional_pod/json/mls.json
new file mode 100644
index 00000000..01ef6deb
--- /dev/null
+++ b/moon_manager/tests/functional_pod/json/mls.json
@@ -0,0 +1,89 @@
+{
+ "pdps": [{"name" : "pdp_mls", "keystone_project_id" : "", "description": "", "policies": [{"name": "MLS policy example"}]}],
+
+ "policies":[{ "name": "MLS policy example", "genre": "authz", "description": "", "model": {"name": "MLS"} , "mandatory" :false , "override":true}],
+
+ "models":[{"name":"MLS", "description":"","meta_rules": [{"name" : "mls"}], "override":true}],
+
+
+
+
+
+ "subjects": [{ "name":"adminuser", "description": "", "extra": {}, "policies": [{ "name": "MLS policy example"}]} ,
+ { "name": "user1", "description": "", "extra": {}, "policies": [{ "name": "MLS policy example"}] },
+ { "name": "user2", "description": "", "extra": {}, "policies": [{ "name": "MLS policy example"}] }],
+
+ "subject_categories": [{ "name":"subject-security-level", "description": "" }],
+
+ "subject_data": [{ "name":"low", "description": "", "policies": [{"name" :"MLS policy example"}], "category": {"name": "subject-security-level"}},
+ { "name":"medium", "description": "", "policies": [{"name" :"MLS policy example"}], "category": {"name": "subject-security-level"}},
+ { "name":"high", "description": "", "policies": [{"name" :"MLS policy example"}], "category": {"name": "subject-security-level"}}],
+
+ "subject_assignments":[{ "subject" : {"name": "adminuser"}, "category" : {"name": "subject-security-level"}, "assignments": [{"name" : "high"}]},
+ { "subject" : {"name": "user1"}, "category" : {"name": "subject-security-level"}, "assignments": [{"name" : "medium"}] }],
+
+
+
+
+
+
+ "objects": [{ "name":"vm0", "description": "", "extra": {}, "policies": [{"name": "MLS policy example"}]} ,
+ {"name": "vm1", "description": "", "extra": {}, "policies": [{"name": "MLS policy example"}]} ],
+
+ "object_categories": [{"name":"object-security-level", "description": ""}],
+
+ "object_data": [{ "name":"low", "description": "", "policies": [{"name" :"MLS policy example"}], "category": {"name": "object-security-level"}},
+ { "name":"medium", "description": "", "policies": [{"name" :"MLS policy example"}], "category": {"name": "object-security-level"}},
+ { "name":"high", "description": "", "policies": [{"name" :"MLS policy example"}], "category": {"name": "object-security-level"}}],
+
+ "object_assignments":[{ "object" : {"name": "vm0"}, "category" : {"name": "object-security-level"}, "assignments": [{"name" : "medium"}]},
+ { "object" : {"name": "vm1"}, "category" : {"name": "object-security-level"}, "assignments": [{"name" : "low"}]}],
+
+
+
+
+
+
+ "actions": [{ "name": "start", "description": "", "extra": {}, "policies": [{"name": "MLS policy example"}]} ,
+ { "name": "stop", "description": "", "extra": {}, "policies": [{"name": "MLS policy example"}]}],
+
+ "action_categories": [{"name":"action-type", "description": ""}],
+
+ "action_data": [{"name":"vm-action", "description": "", "policies": [{"name": "MLS policy example"}], "category": {"name": "action-type"}},
+ {"name":"storage-action", "description": "", "policies": [{"name" :"MLS policy example"}], "category": {"name": "action-type"}}],
+
+ "action_assignments":[{ "action" : {"name": "start"}, "category" : {"name": "action-type"}, "assignments": [{"name" : "vm-action"}]},
+ { "action" : {"name": "stop"}, "category" : {"name": "action-type"}, "assignments": [{"name" : "vm-action"}]}],
+
+
+
+
+
+
+ "meta_rules":[{"name":"mls", "description": "",
+ "subject_categories": [{"name": "subject-security-level"}],
+ "object_categories": [{"name": "object-security-level"}],
+ "action_categories": [{"name": "action-type"}]
+ }],
+
+ "rules": [{
+ "meta_rule": {"name" : "mls"},
+ "rule": {"subject_data" : [{"name":"high"}], "object_data": [{"name": "medium"}], "action_data": [{"name": "vm-action"}]},
+ "policy": {"name" :"MLS policy example"},
+ "instructions" : {"decision" : "grant"}
+ }, {
+ "meta_rule": {"name" : "mls"},
+ "rule": {"subject_data" : [{"name":"high"}], "object_data": [{"name": "low"}], "action_data": [{"name": "vm-action"}]},
+ "policy": {"name" :"MLS policy example"},
+ "instructions" : {"decision" : "grant"}
+ }, {
+ "meta_rule": {"name" : "mls"},
+ "rule": {"subject_data" : [{"name":"medium"}], "object_data": [{"name": "low"}], "action_data": [{"name": "vm-action"}]},
+ "policy": {"name" :"MLS policy example"},
+ "instructions" : {"decision" : "grant"}
+ }]
+
+
+
+
+} \ No newline at end of file
diff --git a/moon_manager/tests/functional_pod/json/rbac.json b/moon_manager/tests/functional_pod/json/rbac.json
new file mode 100644
index 00000000..a75f291b
--- /dev/null
+++ b/moon_manager/tests/functional_pod/json/rbac.json
@@ -0,0 +1,85 @@
+{
+ "pdps": [{"name" : "pdp_rbac", "keystone_project_id" : "", "description": "", "policies": [{"name": "RBAC policy example"}]}],
+
+ "policies":[{ "name": "RBAC policy example", "genre": "authz", "description": "", "model": {"name": "RBAC"} , "mandatory" :true , "override":true}],
+
+ "models":[{"name":"RBAC", "description":"","meta_rules": [{"name" : "rbac"}], "override":true}],
+
+
+
+
+
+ "subjects": [{ "name":"adminuser", "description": "", "extra": {}, "policies": [{ "name": "RBAC policy example"}]} ,
+ { "name": "user1", "description": "", "extra": {}, "policies": [{ "name": "RBAC policy example"}] },
+ { "name": "public", "description": "", "extra": {}, "policies": [] }],
+
+ "subject_categories": [{ "name":"role", "description": "" }],
+
+ "subject_data": [{ "name":"admin", "description": "", "policies": [{"name" :"RBAC policy example"}], "category": {"name": "role"}},
+ { "name":"employee", "description": "", "policies": [{"name" :"RBAC policy example"}], "category": {"name": "role"}},
+ { "name":"*", "description": "", "policies": [{"name" :"RBAC policy example"}], "category": {"name": "role"}}],
+
+ "subject_assignments":[{ "subject" : {"name": "adminuser"}, "category" : {"name": "role"}, "assignments": [{"name" : "admin"}, {"name" : "employee"}, {"name" : "*"}]},
+ { "subject" : {"name": "user1"}, "category" : {"name": "role"}, "assignments": [{"name" : "employee"}, {"name" : "*"}] }],
+
+
+
+
+
+
+ "objects": [{ "name":"vm0", "description": "", "extra": {}, "policies": [{"name": "RBAC policy example"}]} ,
+ {"name": "vm1", "description": "", "extra": {}, "policies": [{"name": "RBAC policy example"}]} ],
+
+ "object_categories": [{"name":"id", "description": ""}],
+
+ "object_data": [{ "name":"vm0", "description": "", "policies": [{"name" :"RBAC policy example"}], "category": {"name": "id"}},
+ { "name":"vm1", "description": "", "policies": [{"name" :"RBAC policy example"}], "category": {"name": "id"}},
+ { "name":"*", "description": "", "policies": [{"name" :"RBAC policy example"}], "category": {"name": "id"}}],
+
+ "object_assignments":[{ "object" : {"name": "vm0"}, "category" : {"name": "id"}, "assignments": [{"name" : "vm0"}, {"name" : "*"}]},
+ { "object" : {"name": "vm1"}, "category" : {"name": "id"}, "assignments": [{"name" : "vm1"}, {"name" : "*"}]}],
+
+
+
+
+
+
+ "actions": [{ "name": "start", "description": "", "extra": {}, "policies": [{"name": "RBAC policy example"}]} ,
+ { "name": "stop", "description": "", "extra": {}, "policies": [{"name": "RBAC policy example"}]}],
+
+ "action_categories": [{"name":"action-type", "description": ""}],
+
+ "action_data": [{"name":"vm-action", "description": "", "policies": [{"name": "RBAC policy example"}], "category": {"name": "action-type"}},
+ {"name":"*", "description": "", "policies": [{"name" :"RBAC policy example"}], "category": {"name": "action-type"}}],
+
+ "action_assignments":[{ "action" : {"name": "start"}, "category" : {"name": "action-type"}, "assignments": [{"name" : "vm-action"}, {"name" : "*"}]},
+ { "action" : {"name": "stop"}, "category" : {"name": "action-type"}, "assignments": [{"name" : "vm-action"}, {"name" : "*"}]}],
+
+
+
+
+
+
+ "meta_rules":[{"name":"rbac", "description": "",
+ "subject_categories": [{"name": "role"}],
+ "object_categories": [{"name": "id"}],
+ "action_categories": [{"name": "action-type"}]
+ }],
+
+ "rules": [{
+ "meta_rule": {"name" : "rbac"},
+ "rule": {"subject_data" : [{"name":"admin"}], "object_data": [{"name": "vm0"}], "action_data": [{"name": "vm-action"}]},
+ "policy": {"name" :"RBAC policy example"},
+ "instructions" : {"decision" : "grant"},
+ "enabled": true
+ }, {
+ "meta_rule": {"name" : "rbac"},
+ "rule": {"subject_data" : [{"name":"employee"}], "object_data": [{"name": "vm1"}], "action_data": [{"name": "vm-action"}]},
+ "policy": {"name" :"RBAC policy example"},
+ "instructions" : {"decision" : "grant"}
+ }]
+
+
+
+
+} \ No newline at end of file
diff --git a/moon_manager/tests/functional_pod/run_functional_tests.sh b/moon_manager/tests/functional_pod/run_functional_tests.sh
index 7a95a491..960e9480 100644
--- a/moon_manager/tests/functional_pod/run_functional_tests.sh
+++ b/moon_manager/tests/functional_pod/run_functional_tests.sh
@@ -1,4 +1,11 @@
#!/usr/bin/env bash
+if [ -d /data/dist ];
+then
+ pip install /data/dist/*.tar.gz --upgrade
+ pip install /data/dist/*.whl --upgrade
+fi
+
+
cd /data/tests/functional_pod
pytest .
diff --git a/moon_manager/tests/functional_pod/test_manager.py b/moon_manager/tests/functional_pod/test_manager.py
index aab5fba4..454d861b 100644
--- a/moon_manager/tests/functional_pod/test_manager.py
+++ b/moon_manager/tests/functional_pod/test_manager.py
@@ -1,6 +1,45 @@
import json
import requests
+def test_import_rbac(context):
+ files = {'file': open('/data/tests/functional_pod/json/rbac.json', 'r')}
+ req = requests.post("http://{}:{}/import".format(
+ context.get("hostname"),
+ context.get("port"))
+ , files=files)
+ print(req)
+ result = req.json()
+ print(result)
+ req.raise_for_status()
+
+def test_import_mls(context):
+ files = {'file': open('/data/tests/functional_pod/json/mls.json', 'r')}
+ req = requests.post("http://{}:{}/import".format(
+ context.get("hostname"),
+ context.get("port"))
+ , files=files)
+ req.raise_for_status()
+
+
+def test_export_rbac(context):
+ test_import_rbac(context)
+ req = requests.get("http://{}:{}/export".format(
+ context.get("hostname"),
+ context.get("port")),
+ data={"filename":"/data/tests/functional_pod/json/rbac_export.json"}
+ )
+ req.raise_for_status()
+
+
+def test_export_mls(context):
+ test_import_mls(context)
+ req = requests.get("http://{}:{}/export".format(
+ context.get("hostname"),
+ context.get("port")),
+ data={"filename":"/data/tests/functional_pod/json/mls_export.json"}
+ )
+ req.raise_for_status()
+
def get_json(data):
return json.loads(data.decode("utf-8"))
diff --git a/moon_manager/tests/functional_pod/test_models.py b/moon_manager/tests/functional_pod/test_models.py
index dcda9f32..8b4ceef5 100644
--- a/moon_manager/tests/functional_pod/test_models.py
+++ b/moon_manager/tests/functional_pod/test_models.py
@@ -32,9 +32,10 @@ def delete_models(context, name):
request = None
for key, value in models['models'].items():
if value['name'] == name:
- request = requests.delete("http://{}:{}/models/{}".format(key,
+ request = requests.delete("http://{}:{}/models/{}".format(
context.get("hostname"),
- context.get("port")),
+ context.get("port"),
+ key),
timeout=3)
break
return request
diff --git a/moon_manager/tests/unit_python/api/import_export_utilities.py b/moon_manager/tests/unit_python/api/import_export_utilities.py
new file mode 100644
index 00000000..12cb208e
--- /dev/null
+++ b/moon_manager/tests/unit_python/api/import_export_utilities.py
@@ -0,0 +1,196 @@
+# Copyright 2018 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 api.test_unit_models as test_models
+import api.test_policies as test_policies
+import api.test_perimeter as test_perimeter
+import api.test_meta_data as test_categories
+import api.test_data as test_data
+import api.test_meta_rules as test_meta_rules
+import api.test_assignemnt as test_assignments
+import api.test_rules as test_rules
+import logging
+
+logger = logging.getLogger("moon.manager.test.api." + __name__)
+
+
+def clean_models(client):
+ req, models = test_models.get_models(client)
+ for key in models["models"]:
+ client.delete("/models/{}".format(key))
+
+
+def clean_policies(client):
+ req, policies = test_policies.get_policies(client)
+ for key in policies["policies"]:
+ req = client.delete("/policies/{}".format(key))
+ assert req.status_code == 200
+
+
+def clean_subjects(client):
+ subjects = test_perimeter.get_subjects(client)
+ logger.info("subjects {}".format(subjects))
+ for key in subjects[1]["subjects"]:
+ subject = subjects[1]["subjects"][key]
+ policy_keys = subject["policy_list"]
+ logger.info("subjects policy_keys {}".format(policy_keys))
+ for policy_key in policy_keys:
+ client.delete("/policies/{}/subjects/{}".format(policy_key, key))
+ client.delete("/subjects/{}".format(key))
+
+
+def clean_objects(client):
+ objects = test_perimeter.get_objects(client)
+ logger.info("objects {}".format(objects))
+ for key in objects[1]["objects"]:
+ object_ = objects[1]["objects"][key]
+ policy_keys = object_["policy_list"]
+ logger.info("objects policy_keys {}".format(policy_keys))
+ for policy_key in policy_keys:
+ client.delete("/policies/{}/objects/{}".format(policy_key, key))
+ client.delete("/objects/{}".format(key))
+
+
+def clean_actions(client):
+ actions = test_perimeter.get_actions(client)
+ logger.info("actions {}".format(actions))
+ for key in actions[1]["actions"]:
+ action = actions[1]["actions"][key]
+ policy_keys = action["policy_list"]
+ logger.info("action policy_keys {}".format(policy_keys))
+ for policy_key in policy_keys:
+ client.delete("/policies/{}/actions/{}".format(policy_key, key))
+ client.delete("/actions/{}".format(key))
+
+
+def clean_subject_categories(client):
+ req, categories = test_categories.get_subject_categories(client)
+ logger.info(categories)
+ for key in categories["subject_categories"]:
+ client.delete("/subject_categories/{}".format(key))
+
+
+def clean_object_categories(client):
+ req, categories = test_categories.get_object_categories(client)
+ logger.info(categories)
+ for key in categories["object_categories"]:
+ client.delete("/object_categories/{}".format(key))
+
+
+def clean_action_categories(client):
+ req, categories = test_categories.get_action_categories(client)
+ logger.info(categories)
+ for key in categories["action_categories"]:
+ client.delete("/action_categories/{}".format(key))
+
+
+def clean_subject_data(client):
+ req, policies = test_policies.get_policies(client)
+ logger.info("clean_subject_data on {}".format(policies))
+ for policy_key in policies["policies"]:
+ req, data = test_data.get_subject_data(client, policy_id=policy_key)
+ logger.info("============= data {}".format(data))
+ for key in data["subject_data"]:
+ logger.info("============= Deleting {}/{}".format(policy_key, key))
+ client.delete("/policies/{}/subject_data/{}".format(policy_key, key))
+
+
+def clean_object_data(client):
+ req, policies = test_policies.get_policies(client)
+ for policy_key in policies["policies"]:
+ req, data = test_data.get_object_data(client, policy_id=policy_key)
+ for key in data["object_data"]:
+ client.delete("/policies/{}/object_data/{}".format(policy_key, key))
+
+
+def clean_action_data(client):
+ req, policies = test_policies.get_policies(client)
+ for policy_key in policies["policies"]:
+ req, data = test_data.get_action_data(client, policy_id=policy_key)
+ for key in data["action_data"]:
+ client.delete("/policies/{}/action_data/{}".format(policy_key, key))
+
+
+def clean_meta_rule(client):
+ req, meta_rules = test_meta_rules.get_meta_rules(client)
+ meta_rules = meta_rules["meta_rules"]
+ for meta_rule_key in meta_rules:
+ logger.info("clean_meta_rule.meta_rule_key={}".format(meta_rule_key))
+ logger.info("clean_meta_rule.meta_rule={}".format(meta_rules[meta_rule_key]))
+ client.delete("/meta_rules/{}".format(meta_rule_key))
+
+
+def clean_subject_assignments(client):
+ req, policies = test_policies.get_policies(client)
+ for policy_key in policies["policies"]:
+ req, assignments = test_assignments.get_subject_assignment(client, policy_key)
+ for key in assignments["subject_assignments"]:
+ subject_key = assignments["subject_assignments"][key]["subject_id"]
+ cat_key = assignments["subject_assignments"][key]["category_id"]
+ data_keys = assignments["subject_assignments"][key]["assignments"]
+ for data_key in data_keys:
+ client.delete("/policies/{}/subject_assignments/{}/{}/{}".format(policy_key, subject_key,
+ cat_key, data_key))
+
+
+def clean_object_assignments(client):
+ req, policies = test_policies.get_policies(client)
+ for policy_key in policies["policies"]:
+ req, assignments = test_assignments.get_object_assignment(client, policy_key)
+ for key in assignments["object_assignments"]:
+ object_key = assignments["object_assignments"][key]["object_id"]
+ cat_key = assignments["object_assignments"][key]["category_id"]
+ data_keys = assignments["object_assignments"][key]["assignments"]
+ for data_key in data_keys:
+ client.delete("/policies/{}/object_assignments/{}/{}/{}".format(policy_key, object_key,
+ cat_key, data_key))
+
+
+def clean_action_assignments(client):
+ req, policies = test_policies.get_policies(client)
+ for policy_key in policies["policies"]:
+ req, assignments = test_assignments.get_action_assignment(client, policy_key)
+ for key in assignments["action_assignments"]:
+ action_key = assignments["action_assignments"][key]["action_id"]
+ cat_key = assignments["action_assignments"][key]["category_id"]
+ data_keys = assignments["action_assignments"][key]["assignments"]
+ for data_key in data_keys:
+ client.delete("/policies/{}/action_assignments/{}/{}/{}".format(policy_key, action_key,
+ cat_key, data_key))
+
+
+def clean_rules(client):
+ req, policies = test_policies.get_policies(client)
+ for policy_key in policies["policies"]:
+ req, rules = test_rules.get_rules(client, policy_key)
+ rules = rules["rules"]
+ rules = rules["rules"]
+ for rule_key in rules:
+ client.delete("/policies/{}/rules/{}".format(policy_key, rule_key))
+
+
+def clean_all(client):
+ clean_rules(client)
+
+ clean_subject_assignments(client)
+ clean_object_assignments(client)
+ clean_action_assignments(client)
+
+ clean_meta_rule(client)
+
+ clean_subject_data(client)
+ clean_object_data(client)
+ clean_action_data(client)
+
+ clean_actions(client)
+ clean_objects(client)
+ clean_subjects(client)
+
+ clean_subject_categories(client)
+ clean_object_categories(client)
+ clean_action_categories(client)
+
+ clean_policies(client)
+ clean_models(client)
diff --git a/moon_manager/tests/unit_python/api/meta_data_test.py b/moon_manager/tests/unit_python/api/meta_data_test.py
index 8fb39ae1..8609f0b5 100644
--- a/moon_manager/tests/unit_python/api/meta_data_test.py
+++ b/moon_manager/tests/unit_python/api/meta_data_test.py
@@ -54,6 +54,20 @@ def test_add_subject_categories():
assert value['description'] == "description of {}".format("testuser")
+def test_add_subject_categories_with_empty_user():
+ client = utilities.register_client()
+ req, subject_categories = add_subject_categories(client, "")
+ assert req.status_code == 500
+ assert json.loads(req.data)["message"] == "Empty String"
+
+
+def test_add_subject_categories_with_user_contain_space():
+ client = utilities.register_client()
+ req, subject_categories = add_subject_categories(client, "test user")
+ assert req.status_code == 500
+ assert json.loads(req.data)["message"] == "String contains space"
+
+
def test_delete_subject_categories():
client = utilities.register_client()
req = delete_subject_categories(client, "testuser")
@@ -119,6 +133,20 @@ def test_add_object_categories():
assert value['description'] == "description of {}".format("testuser")
+def test_add_object_categories_with_empty_user():
+ client = utilities.register_client()
+ req, object_categories = add_object_categories(client, "")
+ assert req.status_code == 500
+ assert json.loads(req.data)["message"] == "Empty String"
+
+
+def test_add_object_categories_with_user_contain_space():
+ client = utilities.register_client()
+ req, object_categories = add_object_categories(client, "test user")
+ assert req.status_code == 500
+ assert json.loads(req.data)["message"] == "String contains space"
+
+
def test_delete_object_categories():
client = utilities.register_client()
req = delete_object_categories(client, "testuser")
@@ -184,6 +212,20 @@ def test_add_action_categories():
assert value['description'] == "description of {}".format("testuser")
+def test_add_action_categories_with_empty_user():
+ client = utilities.register_client()
+ req, action_categories = add_action_categories(client, "")
+ assert req.status_code == 500
+ assert json.loads(req.data)["message"] == "Empty String"
+
+
+def test_add_action_categories_with_user_contain_space():
+ client = utilities.register_client()
+ req, action_categories = add_action_categories(client, "test user")
+ assert req.status_code == 500
+ assert json.loads(req.data)["message"] == "String contains space"
+
+
def test_delete_action_categories():
client = utilities.register_client()
req = delete_action_categories(client, "testuser")
@@ -193,4 +235,4 @@ def test_delete_action_categories():
def test_delete_action_categories_without_id():
client = utilities.register_client()
req = delete_action_categories_without_id(client)
- assert req.status_code == 500 \ No newline at end of file
+ assert req.status_code == 500
diff --git a/moon_manager/tests/unit_python/api/meta_rules_test.py b/moon_manager/tests/unit_python/api/meta_rules_test.py
index b5b1ecf8..a87c16f3 100644
--- a/moon_manager/tests/unit_python/api/meta_rules_test.py
+++ b/moon_manager/tests/unit_python/api/meta_rules_test.py
@@ -22,6 +22,46 @@ def add_meta_rules(client, name):
return req, meta_rules
+def add_meta_rules_without_subject_category_ids(client, name):
+ data = {
+ "name": name,
+ "subject_categories": [],
+ "object_categories": ["object_category_id1"],
+ "action_categories": ["action_category_id1"]
+ }
+ req = client.post("/meta_rules", data=json.dumps(data),
+ headers={'Content-Type': 'application/json'})
+ meta_rules = utilities.get_json(req.data)
+ return req, meta_rules
+
+
+def update_meta_rules(client, name, metaRuleId):
+ data = {
+ "name": name,
+ "subject_categories": ["subject_category_id1_update",
+ "subject_category_id2_update"],
+ "object_categories": ["object_category_id1_update"],
+ "action_categories": ["action_category_id1_update"]
+ }
+ req = client.patch("/meta_rules/{}".format(metaRuleId), data=json.dumps(data),
+ headers={'Content-Type': 'application/json'})
+ meta_rules = utilities.get_json(req.data)
+ return req, meta_rules
+
+
+def update_meta_rules_without_subject_category_ids(client, name):
+ data = {
+ "name": name,
+ "subject_categories": [],
+ "object_categories": ["object_category_id1"],
+ "action_categories": ["action_category_id1"]
+ }
+ req = client.post("/meta_rules", data=json.dumps(data),
+ headers={'Content-Type': 'application/json'})
+ meta_rules = utilities.get_json(req.data)
+ return req, meta_rules
+
+
def delete_meta_rules(client, name):
request, meta_rules = get_meta_rules(client)
for key, value in meta_rules['meta_rules'].items():
@@ -57,6 +97,27 @@ def test_add_meta_rules():
assert value["action_categories"][0] == "action_category_id1"
+def test_add_meta_rules_with_empty_user():
+ client = utilities.register_client()
+ req, meta_rules = add_meta_rules(client, "")
+ assert req.status_code == 500
+ assert json.loads(req.data)["message"] == "Empty String"
+
+
+def test_add_meta_rules_with_user_contain_space():
+ client = utilities.register_client()
+ req, meta_rules = add_meta_rules(client, "test user")
+ assert req.status_code == 500
+ assert json.loads(req.data)["message"] == "String contains space"
+
+
+def test_add_meta_rules_without_subject_categories():
+ client = utilities.register_client()
+ req, meta_rules = add_meta_rules_without_subject_category_ids(client, "testuser")
+ assert req.status_code == 500
+ assert json.loads(req.data)["message"] == 'Empty Container'
+
+
def test_delete_meta_rules():
client = utilities.register_client()
req = delete_meta_rules(client, "testuser")
@@ -67,3 +128,35 @@ def test_delete_meta_rules_without_id():
client = utilities.register_client()
req = delete_meta_rules_without_id(client)
assert req.status_code == 500
+
+
+def test_update_meta_rules():
+ client = utilities.register_client()
+ req = add_meta_rules(client, "testuser")
+ meta_rule_id = list(req[1]['meta_rules'])[0]
+ req_update = update_meta_rules(client, "testuser", meta_rule_id)
+ assert req_update[0].status_code == 200
+ value = list(req_update[1]["meta_rules"].values())[0]
+ assert value["subject_categories"][0] == "subject_category_id1_update"
+ delete_meta_rules(client, "testuser")
+ get_meta_rules(client)
+
+
+def test_update_meta_rules_without_id():
+ client = utilities.register_client()
+ req_update = update_meta_rules(client, "testuser", "")
+ assert req_update[0].status_code == 500
+
+
+def test_update_meta_rules_without_user():
+ client = utilities.register_client()
+ req_update = update_meta_rules(client, "", "")
+ assert req_update[0].status_code == 500
+ assert json.loads(req_update[0].data)["message"] == "Empty String"
+
+
+def test_update_meta_rules_without_subject_categories():
+ client = utilities.register_client()
+ req_update = update_meta_rules_without_subject_category_ids(client, "testuser")
+ assert req_update[0].status_code == 500
+ assert json.loads(req_update[0].data)["message"] == "Empty Container"
diff --git a/moon_manager/tests/unit_python/api/test_assignemnt.py b/moon_manager/tests/unit_python/api/test_assignemnt.py
index 08688e04..22c727af 100644
--- a/moon_manager/tests/unit_python/api/test_assignemnt.py
+++ b/moon_manager/tests/unit_python/api/test_assignemnt.py
@@ -1,5 +1,7 @@
import api.utilities as utilities
import json
+from helpers import data_builder as builder
+from uuid import uuid4
# subject_categories_test
@@ -11,52 +13,84 @@ def get_subject_assignment(client, policy_id):
return req, subject_assignment
-def add_subject_assignment(client, policy_id, category_id):
+def add_subject_assignment(client):
+ subject_category_id, object_category_id, action_category_id, meta_rule_id, policy_id = builder.create_new_policy(
+ subject_category_name="subject_category1" + uuid4().hex,
+ object_category_name="object_category1" + uuid4().hex,
+ action_category_name="action_category1" + uuid4().hex,
+ meta_rule_name="meta_rule_1" + uuid4().hex)
+ subject_id = builder.create_subject(policy_id)
+ data_id = builder.create_subject_data(policy_id=policy_id, category_id=subject_category_id)
+
+ data = {
+ "id": subject_id,
+ "category_id": subject_category_id,
+ "data_id": data_id
+ }
+ req = client.post("/policies/{}/subject_assignments".format(policy_id), data=json.dumps(data),
+ headers={'Content-Type': 'application/json'})
+ subject_assignment = utilities.get_json(req.data)
+ return req, subject_assignment
+
+
+def add_subject_assignment_without_cat_id(client):
+
data = {
- "id": "id1",
- "category_id": category_id,
- "data_id": "data_id1"
+ "id": "subject_id",
+ "category_id": "",
+ "data_id": "data_id"
}
- req = client.post("/policies/{}/subject_assignments/{}".format(policy_id, category_id), data=json.dumps(data),
+ req = client.post("/policies/{}/subject_assignments".format("1111"), data=json.dumps(data),
headers={'Content-Type': 'application/json'})
subject_assignment = utilities.get_json(req.data)
return req, subject_assignment
-def delete_subject_assignment(client, policy_id):
- req = client.delete("/policies/{}/subject_assignments".format(policy_id))
+def delete_subject_assignment(client, policy_id, sub_id, cat_id,data_id):
+ req = client.delete("/policies/{}/subject_assignments/{}/{}/{}".format(policy_id, sub_id, cat_id,data_id))
return req
-def test_get_subject_assignment():
- policy_id = utilities.get_policy_id()
+def test_add_subject_assignment():
client = utilities.register_client()
- req, subject_assignment = get_subject_assignment(client, policy_id)
+ req, subject_assignment = add_subject_assignment(client)
assert req.status_code == 200
assert isinstance(subject_assignment, dict)
assert "subject_assignments" in subject_assignment
-def test_add_subject_assignment():
- policy_id = utilities.get_policy_id()
+def test_add_subject_assignment_without_cat_id():
client = utilities.register_client()
- req, subject_assignment = add_subject_assignment(client, policy_id, "111")
+ req, subject_assignment = add_subject_assignment_without_cat_id(client)
+ assert req.status_code == 400
+ assert json.loads(req.data)["message"] == "Key: 'category_id', [Empty String]"
+
+
+def test_get_subject_assignment():
+ client = utilities.register_client()
+ policy_id = builder.get_policy_id_with_subject_assignment()
+ req, subject_assignment = get_subject_assignment(client, policy_id)
assert req.status_code == 200
assert isinstance(subject_assignment, dict)
- value = subject_assignment["subject_assignments"]
assert "subject_assignments" in subject_assignment
- id = list(value.keys())[0]
- assert value[id]['policy_id'] == policy_id
- assert value[id]['category_id'] == "111"
- assert value[id]['subject_id'] == "id1"
def test_delete_subject_assignment():
client = utilities.register_client()
- policy_id = utilities.get_policy_id()
- success_req = delete_subject_assignment(client, policy_id)
+ policy_id = builder.get_policy_id_with_subject_assignment()
+ req, subject_assignment = get_subject_assignment(client, policy_id)
+ value = subject_assignment["subject_assignments"]
+ id = list(value.keys())[0]
+ success_req = delete_subject_assignment(client, policy_id, value[id]['subject_id'], value[id]['category_id'],value[id]['assignments'][0])
assert success_req.status_code == 200
+
+def test_delete_subject_assignment_without_policy_id():
+ client = utilities.register_client()
+ success_req = delete_subject_assignment(client, "", "id1", "111" ,"data_id1")
+ assert success_req.status_code == 404
+
+
# ---------------------------------------------------------------------------
# object_categories_test
@@ -68,25 +102,47 @@ def get_object_assignment(client, policy_id):
return req, object_assignment
-def add_object_assignment(client, policy_id, category_id):
+def add_object_assignment(client):
+ subject_category_id, object_category_id, action_category_id, meta_rule_id, policy_id = builder.create_new_policy(
+ subject_category_name="subject_category1" + uuid4().hex,
+ object_category_name="object_category1" + uuid4().hex,
+ action_category_name="action_category1" + uuid4().hex,
+ meta_rule_name="meta_rule_1" + uuid4().hex)
+ object_id = builder.create_object(policy_id)
+ data_id = builder.create_object_data(policy_id=policy_id, category_id=object_category_id)
+
+ data = {
+ "id": object_id,
+ "category_id": object_category_id,
+ "data_id": data_id
+ }
+
+ req = client.post("/policies/{}/object_assignments".format(policy_id), data=json.dumps(data),
+ headers={'Content-Type': 'application/json'})
+ object_assignment = utilities.get_json(req.data)
+ return req, object_assignment
+
+
+def add_object_assignment_without_cat_id(client):
+
data = {
- "id": "id1",
- "category_id": category_id,
- "data_id": "data_id1"
+ "id": "object_id",
+ "category_id": "",
+ "data_id": "data_id"
}
- req = client.post("/policies/{}/object_assignments/{}".format(policy_id, category_id), data=json.dumps(data),
+ req = client.post("/policies/{}/object_assignments".format("1111"), data=json.dumps(data),
headers={'Content-Type': 'application/json'})
object_assignment = utilities.get_json(req.data)
return req, object_assignment
-def delete_object_assignment(client, policy_id):
- req = client.delete("/policies/{}/object_assignments".format(policy_id))
+def delete_object_assignment(client, policy_id, obj_id, cat_id, data_id):
+ req = client.delete("/policies/{}/object_assignments/{}/{}/{}".format(policy_id, obj_id, cat_id, data_id))
return req
def test_get_object_assignment():
- policy_id = utilities.get_policy_id()
+ policy_id = builder.get_policy_id_with_object_assignment()
client = utilities.register_client()
req, object_assignment = get_object_assignment(client, policy_id)
assert req.status_code == 200
@@ -95,25 +151,35 @@ def test_get_object_assignment():
def test_add_object_assignment():
- policy_id = utilities.get_policy_id()
client = utilities.register_client()
- req, object_assignment = add_object_assignment(client, policy_id, "111")
+ req, object_assignment = add_object_assignment(client)
assert req.status_code == 200
- assert isinstance(object_assignment, dict)
- value = object_assignment["object_assignments"]
assert "object_assignments" in object_assignment
- id = list(value.keys())[0]
- assert value[id]['policy_id'] == policy_id
- assert value[id]['category_id'] == "111"
- assert value[id]['object_id'] == "id1"
+
+
+def test_add_object_assignment_without_cat_id():
+ client = utilities.register_client()
+ req, object_assignment = add_object_assignment_without_cat_id(client)
+ assert req.status_code == 400
+ assert json.loads(req.data)["message"] == "Key: 'category_id', [Empty String]"
def test_delete_object_assignment():
client = utilities.register_client()
- policy_id = utilities.get_policy_id()
- success_req = delete_object_assignment(client, policy_id)
+ policy_id = builder.get_policy_id_with_object_assignment()
+ req, object_assignment = get_object_assignment(client, policy_id)
+ value = object_assignment["object_assignments"]
+ id = list(value.keys())[0]
+ success_req = delete_object_assignment(client, policy_id, value[id]['object_id'], value[id]['category_id'],value[id]['assignments'][0])
assert success_req.status_code == 200
+
+def test_delete_object_assignment_without_policy_id():
+ client = utilities.register_client()
+ success_req = delete_object_assignment(client, "", "id1", "111","data_id1")
+ assert success_req.status_code == 404
+
+
# ---------------------------------------------------------------------------
# action_categories_test
@@ -125,25 +191,46 @@ def get_action_assignment(client, policy_id):
return req, action_assignment
-def add_action_assignment(client, policy_id, category_id):
+def add_action_assignment(client):
+ subject_category_id, object_category_id, action_category_id, meta_rule_id, policy_id = builder.create_new_policy(
+ subject_category_name="subject_category1" + uuid4().hex,
+ object_category_name="object_category1" + uuid4().hex,
+ action_category_name="action_category1" + uuid4().hex,
+ meta_rule_name="meta_rule_1" + uuid4().hex)
+ action_id = builder.create_action(policy_id)
+ data_id = builder.create_action_data(policy_id=policy_id, category_id=action_category_id)
+
+ data = {
+ "id": action_id,
+ "category_id": action_category_id,
+ "data_id": data_id
+ }
+ req = client.post("/policies/{}/action_assignments".format(policy_id), data=json.dumps(data),
+ headers={'Content-Type': 'application/json'})
+ action_assignment = utilities.get_json(req.data)
+ return req, action_assignment
+
+
+def add_action_assignment_without_cat_id(client):
+
data = {
- "id": "id1",
- "category_id": category_id,
- "data_id": "data_id1"
+ "id": "action_id",
+ "category_id": "",
+ "data_id": "data_id"
}
- req = client.post("/policies/{}/action_assignments/{}".format(policy_id, category_id), data=json.dumps(data),
+ req = client.post("/policies/{}/action_assignments".format("1111"), data=json.dumps(data),
headers={'Content-Type': 'application/json'})
action_assignment = utilities.get_json(req.data)
return req, action_assignment
-def delete_action_assignment(client, policy_id):
- req = client.delete("/policies/{}/action_assignments".format(policy_id))
+def delete_action_assignment(client, policy_id, action_id, cat_id, data_id):
+ req = client.delete("/policies/{}/action_assignments/{}/{}/{}".format(policy_id, action_id, cat_id, data_id))
return req
def test_get_action_assignment():
- policy_id = utilities.get_policy_id()
+ policy_id = builder.get_policy_id_with_action_assignment()
client = utilities.register_client()
req, action_assignment = get_action_assignment(client, policy_id)
assert req.status_code == 200
@@ -152,23 +239,32 @@ def test_get_action_assignment():
def test_add_action_assignment():
- policy_id = utilities.get_policy_id()
client = utilities.register_client()
- req, action_assignment = add_action_assignment(client, policy_id, "111")
+ req, action_assignment = add_action_assignment(client)
assert req.status_code == 200
- assert isinstance(action_assignment, dict)
- value = action_assignment["action_assignments"]
assert "action_assignments" in action_assignment
- id = list(value.keys())[0]
- assert value[id]['policy_id'] == policy_id
- assert value[id]['category_id'] == "111"
- assert value[id]['action_id'] == "id1"
+
+
+def test_add_action_assignment_without_cat_id():
+ client = utilities.register_client()
+ req, action_assignment = add_action_assignment_without_cat_id(client)
+ assert req.status_code == 400
+ assert json.loads(req.data)["message"] == "Key: 'category_id', [Empty String]"
def test_delete_action_assignment():
client = utilities.register_client()
- policy_id = utilities.get_policy_id()
- success_req = delete_action_assignment(client, policy_id)
+ policy_id = builder.get_policy_id_with_action_assignment()
+ req, action_assignment = get_action_assignment(client, policy_id)
+ value = action_assignment["action_assignments"]
+ id = list(value.keys())[0]
+ success_req = delete_action_assignment(client, policy_id, value[id]['action_id'], value[id]['category_id'],value[id]['assignments'][0])
assert success_req.status_code == 200
-# --------------------------------------------------------------------------- \ No newline at end of file
+
+def test_delete_action_assignment_without_policy_id():
+ client = utilities.register_client()
+ success_req = delete_action_assignment(client, "", "id1", "111" ,"data_id1")
+ assert success_req.status_code == 404
+
+# ---------------------------------------------------------------------------
diff --git a/moon_manager/tests/unit_python/api/test_data.py b/moon_manager/tests/unit_python/api/test_data.py
index 87a80c69..ff0856af 100644
--- a/moon_manager/tests/unit_python/api/test_data.py
+++ b/moon_manager/tests/unit_python/api/test_data.py
@@ -1,22 +1,36 @@
+# Copyright 2018 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 api.utilities as utilities
import json
-
+from helpers import data_builder as builder
+from uuid import uuid4
# subject_categories_test
-def get_subject_data(client, policy_id):
- req = client.get("/policies/{}/subject_data".format(policy_id))
+def get_subject_data(client, policy_id, category_id=None):
+ if category_id is None:
+ req = client.get("/policies/{}/subject_data".format(policy_id))
+ else:
+ req = client.get("/policies/{}/subject_data/{}".format(policy_id, category_id))
subject_data = utilities.get_json(req.data)
return req, subject_data
-def add_subject_data(client, name, policy_id, category_id):
+def add_subject_data(client, name):
+ subject_category_id, object_category_id, action_category_id, meta_rule_id, policy_id = builder.create_new_policy(
+ subject_category_name="subject_category1" + uuid4().hex,
+ object_category_name="object_category1" + uuid4().hex,
+ action_category_name="action_category1" + uuid4().hex,
+ meta_rule_name="meta_rule_1" + uuid4().hex)
data = {
"name": name,
"description": "description of {}".format(name)
}
- req = client.post("/policies/{}/subject_data/{}".format(policy_id, category_id), data=json.dumps(data),
+ req = client.post("/policies/{}/subject_data/{}".format(policy_id, subject_category_id), data=json.dumps(data),
headers={'Content-Type': 'application/json'})
subject_data = utilities.get_json(req.data)
return req, subject_data
@@ -37,9 +51,8 @@ def test_get_subject_data():
def test_add_subject_data():
- policy_id = utilities.get_policy_id()
client = utilities.register_client()
- req, subject_data = add_subject_data(client, "testuser", policy_id, "111")
+ req, subject_data = add_subject_data(client, "testuser")
assert req.status_code == 200
assert isinstance(subject_data, dict)
value = subject_data["subject_data"]['data']
@@ -51,27 +64,55 @@ def test_add_subject_data():
def test_delete_subject_data():
client = utilities.register_client()
- policy_id = utilities.get_policy_id()
+ subject_category_id, object_category_id, action_category_id, meta_rule_id,policy_id = builder.create_new_policy()
success_req = delete_subject_data(client, policy_id)
assert success_req.status_code == 200
+
+def test_add_subject_data_with_empty_user():
+ client = utilities.register_client()
+ req, subject_data = add_subject_data(client, "")
+ assert req.status_code == 400
+ assert json.loads(req.data)["message"] == "Key: 'name', [Empty String]"
+
+
+def test_add_subject_data_with_user_contain_space():
+ client = utilities.register_client()
+ req, subject_data = add_subject_data(client, "test user")
+ assert req.status_code == 400
+ assert json.loads(req.data)["message"] == "Key: 'name', [String contains space]"
+
+
+def test_delete_subject_data_without_policy_id():
+ client = utilities.register_client()
+ success_req = delete_subject_data(client, "")
+ assert success_req.status_code == 404
+
# ---------------------------------------------------------------------------
# object_categories_test
-def get_object_data(client, policy_id):
- req = client.get("/policies/{}/object_data".format(policy_id))
+def get_object_data(client, policy_id, category_id=None):
+ if category_id is None:
+ req = client.get("/policies/{}/object_data".format(policy_id))
+ else:
+ req = client.get("/policies/{}/object_data/{}".format(policy_id, category_id))
object_data = utilities.get_json(req.data)
return req, object_data
-def add_object_data(client, name, policy_id, category_id):
+def add_object_data(client, name):
+ subject_category_id, object_category_id, action_category_id, meta_rule_id, policy_id = builder.create_new_policy(
+ subject_category_name="subject_category1" + uuid4().hex,
+ object_category_name="object_category1" + uuid4().hex,
+ action_category_name="action_category1" + uuid4().hex,
+ meta_rule_name="meta_rule_1" + uuid4().hex)
data = {
"name": name,
"description": "description of {}".format(name)
}
- req = client.post("/policies/{}/object_data/{}".format(policy_id, category_id), data=json.dumps(data),
+ req = client.post("/policies/{}/object_data/{}".format(policy_id, object_category_id), data=json.dumps(data),
headers={'Content-Type': 'application/json'})
object_data = utilities.get_json(req.data)
return req, object_data
@@ -92,16 +133,19 @@ def test_get_object_data():
def test_add_object_data():
- policy_id = utilities.get_policy_id()
client = utilities.register_client()
- req, object_data = add_object_data(client, "testuser", policy_id, "111")
+ req, object_data = add_object_data(client, "testuser")
assert req.status_code == 200
assert isinstance(object_data, dict)
value = object_data["object_data"]['data']
assert "object_data" in object_data
id = list(value.keys())[0]
- assert value[id]['value']['name'] == "testuser"
- assert value[id]['value']['description'] == "description of {}".format("testuser")
+ print("-----------------------")
+ print(id)
+ print(value[id])
+ print("-----------------------")
+ assert value[id]['name'] == "testuser"
+ assert value[id]['description'] == "description of {}".format("testuser")
def test_delete_object_data():
@@ -110,23 +154,50 @@ def test_delete_object_data():
success_req = delete_object_data(client, policy_id)
assert success_req.status_code == 200
+
+def test_add_object_data_with_empty_user():
+ client = utilities.register_client()
+ req, subject_data = add_object_data(client, "")
+ assert req.status_code == 400
+ assert json.loads(req.data)["message"] == "Key: 'name', [Empty String]"
+
+
+def test_add_object_data_with_user_contain_space():
+ client = utilities.register_client()
+ req, object_data = add_object_data(client, "test user")
+ assert req.status_code == 400
+ assert json.loads(req.data)["message"] == "Key: 'name', [String contains space]"
+
+
+def test_delete_object_data_without_policy_id():
+ client = utilities.register_client()
+ success_req = delete_object_data(client, "")
+ assert success_req.status_code == 404
# ---------------------------------------------------------------------------
# action_categories_test
-def get_action_data(client, policy_id):
- req = client.get("/policies/{}/action_data".format(policy_id))
+def get_action_data(client, policy_id, category_id=None):
+ if category_id is None:
+ req = client.get("/policies/{}/action_data".format(policy_id))
+ else:
+ req = client.get("/policies/{}/action_data/{}".format(policy_id, category_id))
action_data = utilities.get_json(req.data)
return req, action_data
-def add_action_data(client, name, policy_id, category_id):
+def add_action_data(client, name):
+ subject_category_id, object_category_id, action_category_id, meta_rule_id, policy_id = builder.create_new_policy(
+ subject_category_name="subject_category1" + uuid4().hex,
+ object_category_name="object_category1" + uuid4().hex,
+ action_category_name="action_category1" + uuid4().hex,
+ meta_rule_name="meta_rule_1" + uuid4().hex)
data = {
"name": name,
"description": "description of {}".format(name)
}
- req = client.post("/policies/{}/action_data/{}".format(policy_id, category_id), data=json.dumps(data),
+ req = client.post("/policies/{}/action_data/{}".format(policy_id, action_category_id), data=json.dumps(data),
headers={'Content-Type': 'application/json'})
action_data = utilities.get_json(req.data)
return req, action_data
@@ -147,16 +218,15 @@ def test_get_action_data():
def test_add_action_data():
- policy_id = utilities.get_policy_id()
client = utilities.register_client()
- req, action_data = add_action_data(client, "testuser", policy_id, "111")
+ req, action_data = add_action_data(client, "testuser")
assert req.status_code == 200
assert isinstance(action_data, dict)
value = action_data["action_data"]['data']
assert "action_data" in action_data
id = list(value.keys())[0]
- assert value[id]['value']['name'] == "testuser"
- assert value[id]['value']['description'] == "description of {}".format("testuser")
+ assert value[id]['name'] == "testuser"
+ assert value[id]['description'] == "description of {}".format("testuser")
def test_delete_action_data():
@@ -165,4 +235,23 @@ def test_delete_action_data():
success_req = delete_action_data(client, policy_id)
assert success_req.status_code == 200
-# --------------------------------------------------------------------------- \ No newline at end of file
+
+def test_add_action_data_with_empty_user():
+ client = utilities.register_client()
+ req, action_data = add_action_data(client, "")
+ assert req.status_code == 400
+ assert json.loads(req.data)["message"] == "Key: 'name', [Empty String]"
+
+
+def test_add_action_data_with_user_contain_space():
+ client = utilities.register_client()
+ req, action_data = add_action_data(client, "test user")
+ assert req.status_code == 400
+ assert json.loads(req.data)["message"] == "Key: 'name', [String contains space]"
+
+
+def test_delete_action_data_without_policy_id():
+ client = utilities.register_client()
+ success_req = delete_action_data(client, "")
+ assert success_req.status_code == 404
+# ---------------------------------------------------------------------------
diff --git a/moon_manager/tests/unit_python/api/test_export.py b/moon_manager/tests/unit_python/api/test_export.py
new file mode 100644
index 00000000..ac8e8d17
--- /dev/null
+++ b/moon_manager/tests/unit_python/api/test_export.py
@@ -0,0 +1,282 @@
+# Copyright 2018 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 json
+import api.utilities as utilities
+import api.import_export_utilities as import_export_utilities
+
+
+MODEL_WITHOUT_META_RULES = {"models": [{"name": "test model", "description": "model description", "meta_rules": []}]}
+
+POLICIES = {"models": [{"name": "test model", "description": "", "meta_rules": []}],
+ "policies": [{"name": "test policy", "genre": "authz", "description": "policy description", "model": {"name" : "test model"}}]}
+
+SUBJECTS_OBJECTS_ACTIONS = {"models": [{"name": "test model", "description": "", "meta_rules": []}],
+ "policies": [{"name": "test policy", "genre": "authz", "description": "policy description", "model": {"name" : "test model"}}],
+ "subjects": [{"name": "testuser", "description": "description of the subject", "extra": {"field_extra_subject": "value extra subject"}, "policies": [{"name": "test policy"}]}],
+ "objects": [{"name": "test object", "description": "description of the object", "extra": {"field_extra_object": "value extra object"}, "policies": [{"name": "test policy"}]}],
+ "actions": [{"name": "test action", "description": "description of the action", "extra": {"field_extra_action": "value extra action"}, "policies": [{"name": "test policy"}]}]}
+
+
+SUBJECT_OBJECT_ACTION_CATEGORIES = {"subject_categories": [{"name": "test subject categories", "description": "subject category description"}],
+ "object_categories": [{"name": "test object categories", "description": "object category description"}],
+ "action_categories": [{"name": "test action categories", "description": "action category description"}]}
+
+SUBJECT_OBJECT_ACTION_DATA = {"models": [{"name": "test model", "description": "", "meta_rules": [{"name": "meta rule"}]}],
+ "policies": [{"name": "test policy", "genre": "authz", "description": "policy description", "model": {"name" : "test model"}}],
+ "subject_categories": [{"name": "test subject categories", "description": "subject category description"}],
+ "object_categories": [{"name": "test object categories", "description": "object category description"}],
+ "action_categories": [{"name": "test action categories", "description": "action category description"}],
+ "subject_data": [{"name": "test subject data", "description": "subject data description", "policies": [{"name": "test policy"}], "category": {"name": "test subject categories"}}],
+ "object_data": [{"name": "test object data", "description": "object data description", "policies": [{"name": "test policy"}], "category": {"name": "test object categories"}}],
+ "action_data": [{"name": "test action data", "description": "action data description", "policies": [{"name": "test policy"}], "category": {"name": "test action categories"}}],
+ "meta_rules": [{"name": "meta rule", "description": "valid meta rule", "subject_categories": [{"name": "test subject categories"}], "object_categories": [{"name": "test object categories"}], "action_categories": [{"name": "test action categories"}]}]}
+
+
+META_RULES = {"subject_categories": [{"name": "test subject categories", "description": "subject category description"}],
+ "object_categories": [{"name": "test object categories", "description": "object category description"}],
+ "action_categories": [{"name": "test action categories", "description": "object action description"}],
+ "meta_rules": [{"name": "meta rule", "description": "valid meta rule", "subject_categories": [{"name": "test subject categories"}], "object_categories": [{"name": "test object categories"}], "action_categories": [{"name": "test action categories"}]}]}
+
+
+ASSIGNMENTS = {"models": [{"name": "test model", "description": "", "meta_rules": [{"name": "meta rule"}]}],
+ "policies": [{"name": "test policy", "genre": "authz", "description": "policy description", "model": {"name" : "test model"}}],
+ "subject_categories": [{"name": "test subject categories", "description": "subject category description"}],
+ "object_categories": [{"name": "test object categories", "description": "object category description"}],
+ "action_categories": [{"name": "test action categories", "description": "action category description"}],
+ "subject_data": [{"name": "test subject data", "description": "subject data description", "policies": [{"name": "test policy"}], "category": {"name": "test subject categories"}}],
+ "object_data": [{"name": "test object data", "description": "object data description", "policies": [{"name": "test policy"}], "category": {"name": "test object categories"}}],
+ "action_data": [{"name": "test action data", "description": "action data description", "policies": [{"name": "test policy"}], "category": {"name": "test action categories"}}],
+ "meta_rules": [{"name": "meta rule", "description": "valid meta rule", "subject_categories": [{"name": "test subject categories"}], "object_categories": [{"name": "test object categories"}], "action_categories": [{"name": "test action categories"}]}],
+ "subjects": [{"name": "testuser", "description": "description of the subject", "extra": {"field_extra_subject": "value extra subject"}, "policies": [{"name": "test policy"}]}],
+ "objects": [{"name": "test object e0", "description": "description of the object", "extra": {"field_extra_object": "value extra object"}, "policies": [{"name": "test policy"}]}],
+ "actions": [{"name": "test action e0", "description": "description of the action", "extra": {"field_extra_action": "value extra action"}, "policies": [{"name": "test policy"}]}],
+ "subject_assignments": [{"subject": {"name": "testuser"}, "category": {"name": "test subject categories"}, "assignments": [{"name": "test subject data"}]}],
+ "object_assignments": [{"object": {"name": "test object e0"}, "category": {"name": "test object categories"}, "assignments": [{"name": "test object data"}]}],
+ "action_assignments": [{"action": {"name": "test action e0"}, "category": {"name": "test action categories"}, "assignments": [{"name": "test action data"}]}]}
+
+RULES = {"models": [{"name": "test model", "description": "", "meta_rules": [{"name": "meta rule"}]}],
+ "policies": [{"name": "test policy", "genre": "authz", "description": "policy description", "model": {"name" : "test model"}}],
+ "subject_categories": [{"name": "test subject categories", "description": "subject category description"}],
+ "object_categories": [{"name": "test object categories", "description": "object category description"}],
+ "action_categories": [{"name": "test action categories", "description": "action category description"}],
+ "subject_data": [{"name": "test subject data", "description": "subject data description", "policies": [{"name": "test policy"}], "category": {"name": "test subject categories"}}],
+ "object_data": [{"name": "test object data", "description": "object data description", "policies": [{"name": "test policy"}], "category": {"name": "test object categories"}}],
+ "action_data": [{"name": "test action data", "description": "action data description", "policies": [{"name": "test policy"}], "category": {"name": "test action categories"}}],
+ "meta_rules": [{"name": "meta rule", "description": "valid meta rule", "subject_categories": [{"name": "test subject categories"}], "object_categories": [{"name": "test object categories"}], "action_categories": [{"name": "test action categories"}]}],
+ "subjects": [{"name": "testuser", "description": "description of the subject", "extra": {"field_extra_subject": "value extra subject"}, "policies": [{"name": "test policy"}]}],
+ "objects": [{"name": "test object e1", "description": "description of the object", "extra": {"field_extra_object": "value extra object"}, "policies": [{"name": "test policy"}]}],
+ "actions": [{"name": "test action e1", "description": "description of the action", "extra": {"field_extra_action": "value extra action"}, "policies": [{"name": "test policy"}]}],
+ "subject_assignments": [{"subject": {"name": "testuser"}, "category": {"name": "test subject categories"}, "assignments": [{"name": "test subject data"}]}],
+ "object_assignments": [{"object": {"name": "test object e1"}, "category": {"name": "test object categories"}, "assignments": [{"name": "test object data"}]}],
+ "action_assignments": [{"action": {"name": "test action e1"}, "category": {"name": "test action categories"}, "assignments": [{"name": "test action data"}]}],
+ "rules": [{"meta_rule": {"name": "meta rule"}, "rule": {"subject_data": [{"name": "test subject data"}], "object_data": [{"name": "test object data"}], "action_data": [{"name": "test action data"}]}, "policy": {"name":"test policy"}, "instructions": {"decision": "grant"}, "enabled": True}]
+ }
+
+
+def test_export_models():
+ client = utilities.register_client()
+ import_export_utilities.clean_all(client)
+ req = client.post("/import", content_type='application/json', data=json.dumps(MODEL_WITHOUT_META_RULES))
+ data = utilities.get_json(req.data)
+ assert data == "Import ok !"
+
+ req = client.get("/export")
+ assert req.status_code == 200
+ data = utilities.get_json(req.data)
+
+ assert "content" in data
+ assert "models" in data["content"]
+ assert isinstance(data["content"]["models"], list)
+ assert len(data["content"]["models"]) == 1
+ model = data["content"]["models"][0]
+ assert model["name"] == "test model"
+ assert model["description"] == "model description"
+ assert isinstance(model["meta_rules"], list)
+ assert len(model["meta_rules"]) == 0
+
+
+def test_export_policies():
+ client = utilities.register_client()
+ import_export_utilities.clean_all(client)
+ req = client.post("/import", content_type='application/json', data=json.dumps(POLICIES))
+ data = utilities.get_json(req.data)
+ assert data == "Import ok !"
+
+ req = client.get("/export")
+ assert req.status_code == 200
+ data = utilities.get_json(req.data)
+
+ assert "content" in data
+ assert "policies" in data["content"]
+ assert isinstance(data["content"]["policies"], list)
+ assert len(data["content"]["policies"]) == 1
+ policy = data["content"]["policies"][0]
+ assert policy["name"] == "test policy"
+ assert policy["genre"] == "authz"
+ assert policy["description"] == "policy description"
+ assert "model" in policy
+ assert "name" in policy["model"]
+ model = policy["model"]
+ assert model["name"] == "test model"
+
+
+def test_export_subject_object_action():
+ client = utilities.register_client()
+ import_export_utilities.clean_all(client)
+ req = client.post("/import", content_type='application/json', data=json.dumps(SUBJECTS_OBJECTS_ACTIONS))
+ data = utilities.get_json(req.data)
+ assert data == "Import ok !"
+
+ req = client.get("/export")
+ assert req.status_code == 200
+ data = utilities.get_json(req.data)
+
+ assert "content" in data
+ type_elements = ["subject", "object", "action"]
+ for type_element in type_elements:
+ key = type_element + "s"
+ assert key in data["content"]
+ assert isinstance(data["content"][key], list)
+ assert len(data["content"][key]) == 1
+ element = data["content"][key][0]
+ if type_element == "subject":
+ assert element["name"] == "testuser"
+ else:
+ assert element["name"] == "test "+ type_element
+ assert element["description"] == "description of the " + type_element
+ assert "policies" in element
+ assert isinstance(element["policies"], list)
+ assert len(element["policies"]) == 1
+ assert isinstance(element["policies"][0], dict)
+ assert element["policies"][0]["name"] == "test policy"
+ assert isinstance(element["extra"], dict)
+ key_dict = "field_extra_" + type_element
+ value_dict = "value extra " + type_element
+ assert key_dict in element["extra"]
+ assert element["extra"][key_dict] == value_dict
+
+
+def test_export_subject_object_action_categories():
+ client = utilities.register_client()
+ import_export_utilities.clean_all(client)
+ req = client.post("/import", content_type='application/json', data=json.dumps(SUBJECT_OBJECT_ACTION_CATEGORIES))
+ data = utilities.get_json(req.data)
+ assert data == "Import ok !"
+
+ req = client.get("/export")
+ assert req.status_code == 200
+ data = utilities.get_json(req.data)
+ assert "content" in data
+ type_elements = ["subject", "object", "action"]
+ for type_element in type_elements:
+ key = type_element + "_categories"
+ assert key in data["content"]
+ assert isinstance(data["content"][key], list)
+ assert len(data["content"][key]) == 1
+ category = data["content"][key][0]
+ assert category["name"] == "test " + type_element + " categories"
+ assert category["description"] == type_element + " category description"
+
+
+def test_export_subject_object_action_data():
+ client = utilities.register_client()
+ import_export_utilities.clean_all(client)
+ req = client.post("/import", content_type='application/json', data=json.dumps(SUBJECT_OBJECT_ACTION_DATA))
+ data = utilities.get_json(req.data)
+ assert data == "Import ok !"
+
+ req = client.get("/export")
+ assert req.status_code == 200
+ data = utilities.get_json(req.data)
+ assert "content" in data
+ type_elements = ["subject", "object", "action"]
+ for type_element in type_elements:
+ key = type_element + "_data"
+ assert key in data["content"]
+ assert isinstance(data["content"][key], list)
+ assert len(data["content"][key]) == 1
+ data_elt = data["content"][key][0]
+ assert data_elt["name"] == "test " + type_element + " data"
+ assert data_elt["description"] == type_element + " data description"
+ assert isinstance(data_elt["policy"], dict)
+ assert data_elt["policy"]["name"] == "test policy"
+ assert isinstance(data_elt["category"], dict)
+ assert data_elt["category"]["name"] == "test " + type_element + " categories"
+
+
+def test_export_assignments():
+ client = utilities.register_client()
+ import_export_utilities.clean_all(client)
+ req = client.post("/import", content_type='application/json', data=json.dumps(ASSIGNMENTS))
+ data = utilities.get_json(req.data)
+ assert data == "Import ok !"
+
+ req = client.get("/export")
+ assert req.status_code == 200
+ data = utilities.get_json(req.data)
+ assert "content" in data
+ type_elements = ["subject", "object", "action"]
+ for type_element in type_elements:
+ key = type_element + "_assignments"
+ assert key in data["content"]
+ assert isinstance(data["content"][key], list)
+ assert len(data["content"][key]) == 1
+ assignment_elt = data["content"][key][0]
+ assert type_element in assignment_elt
+ assert isinstance(assignment_elt[type_element], dict)
+ if type_element == "subject":
+ assert assignment_elt[type_element]["name"] == "testuser"
+ else:
+ assert assignment_elt[type_element]["name"] == "test " + type_element + " e0"
+ assert "category" in assignment_elt
+ assert isinstance(assignment_elt["category"], dict)
+ assert assignment_elt["category"]["name"] == "test " + type_element + " categories"
+ assert "assignments" in assignment_elt
+ assert isinstance(assignment_elt["assignments"], list)
+ assert len(assignment_elt["assignments"]) == 1
+ assert assignment_elt["assignments"][0]["name"] == "test " + type_element + " data"
+
+ import_export_utilities.clean_all(client)
+
+
+def test_export_rules():
+ client = utilities.register_client()
+ import_export_utilities.clean_all(client)
+ req = client.post("/import", content_type='application/json', data=json.dumps(RULES))
+ data = utilities.get_json(req.data)
+ assert data == "Import ok !"
+
+ req = client.get("/export")
+ assert req.status_code == 200
+ data = utilities.get_json(req.data)
+ assert "content" in data
+ assert "rules" in data["content"]
+ assert isinstance(data["content"]["rules"], list)
+ assert len(data["content"]["rules"]) == 1
+ rule = data["content"]["rules"][0]
+ assert "instructions" in rule
+ assert "decision" in rule["instructions"]
+ assert rule["instructions"]["decision"] == "grant"
+ assert "enabled" in rule
+ assert rule["enabled"]
+ assert "meta_rule" in rule
+ assert rule["meta_rule"]["name"] == "meta rule"
+ assert "policy" in rule
+ assert rule["policy"]["name"] == "test policy"
+ assert "rule" in rule
+ rule = rule["rule"]
+ assert "subject_data" in rule
+ assert isinstance(rule["subject_data"], list)
+ assert len(rule["subject_data"]) == 1
+ assert rule["subject_data"][0]["name"] == "test subject data"
+ assert "object_data" in rule
+ assert isinstance(rule["object_data"], list)
+ assert len(rule["object_data"]) == 1
+ assert rule["object_data"][0]["name"] == "test object data"
+ assert "action_data" in rule
+ assert isinstance(rule["action_data"], list)
+ assert len(rule["action_data"]) == 1
+ assert rule["action_data"][0]["name"] == "test action data"
diff --git a/moon_manager/tests/unit_python/api/test_import.py b/moon_manager/tests/unit_python/api/test_import.py
new file mode 100644
index 00000000..f1ab8251
--- /dev/null
+++ b/moon_manager/tests/unit_python/api/test_import.py
@@ -0,0 +1,498 @@
+# Copyright 2018 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 api.utilities as utilities
+import api.test_unit_models as test_models
+import api.test_policies as test_policies
+import api.test_meta_data as test_categories
+import api.test_data as test_data
+import api.test_meta_rules as test_meta_rules
+import api.test_assignemnt as test_assignments
+import api.test_rules as test_rules
+import api.import_export_utilities as import_export_utilities
+
+import json
+
+
+MODEL_WITHOUT_META_RULES = [
+ {"models": [{"name": "test model", "description": "", "meta_rules": []}]},
+ {"models": [{"name": "test model", "description": "new description", "meta_rules": [], "override": True}]},
+ {"models": [{"name": "test model", "description": "description not taken into account", "meta_rules": [], "override": False}]}
+ ]
+
+POLICIES = [
+ {"policies": [{"name": "test policy", "genre": "authz", "description": "description", "model": {}, "mandatory": False}]},
+ {"policies": [{"name": "test policy", "genre": "authz", "description": "new description not taken into account", "model": {"name" : "test model"}, "mandatory": True}]},
+ {"policies": [{"name": "test policy", "genre": "not authz ?", "description": "generates an exception", "model": {"name" : "test model"}, "override": True}]},
+ {"models": [{"name": "test model", "description": "", "meta_rules": []}], "policies": [{"name": "test policy", "genre": "not authz ?", "description": "changes taken into account", "model": {"name" : "test model"}, "override": True}]},
+]
+
+SUBJECTS = [{"subjects": [{"name": "testuser", "description": "description of the subject", "extra": {}, "policies": []}]},
+ {"policies": [{"name": "test policy", "genre": "authz", "description": "description", "model": {}, "mandatory": False}], "subjects": [{"name": "testuser", "description": "description of the subject", "extra": {}, "policies": []}]},
+ {"policies": [{"name": "test other policy", "genre": "authz", "description": "description", "model": {}, "mandatory": True}], "subjects": [{"name": "testuser", "description": "description of the subject", "extra": {}, "policies": []}]},
+ {"subjects": [{"name": "testuser", "description": "new description of the subject", "extra": {"email": "new-email@test.com"}, "policies": [{"name": "test other policy"}]}]},
+ {"policies": [{"name": "test policy", "genre": "authz", "description": "description", "model": {}, "mandatory": False}], "subjects": [{"name": "testuser", "description": "description of the subject", "extra": {}, "policies": [{"name": "test policy"}]}]}]
+
+
+OBJECTS = [
+ {"objects": [{"name": "test object", "description": "description of the object", "extra": {}, "policies": []}]},
+ {"policies": [{"name": "test policy", "genre": "authz", "description": "description", "model": {}, "mandatory": False}],
+ "objects": [{"name": "test object", "description": "description of the object", "extra": {}, "policies": []}]},
+ {"policies": [{"name": "test other policy", "genre": "authz", "description": "description", "model": {}, "mandatory": True}],
+ "objects": [{"name": "test object", "description": "description of the object", "extra": {}, "policies": []}]},
+ {"objects": [{"name": "test object", "description": "new description of the object", "extra": {"test": "test extra"},
+ "policies": [{"name": "test other policy"}]}]},
+ {"policies": [{"name": "test policy", "genre": "authz", "description": "description", "model": {}, "mandatory": False}],
+ "objects": [{"name": "test object", "description": "description of the object", "extra": {}, "policies": [{"name": "test policy"}]}]},
+]
+
+
+ACTIONS = [{"actions": [{"name": "test action", "description": "description of the action", "extra": {}, "policies": []}]},
+ {"policies": [{"name": "test policy", "genre": "authz", "description": "description", "model": {}, "mandatory": False}], "actions": [{"name": "test action", "description": "description of the action", "extra": {}, "policies": []}]},
+ {"policies": [{"name": "test other policy", "genre": "authz", "description": "description", "model": {}, "mandatory": True}], "actions": [{"name": "test action", "description": "description of the action", "extra": {}, "policies": []}]},
+ {"actions": [{"name": "test action", "description": "new description of the action", "extra": {"test": "test extra"}, "policies": [{"name": "test other policy"}]}]},
+ {"policies": [{"name": "test policy", "genre": "authz", "description": "description", "model": {}, "mandatory": False}], "actions": [{"name": "test action", "description": "description of the action", "extra": {}, "policies": [{"name": "test policy"}]}]}]
+
+
+SUBJECT_CATEGORIES = [{"subject_categories": [{"name": "test subject categories", "description": "subject category description"}]},
+ {"subject_categories": [{"name": "test subject categories", "description": "new subject category description"}]}]
+
+
+OBJECT_CATEGORIES = [{"object_categories": [{"name": "test object categories", "description": "object category description"}]},
+ {"object_categories": [{"name": "test object categories", "description": "new object category description"}]}]
+
+
+ACTION_CATEGORIES = [{"action_categories": [{"name": "test action categories", "description": "action category description"}]},
+ {"action_categories": [{"name": "test action categories", "description": "new action category description"}]}]
+
+# meta_rules import is needed otherwise the search for data do not work !!!
+PRE_DATA = {"models": [{"name": "test model", "description": "", "meta_rules": [{"name": "good meta rule"}, {"name": "other good meta rule"}]}],
+ "policies": [{"name": "test other policy", "genre": "authz", "description": "description", "model": {"name": "test model"}, "mandatory": True}],
+ "subject_categories": [{"name": "test subject categories", "description": "subject category description"}, {"name": "other test subject categories", "description": "subject category description"}],
+ "object_categories": [{"name": "test object categories", "description": "object category description"}, {"name": "other test object categories", "description": "object category description"}],
+ "action_categories": [{"name": "test action categories", "description": "action category description"}, {"name": "other test action categories", "description": "action category description"}],
+ "meta_rules": [{"name": "good meta rule", "description": "valid meta rule", "subject_categories": [{"name": "test subject categories"}], "object_categories": [{"name": "test object categories"}], "action_categories": [{"name": "test action categories"}]},
+ {"name": "other good meta rule", "description": "valid meta rule", "subject_categories": [{"name": "other test subject categories"}], "object_categories": [{"name": "other test object categories"}], "action_categories": [{"name": "other test action categories"}]}]}
+
+SUBJECT_DATA = [{"subject_data": [{"name": "not valid subject data", "description": "", "policies": [{}], "category": {}}]},
+ {"subject_data": [{"name": "not valid subject data", "description": "", "policies": [{}], "category": {"name": "test subject categories"}}]},
+ {"policies": [{"name": "test policy", "genre": "authz", "description": "description", "model": {"name": "test model"}, "mandatory": True}], "subject_data": [{"name": "one valid subject data", "description": "description", "policies": [{}], "category": {"name": "test subject categories"}}]},
+ {"subject_data": [{"name": "valid subject data", "description": "description", "policies": [{"name": "test policy"}], "category": {"name": "test subject categories"}}]},
+ {"subject_data": [{"name": "valid subject data", "description": "new description", "policies": [{"name": "test other policy"}], "category": {"name": "test subject categories"}}]}]
+
+OBJECT_DATA = [{"object_data": [{"name": "not valid object data", "description": "", "policies": [{}], "category": {}}]},
+ {"object_data": [{"name": "not valid object data", "description": "", "policies": [{}], "category": {"name": "test object categories"}}]},
+ {"policies": [{"name": "test policy", "genre": "authz", "description": "description", "model": {"name": "test model"}, "mandatory": True}], "object_data": [{"name": "one valid object data", "description": "description", "policies": [{}], "category": {"name": "test object categories"}}]},
+ {"object_data": [{"name": "valid object data", "description": "description", "policies": [{"name": "test policy"}], "category": {"name": "test object categories"}}]},
+ {"object_data": [{"name": "valid object data", "description": "new description", "policies": [{"name": "test other policy"}], "category": {"name": "test object categories"}}]}]
+
+
+ACTION_DATA = [{"action_data": [{"name": "not valid action data", "description": "", "policies": [{}], "category": {}}]},
+ {"action_data": [{"name": "not valid action data", "description": "", "policies": [{}], "category": {"name": "test action categories"}}]},
+ {"policies": [{"name": "test policy", "genre": "authz", "description": "description", "model": {"name": "test model"}, "mandatory": True}], "action_data": [{"name": "one valid action data", "description": "description", "policies": [{}], "category": {"name": "test action categories"}}]},
+ {"action_data": [{"name": "valid action data", "description": "description", "policies": [{"name": "test policy"}], "category": {"name": "test action categories"}}]},
+ {"action_data": [{"name": "valid action data", "description": "new description", "policies": [{"name": "test other policy"}], "category": {"name": "test action categories"}}]}]
+
+
+PRE_META_RULES = {"subject_categories": [{"name": "test subject categories", "description": "subject category description"}],
+ "object_categories": [{"name": "test object categories", "description": "object category description"}],
+ "action_categories": [{"name": "test action categories", "description": "object action description"}]}
+
+META_RULES = [{"meta_rules" :[{"name": "bad meta rule", "description": "not valid meta rule", "subject_categories": [{"name": "not valid category"}], "object_categories": [{"name": "test object categories"}], "action_categories": [{"name": "test action categories"}]}]},
+ {"meta_rules": [{"name": "bad meta rule", "description": "not valid meta rule", "subject_categories": [{"name": "test subject categories"}], "object_categories": [{"name": "not valid category"}], "action_categories": [{"name": "test action categories"}]}]},
+ {"meta_rules": [{"name": "bad meta rule", "description": "not valid meta rule", "subject_categories": [{"name": "test subject categories"}], "object_categories": [{"name": "test object categories"}], "action_categories": [{"name": "not valid category"}]}]},
+ {"meta_rules": [{"name": "good meta rule", "description": "valid meta rule", "subject_categories": [{"name": "test subject categories"}], "object_categories": [{"name": "test object categories"}], "action_categories": [{"name": "test action categories"}]}]}]
+
+
+PRE_ASSIGNMENTS = {"models": [{"name": "test model", "description": "", "meta_rules": [{"name": "good meta rule"}]}],
+ "policies": [{"name": "test policy", "genre": "authz", "description": "description", "model": {"name" : "test model"}, "mandatory": True}],
+ "subject_categories": [{"name": "test subject categories", "description": "subject category description"}],
+ "object_categories": [{"name": "test object categories", "description": "object category description"}],
+ "action_categories": [{"name": "test action categories", "description": "object action description"}],
+ "subjects": [{"name": "testuser", "description": "description of the subject", "extra": {}, "policies": [{"name": "test policy"}]}],
+ "objects": [{"name": "test object", "description": "description of the object", "extra": {}, "policies": [{"name": "test policy"}]}],
+ "actions": [{"name": "test action", "description": "description of the action", "extra": {}, "policies": [{"name": "test policy"}]}],
+ "meta_rules": [{"name": "good meta rule", "description": "valid meta rule", "subject_categories": [{"name": "test subject categories"}], "object_categories": [{"name": "test object categories"}], "action_categories": [{"name": "test action categories"}]}],
+ "subject_data": [{"name": "subject data", "description": "test subject data", "policies": [{"name": "test policy"}], "category": {"name": "test subject categories"}}],
+ "object_data": [{"name": "object data", "description": "test object data", "policies": [{"name": "test policy"}], "category": {"name": "test object categories"}}],
+ "action_data": [{"name": "action data", "description": "test action data", "policies": [{"name": "test policy"}], "category": {"name": "test action categories"}}]}
+
+
+SUBJECT_ASSIGNMENTS = [{"subject_assignments": [{"subject": {"name": "unknonw"}, "category" : {"name": "test subject categories"}, "assignments": [{"name": "subject data"}]}]},
+ {"subject_assignments": [{"subject": {"name": "testuser"}, "category": {"name": "unknown"}, "assignments": [{"name": "subject data"}]}]},
+ {"subject_assignments": [{"subject": {"name": "testuser"}, "category" : {"name": "test subject categories"}, "assignments": [{"name": "unknwon"}]}]},
+ {"subject_assignments": [{"subject": {"name": "testuser"}, "category": {"name": "test subject categories"}, "assignments": [{"name": "subject data"}]}]}]
+
+OBJECT_ASSIGNMENTS = [{"object_assignments": [{"object": {"name": "unknown"}, "category" : {"name": "test object categories"}, "assignments": [{"name": "object data"}]}]},
+ {"object_assignments": [{"object": {"name": "test object"}, "category" : {"name": "unknown"}, "assignments": [{"name": "object data"}]}]},
+ {"object_assignments": [{"object": {"name": "test object"}, "category" : {"name": "test object categories"}, "assignments": [{"name": "unknown"}]}]},
+ {"object_assignments": [{"object": {"name": "test object"}, "category" : {"name": "test object categories"}, "assignments": [{"name": "object data"}]}]}]
+
+ACTION_ASSIGNMENTS = [{"action_assignments": [{"action": {"name": "unknown"}, "category" : {"name": "test action categories"}, "assignments": [{"name": "action data"}]}]},
+ {"action_assignments": [{"action": {"name": "test action"}, "category" : {"name": "unknown"}, "assignments": [{"name": "action data"}]}]},
+ {"action_assignments": [{"action": {"name": "test action"}, "category" : {"name": "test action categories"}, "assignments": [{"name": "unknown"}]}]},
+ {"action_assignments": [{"action": {"name": "test action"}, "category" : {"name": "test action categories"}, "assignments": [{"name": "action data"}]}]}]
+
+RULES = [{"rules": [{"meta_rule": {"name": "unknown meta rule"}, "policy": {"name": "test policy"}, "instructions": {"decision": "grant"}, "enabled": True, "rule": {"subject_data": [{"name": "subject data"}], "object_data": [{"name": "object data"}], "action_data": [{"name": "action data"}]}}]},
+ {"rules": [{"meta_rule": {"name": "good meta rule"}, "policy": {"name": "unknown policy"}, "instructions": {"decision": "grant"}, "enabled": True, "rule": {"subject_data": [{"name": "subject data"}], "object_data": [{"name": "object data"}], "action_data": [{"name": "action data"}]}}]},
+ {"rules": [{"meta_rule": {"name": "good meta rule"}, "policy": {"name": "test policy"}, "instructions": {"decision": "grant"}, "enabled": True, "rule": {"subject_data": [{"name": "unknown subject data"}], "object_data": [{"name": "object data"}], "action_data": [{"name": "action data"}]}}]},
+ {"rules": [{"meta_rule": {"name": "good meta rule"}, "policy": {"name": "test policy"}, "instructions": {"decision": "grant"}, "enabled": True, "rule": {"subject_data": [{"name": "subject data"}], "object_data": [{"name": "unknown object data"}], "action_data": [{"name": "action data"}]}}]},
+ {"rules": [{"meta_rule": {"name": "good meta rule"}, "policy": {"name": "test policy"}, "instructions": {"decision": "grant"}, "enabled": True, "rule": {"subject_data": [{"name": "subject data"}], "object_data": [{"name": "object data"}], "action_data": [{"name": "unknown action data"}]}}]},
+ {"rules": [{"meta_rule": {"name": "good meta rule"}, "policy": {"name": "test policy"}, "instructions": {"decision": "grant"}, "enabled": True, "rule": {"subject_data": [{"name": "subject data"}], "object_data": [{"name": "object data"}], "action_data": [{"name": "action data"}]}}]}]
+
+
+def test_import_models_without_new_meta_rules():
+ client = utilities.register_client()
+ import_export_utilities.clean_all(client)
+ counter = 0
+ for models_description in MODEL_WITHOUT_META_RULES:
+ req = client.post("/import", content_type='application/json', data=json.dumps(models_description))
+ data = utilities.get_json(req.data)
+ assert data == "Import ok !"
+ req, models = test_models.get_models(client)
+ models = models["models"]
+ assert len(list(models.keys())) == 1
+ values = list(models.values())
+ assert values[0]["name"] == "test model"
+ if counter == 0:
+ assert len(values[0]["description"]) == 0
+ if counter == 1 or counter == 2:
+ assert values[0]["description"] == "new description"
+ counter = counter + 1
+ import_export_utilities.clean_all(client)
+
+
+def test_import_policies():
+ client = utilities.register_client()
+ import_export_utilities.clean_all(client)
+ counter = -1
+ for policy_description in POLICIES:
+ counter = counter + 1
+ req = client.post("/import", content_type='application/json', data=json.dumps(policy_description))
+ try:
+ data = utilities.get_json(req.data)
+ assert data == "Import ok !"
+ except Exception:
+ assert counter == 2 # this is an expected failure
+ continue
+
+ req, policies = test_policies.get_policies(client)
+ policies = policies["policies"]
+ assert len(list(policies.keys())) == 1
+ values = list(policies.values())
+ assert values[0]["name"] == "test policy"
+ if counter < 3:
+ assert values[0]["genre"] == "authz"
+ assert values[0]["description"] == "description"
+ else:
+ assert values[0]["genre"] == "not authz ?"
+ assert values[0]["description"] == "changes taken into account"
+ assert len(values[0]["model_id"]) > 0
+ import_export_utilities.clean_all(client)
+
+
+def test_import_subject_object_action():
+ client = utilities.register_client()
+ type_elements = ["object", "action"]
+
+ for type_element in type_elements:
+ import_export_utilities.clean_all(client)
+ counter = -1
+ # set the getters and the comparison values
+ if type_element == "subject":
+ elements = SUBJECTS
+ clean_method = import_export_utilities.clean_subjects
+ name = "testuser"
+ key_extra = "email"
+ value_extra = "new-email@test.com"
+ elif type_element == "object":
+ elements = OBJECTS
+ clean_method = import_export_utilities.clean_objects
+ name = "test object"
+ key_extra = "test"
+ value_extra = "test extra"
+ else:
+ elements = ACTIONS
+ clean_method = import_export_utilities.clean_actions
+ name = "test action"
+ key_extra = "test"
+ value_extra = "test extra"
+
+ for element in elements:
+ counter = counter + 1
+ if counter == 2 or counter == 4:
+ clean_method(client)
+
+ req = client.post("/import", content_type='application/json', data=json.dumps(element))
+ if counter < 2:
+ assert req.status_code == 500
+ continue
+
+ try:
+ data = utilities.get_json(req.data)
+ except Exception as e:
+ assert False
+ #assert counter < 2 #  this is an expected failure
+ #continue
+
+ assert data == "Import ok !"
+ get_elements = utilities.get_json(client.get("/"+type_element + "s").data)
+ get_elements = get_elements[type_element + "s"]
+
+ assert len(list(get_elements.keys())) == 1
+ values = list(get_elements.values())
+ assert values[0]["name"] == name
+ if counter == 2 or counter == 4:
+ assert values[0]["description"] == "description of the " + type_element
+ #assert not values[0]["extra"]
+ if counter == 3:
+ assert values[0]["description"] == "new description of the " + type_element
+ assert values[0]["extra"][key_extra] == value_extra
+
+ # assert len(values[0]["policy_list"]) == 1
+ import_export_utilities.clean_all(client)
+
+
+def test_import_subject_object_action_categories():
+ client = utilities.register_client()
+ type_elements = ["subject", "object", "action"]
+
+ for type_element in type_elements:
+ import_export_utilities.clean_all(client)
+ counter = -1
+ # set the getters and the comparison values
+ if type_element == "subject":
+ elements = SUBJECT_CATEGORIES
+ get_method = test_categories.get_subject_categories
+ elif type_element == "object":
+ elements = OBJECT_CATEGORIES
+ get_method = test_categories.get_object_categories
+ else:
+ elements = ACTION_CATEGORIES
+ get_method = test_categories.get_action_categories
+
+ for element in elements:
+ req = client.post("/import", content_type='application/json', data=json.dumps(element))
+ counter = counter + 1
+ data = utilities.get_json(req.data)
+ assert data == "Import ok !"
+ req, get_elements = get_method(client)
+ get_elements = get_elements[type_element + "_categories"]
+ assert len(list(get_elements.keys())) == 1
+ values = list(get_elements.values())
+ assert values[0]["name"] == "test " + type_element + " categories"
+ assert values[0]["description"] == type_element + " category description"
+
+
+def test_import_meta_rules():
+ client = utilities.register_client()
+ import_export_utilities.clean_all(client)
+ # import some categories
+ req = client.post("/import", content_type='application/json', data=json.dumps(PRE_META_RULES))
+ data = utilities.get_json(req.data)
+ assert data == "Import ok !"
+
+ counter = -1
+ for meta_rule in META_RULES:
+ counter = counter + 1
+ req = client.post("/import", content_type='application/json', data=json.dumps(meta_rule))
+ if counter != 3:
+ assert req.status_code == 500
+ continue
+ else:
+ data = utilities.get_json(req.data)
+ assert data == "Import ok !"
+ assert req.status_code == 200
+
+ req, meta_rules = test_meta_rules.get_meta_rules(client)
+ meta_rules = meta_rules["meta_rules"]
+ key = list(meta_rules.keys())[0]
+ assert isinstance(meta_rules,dict)
+ assert meta_rules[key]["name"] == "good meta rule"
+ assert meta_rules[key]["description"] == "valid meta rule"
+ assert len(meta_rules[key]["subject_categories"]) == 1
+ assert len(meta_rules[key]["object_categories"]) == 1
+ assert len(meta_rules[key]["action_categories"]) == 1
+
+ subject_category_key = meta_rules[key]["subject_categories"][0]
+ object_category_key = meta_rules[key]["object_categories"][0]
+ action_category_key = meta_rules[key]["action_categories"][0]
+
+ req, sub_cat = test_categories.get_subject_categories(client)
+ sub_cat = sub_cat["subject_categories"]
+ assert sub_cat[subject_category_key]["name"] == "test subject categories"
+
+ req, ob_cat = test_categories.get_object_categories(client)
+ ob_cat = ob_cat["object_categories"]
+ assert ob_cat[object_category_key]["name"] == "test object categories"
+
+ req, ac_cat = test_categories.get_action_categories(client)
+ ac_cat = ac_cat["action_categories"]
+ assert ac_cat[action_category_key]["name"] == "test action categories"
+
+ import_export_utilities.clean_all(client)
+
+
+def test_import_subject_object_action_assignments():
+ client = utilities.register_client()
+ import_export_utilities.clean_all(client)
+ req = client.post("/import", content_type='application/json', data=json.dumps(PRE_ASSIGNMENTS))
+ data = utilities.get_json(req.data)
+ assert data == "Import ok !"
+
+ type_elements = ["subject", "object", "action"]
+
+ for type_element in type_elements:
+ counter = -1
+ if type_element == "subject":
+ datas = SUBJECT_ASSIGNMENTS
+ get_method = test_assignments.get_subject_assignment
+ elif type_element == "object":
+ datas = OBJECT_ASSIGNMENTS
+ get_method = test_assignments.get_object_assignment
+ else:
+ datas = ACTION_ASSIGNMENTS
+ get_method = test_assignments.get_action_assignment
+
+ for assignments in datas:
+ counter = counter + 1
+ req = client.post("/import", content_type='application/json', data=json.dumps(assignments))
+ if counter != 3:
+ assert req.status_code == 500
+ continue
+ else:
+ assert data == "Import ok !"
+ assert req.status_code == 200
+ req, policies = test_policies.get_policies(client)
+ for policy_key in policies["policies"]:
+ req, get_assignments = get_method(client, policy_key)
+ get_assignments = get_assignments[type_element+"_assignments"]
+ assert len(get_assignments) == 1
+
+
+def test_import_rules():
+ client = utilities.register_client()
+ import_export_utilities.clean_all(client)
+ req = client.post("/import", content_type='application/json', data=json.dumps(PRE_ASSIGNMENTS))
+ data = utilities.get_json(req.data)
+ assert data == "Import ok !"
+
+ counter = -1
+ for rule in RULES:
+ counter = counter + 1
+ req = client.post("/import", content_type='application/json', data=json.dumps(rule))
+
+ if counter < 5:
+ assert req.status_code == 500
+ continue
+
+ assert req.status_code == 200
+
+ req, rules = test_rules.test_get_rules()
+ rules = rules["rules"]
+ rules = rules["rules"]
+ assert len(rules) == 1
+ rules = rules[0]
+ assert rules["enabled"]
+ assert rules["instructions"]["decision"] == "grant"
+
+ req, meta_rules = test_meta_rules.get_meta_rules(client)
+ assert meta_rules["meta_rules"][list(meta_rules["meta_rules"].keys())[0]]["name"] == "good meta rule"
+
+
+def test_import_subject_object_action_data():
+ client = utilities.register_client()
+ type_elements = ["subject", "object", "action"]
+
+ for type_element in type_elements:
+ import_export_utilities.clean_all(client)
+ req = client.post("/import", content_type='application/json', data=json.dumps(PRE_DATA))
+ counter = -1
+ # set the getters and the comparison values
+ if type_element == "subject":
+ elements = SUBJECT_DATA
+ get_method = test_data.get_subject_data
+ get_categories = test_categories.get_subject_categories
+ elif type_element == "object":
+ elements = OBJECT_DATA
+ get_method = test_data.get_object_data
+ get_categories = test_categories.get_object_categories
+ else:
+ elements = ACTION_DATA
+ get_method = test_data.get_action_data
+ get_categories = test_categories.get_action_categories
+
+ for element in elements:
+ req = client.post("/import", content_type='application/json', data=json.dumps(element))
+ counter = counter + 1
+ if counter == 0 or counter == 1:
+ assert req.status_code == 500
+ continue
+ assert req.status_code == 200
+ data = utilities.get_json(req.data)
+ assert data == "Import ok !"
+
+ req, policies = test_policies.get_policies(client)
+ policies = policies["policies"]
+ req, categories = get_categories(client)
+ categories = categories[type_element + "_categories"]
+ case_tested = False
+ for policy_key in policies.keys():
+ policy = policies[policy_key]
+ for category_key in categories:
+ req, get_elements = get_method(client, policy_id=policy_key, category_id=category_key)
+ if len(get_elements[type_element+"_data"]) == 0:
+ continue
+
+ # do this because the backend gives an element with empty data if the policy_key,
+ # category_key couple does not have any data...
+ get_elements = get_elements[type_element+"_data"]
+ if len(get_elements[0]["data"]) == 0:
+ continue
+
+ if policy["name"] == "test policy":
+ assert len(get_elements) == 1
+ el = get_elements[0]
+ assert isinstance(el["data"], dict)
+ if counter == 2:
+ assert len(el["data"].keys()) == 1
+ el = el["data"][list(el["data"].keys())[0]]
+ if "value" in el:
+ el = el["value"]
+ assert el["name"] == "one valid " + type_element + " data"
+ if counter == 3:
+ assert len(el["data"].keys()) == 2
+ el1 = el["data"][list(el["data"].keys())[0]]
+ el2 = el["data"][list(el["data"].keys())[1]]
+ if "value" in el1:
+ el1 = el1["value"]
+ el2 = el2["value"]
+ assert (el1["name"] == "one valid " + type_element + " data" and el2["name"] == "valid " + type_element + " data") or (el2["name"] == "one valid " + type_element + " data" and el1["name"] == "valid " + type_element + " data")
+ assert el1["description"] == "description"
+ assert el2["description"] == "description"
+
+ case_tested = True
+
+ if policy["name"] == "test other policy":
+ if counter == 4:
+ assert len(get_elements) == 1
+ el = get_elements[0]
+ assert isinstance(el["data"], dict)
+ assert len(el["data"].keys()) == 1
+ el = el["data"][list(el["data"].keys())[0]]
+ if "value" in el:
+ el = el["value"]
+ assert el["name"] == "valid " + type_element + " data"
+ assert el["description"] == "new description"
+ case_tested = True
+
+ assert case_tested is True
+
+
+def test_clean():
+ client = utilities.register_client()
+ import_export_utilities.clean_all(client)
+ #restore the database as previously
+ utilities.get_policy_id()
diff --git a/moon_manager/tests/unit_python/api/test_meta_data.py b/moon_manager/tests/unit_python/api/test_meta_data.py
new file mode 100644
index 00000000..4cb86913
--- /dev/null
+++ b/moon_manager/tests/unit_python/api/test_meta_data.py
@@ -0,0 +1,235 @@
+import json
+import api.utilities as utilities
+
+#subject_categories_test
+
+
+def get_subject_categories(client):
+ req = client.get("/subject_categories")
+ subject_categories = utilities.get_json(req.data)
+ return req, subject_categories
+
+
+def add_subject_categories(client, name):
+ data = {
+ "name": name,
+ "description": "description of {}".format(name)
+ }
+ req = client.post("/subject_categories", data=json.dumps(data),
+ headers={'Content-Type': 'application/json'})
+ subject_categories = utilities.get_json(req.data)
+ return req, subject_categories
+
+
+def delete_subject_categories(client, name):
+ request, subject_categories = get_subject_categories(client)
+ for key, value in subject_categories['subject_categories'].items():
+ if value['name'] == name:
+ return client.delete("/subject_categories/{}".format(key))
+
+
+def delete_subject_categories_without_id(client):
+ req = client.delete("/subject_categories/{}".format(""))
+ return req
+
+
+def test_get_subject_categories():
+ client = utilities.register_client()
+ req, subject_categories = get_subject_categories(client)
+ assert req.status_code == 200
+ assert isinstance(subject_categories, dict)
+ assert "subject_categories" in subject_categories
+
+
+def test_add_subject_categories():
+ client = utilities.register_client()
+ req, subject_categories = add_subject_categories(client, "testuser")
+ assert req.status_code == 200
+ assert isinstance(subject_categories, dict)
+ value = list(subject_categories["subject_categories"].values())[0]
+ assert "subject_categories" in subject_categories
+ assert value['name'] == "testuser"
+ assert value['description'] == "description of {}".format("testuser")
+
+
+def test_add_subject_categories_with_empty_user():
+ client = utilities.register_client()
+ req, subject_categories = add_subject_categories(client, "")
+ assert req.status_code == 400
+ assert json.loads(req.data)["message"] == "Key: 'name', [Empty String]"
+
+
+def test_add_subject_categories_with_user_contain_space():
+ client = utilities.register_client()
+ req, subject_categories = add_subject_categories(client, "test user")
+ assert req.status_code == 400
+ assert json.loads(req.data)["message"] == "Key: 'name', [String contains space]"
+
+
+def test_delete_subject_categories():
+ client = utilities.register_client()
+ req = delete_subject_categories(client, "testuser")
+ assert req.status_code == 200
+
+
+def test_delete_subject_categories_without_id():
+ client = utilities.register_client()
+ req = delete_subject_categories_without_id(client)
+ assert req.status_code == 400
+ assert json.loads(req.data)["message"] == "400: Subject Category Unknown"
+
+
+#---------------------------------------------------------------------------
+#object_categories_test
+
+def get_object_categories(client):
+ req = client.get("/object_categories")
+ object_categories = utilities.get_json(req.data)
+ return req, object_categories
+
+
+def add_object_categories(client, name):
+ data = {
+ "name": name,
+ "description": "description of {}".format(name)
+ }
+ req = client.post("/object_categories", data=json.dumps(data),
+ headers={'Content-Type': 'application/json'})
+ object_categories = utilities.get_json(req.data)
+ return req, object_categories
+
+
+def delete_object_categories(client, name):
+ request, object_categories = get_object_categories(client)
+ for key, value in object_categories['object_categories'].items():
+ if value['name'] == name:
+ return client.delete("/object_categories/{}".format(key))
+
+
+def delete_object_categories_without_id(client):
+ req = client.delete("/object_categories/{}".format(""))
+ return req
+
+
+def test_get_object_categories():
+ client = utilities.register_client()
+ req, object_categories = get_object_categories(client)
+ assert req.status_code == 200
+ assert isinstance(object_categories, dict)
+ assert "object_categories" in object_categories
+
+
+def test_add_object_categories():
+ client = utilities.register_client()
+ req, object_categories = add_object_categories(client, "testuser")
+ assert req.status_code == 200
+ assert isinstance(object_categories, dict)
+ value = list(object_categories["object_categories"].values())[0]
+ assert "object_categories" in object_categories
+ assert value['name'] == "testuser"
+ assert value['description'] == "description of {}".format("testuser")
+
+
+def test_add_object_categories_with_empty_user():
+ client = utilities.register_client()
+ req, object_categories = add_object_categories(client, "")
+ assert req.status_code == 400
+ assert json.loads(req.data)["message"] == "Key: 'name', [Empty String]"
+
+
+def test_add_object_categories_with_user_contain_space():
+ client = utilities.register_client()
+ req, object_categories = add_object_categories(client, "test user")
+ assert req.status_code == 400
+ assert json.loads(req.data)["message"] == "Key: 'name', [String contains space]"
+
+
+def test_delete_object_categories():
+ client = utilities.register_client()
+ req = delete_object_categories(client, "testuser")
+ assert req.status_code == 200
+
+
+def test_delete_object_categories_without_id():
+ client = utilities.register_client()
+ req = delete_object_categories_without_id(client)
+ assert req.status_code == 400
+ assert json.loads(req.data)["message"] == "400: Object Category Unknown"
+
+
+#---------------------------------------------------------------------------
+#action_categories_test
+
+def get_action_categories(client):
+ req = client.get("/action_categories")
+ action_categories = utilities.get_json(req.data)
+ return req, action_categories
+
+
+def add_action_categories(client, name):
+ data = {
+ "name": name,
+ "description": "description of {}".format(name)
+ }
+ req = client.post("/action_categories", data=json.dumps(data),
+ headers={'Content-Type': 'application/json'})
+ action_categories = utilities.get_json(req.data)
+ return req, action_categories
+
+
+def delete_action_categories(client, name):
+ request, action_categories = get_action_categories(client)
+ for key, value in action_categories['action_categories'].items():
+ if value['name'] == name:
+ return client.delete("/action_categories/{}".format(key))
+
+
+def delete_action_categories_without_id(client):
+ req = client.delete("/action_categories/{}".format(""))
+ return req
+
+
+def test_get_action_categories():
+ client = utilities.register_client()
+ req, action_categories = get_action_categories(client)
+ assert req.status_code == 200
+ assert isinstance(action_categories, dict)
+ assert "action_categories" in action_categories
+
+
+def test_add_action_categories():
+ client = utilities.register_client()
+ req, action_categories = add_action_categories(client, "testuser")
+ assert req.status_code == 200
+ assert isinstance(action_categories, dict)
+ value = list(action_categories["action_categories"].values())[0]
+ assert "action_categories" in action_categories
+ assert value['name'] == "testuser"
+ assert value['description'] == "description of {}".format("testuser")
+
+
+def test_add_action_categories_with_empty_user():
+ client = utilities.register_client()
+ req, action_categories = add_action_categories(client, "")
+ assert req.status_code == 400
+ assert json.loads(req.data)["message"] == "Key: 'name', [Empty String]"
+
+
+def test_add_action_categories_with_user_contain_space():
+ client = utilities.register_client()
+ req, action_categories = add_action_categories(client, "test user")
+ assert req.status_code == 400
+ assert json.loads(req.data)["message"] == "Key: 'name', [String contains space]"
+
+
+def test_delete_action_categories():
+ client = utilities.register_client()
+ req = delete_action_categories(client, "testuser")
+ assert req.status_code == 200
+
+
+def test_delete_action_categories_without_id():
+ client = utilities.register_client()
+ req = delete_action_categories_without_id(client)
+ assert req.status_code == 400
+ assert json.loads(req.data)["message"] == "400: Action Category Unknown"
diff --git a/moon_manager/tests/unit_python/api/test_meta_rules.py b/moon_manager/tests/unit_python/api/test_meta_rules.py
new file mode 100644
index 00000000..80d648b4
--- /dev/null
+++ b/moon_manager/tests/unit_python/api/test_meta_rules.py
@@ -0,0 +1,175 @@
+import json
+import api.utilities as utilities
+from helpers import category_helper
+from uuid import uuid4
+
+
+def get_meta_rules(client):
+ req = client.get("/meta_rules")
+ meta_rules = utilities.get_json(req.data)
+ return req, meta_rules
+
+
+def add_meta_rules(client, name):
+ subject_category = category_helper.add_subject_category(value={"name": "subject category name"+uuid4().hex, "description": "description 1"})
+ subject_category_id = list(subject_category.keys())[0]
+ object_category = category_helper.add_object_category(value={"name": "object category name"+ uuid4().hex, "description": "description 1"})
+ object_category_id = list(object_category.keys())[0]
+ action_category = category_helper.add_action_category(value={"name": "action category name"+uuid4().hex, "description": "description 1"})
+ action_category_id = list(action_category.keys())[0]
+
+ data = {
+ "name": name,
+ "subject_categories": [subject_category_id],
+ "object_categories": [object_category_id],
+ "action_categories": [action_category_id]
+ }
+ req = client.post("/meta_rules", data=json.dumps(data),
+ headers={'Content-Type': 'application/json'})
+ meta_rules = utilities.get_json(req.data)
+ return req, meta_rules
+
+
+def add_meta_rules_without_subject_category_ids(client, name):
+ data = {
+ "name": name,
+ "subject_categories": [],
+ "object_categories": ["object_category_id1"],
+ "action_categories": ["action_category_id1"]
+ }
+ req = client.post("/meta_rules", data=json.dumps(data),
+ headers={'Content-Type': 'application/json'})
+ meta_rules = utilities.get_json(req.data)
+ return req, meta_rules
+
+
+def update_meta_rules(client, name, metaRuleId):
+ subject_category = category_helper.add_subject_category(
+ value={"name": "subject category name update" + uuid4().hex, "description": "description 1"})
+ subject_category_id = list(subject_category.keys())[0]
+ object_category = category_helper.add_object_category(
+ value={"name": "object category name update" + uuid4().hex, "description": "description 1"})
+ object_category_id = list(object_category.keys())[0]
+ action_category = category_helper.add_action_category(
+ value={"name": "action category name update" + uuid4().hex, "description": "description 1"})
+ action_category_id = list(action_category.keys())[0]
+ data = {
+ "name": name,
+ "subject_categories": [subject_category_id],
+ "object_categories": [object_category_id],
+ "action_categories": [action_category_id]
+ }
+ req = client.patch("/meta_rules/{}".format(metaRuleId), data=json.dumps(data),
+ headers={'Content-Type': 'application/json'})
+ meta_rules = utilities.get_json(req.data)
+ return req, meta_rules
+
+
+def update_meta_rules_without_subject_category_ids(client, name):
+ data = {
+ "name": name,
+ "subject_categories": [],
+ "object_categories": ["object_category_id1"],
+ "action_categories": ["action_category_id1"]
+ }
+ req = client.post("/meta_rules", data=json.dumps(data),
+ headers={'Content-Type': 'application/json'})
+ meta_rules = utilities.get_json(req.data)
+ return req, meta_rules
+
+
+def delete_meta_rules(client, name):
+ request, meta_rules = get_meta_rules(client)
+ for key, value in meta_rules['meta_rules'].items():
+ if value['name'] == name:
+ req = client.delete("/meta_rules/{}".format(key))
+ break
+ return req
+
+
+def delete_meta_rules_without_id(client):
+ req = client.delete("/meta_rules/{}".format(""))
+ return req
+
+
+def test_get_meta_rules():
+ client = utilities.register_client()
+ req, meta_rules = get_meta_rules(client)
+ assert req.status_code == 200
+ assert isinstance(meta_rules, dict)
+ assert "meta_rules" in meta_rules
+
+
+def test_add_meta_rules():
+ client = utilities.register_client()
+ req, meta_rules = add_meta_rules(client, "testuser")
+ assert req.status_code == 200
+ assert isinstance(meta_rules, dict)
+ value = list(meta_rules["meta_rules"].values())[0]
+ assert "meta_rules" in meta_rules
+ assert value['name'] == "testuser"
+
+
+def test_add_meta_rules_with_empty_user():
+ client = utilities.register_client()
+ req, meta_rules = add_meta_rules(client, "")
+ assert req.status_code == 400
+ assert json.loads(req.data)["message"] == "Key: 'name', [Empty String]"
+
+
+def test_add_meta_rules_with_user_contain_space():
+ client = utilities.register_client()
+ req, meta_rules = add_meta_rules(client, "test user")
+ assert req.status_code == 400
+ assert json.loads(req.data)["message"] == "Key: 'name', [String contains space]"
+
+
+def test_add_meta_rules_without_subject_categories():
+ client = utilities.register_client()
+ req, meta_rules = add_meta_rules_without_subject_category_ids(client, "testuser")
+ assert req.status_code == 400
+ assert json.loads(req.data)["message"] == "Key: 'subject_categories', [Empty Container]"
+
+
+def test_delete_meta_rules():
+ client = utilities.register_client()
+ req = delete_meta_rules(client, "testuser")
+ assert req.status_code == 200
+
+
+def test_delete_meta_rules_without_id():
+ client = utilities.register_client()
+ req = delete_meta_rules_without_id(client)
+ assert req.status_code == 400
+ assert json.loads(req.data)["message"] == "400: Meta Rule Unknown"
+
+
+def test_update_meta_rules():
+ client = utilities.register_client()
+ req = add_meta_rules(client, "testuser")
+ meta_rule_id = list(req[1]['meta_rules'])[0]
+ req_update = update_meta_rules(client, "testuser", meta_rule_id)
+ assert req_update[0].status_code == 200
+ delete_meta_rules(client, "testuser")
+ get_meta_rules(client)
+
+
+def test_update_meta_rules_without_id():
+ client = utilities.register_client()
+ req_update = update_meta_rules(client, "testuser", "")
+ assert req_update[0].status_code == 400
+ assert json.loads(req_update[0].data)["message"] == "400: Meta Rule Unknown"
+
+
+def test_update_meta_rules_without_user():
+ client = utilities.register_client()
+ req_update = update_meta_rules(client, "", "")
+ assert req_update[0].status_code == 400
+ assert json.loads(req_update[0].data)["message"] == "Key: 'name', [Empty String]"
+
+
+def test_update_meta_rules_without_subject_categories():
+ client = utilities.register_client()
+ req_update = update_meta_rules_without_subject_category_ids(client, "testuser")
+ assert req_update[0].status_code == 400
+ assert json.loads(req_update[0].data)["message"] == "Key: 'subject_categories', [Empty Container]"
diff --git a/moon_manager/tests/unit_python/api/test_models.py b/moon_manager/tests/unit_python/api/test_models.py
deleted file mode 100644
index 3c205d1d..00000000
--- a/moon_manager/tests/unit_python/api/test_models.py
+++ /dev/null
@@ -1,67 +0,0 @@
-import json
-import api.utilities as utilities
-
-
-def get_models(client):
- req = client.get("/models")
- models = utilities.get_json(req.data)
- return req, models
-
-
-def add_models(client, name):
- data = {
- "name": name,
- "description": "description of {}".format(name),
- "meta_rules": ["meta_rule_id1", "meta_rule_id2"]
- }
- req = client.post("/models", data=json.dumps(data),
- headers={'Content-Type': 'application/json'})
- models = utilities.get_json(req.data)
- return req, models
-
-
-def delete_models(client, name):
- request, models = get_models(client)
- for key, value in models['models'].items():
- if value['name'] == name:
- req = client.delete("/models/{}".format(key))
- break
- return req
-
-
-def delete_models_without_id(client):
- req = client.delete("/models/{}".format(""))
- return req
-
-
-def test_get_models():
- client = utilities.register_client()
- req, models= get_models(client)
- assert req.status_code == 200
- assert isinstance(models, dict)
- assert "models" in models
-
-
-def test_add_models():
- client = utilities.register_client()
- req, models = add_models(client, "testuser")
- assert req.status_code == 200
- assert isinstance(models, dict)
- value = list(models["models"].values())[0]
- assert "models" in models
- assert value['name'] == "testuser"
- assert value["description"] == "description of {}".format("testuser")
- assert value["meta_rules"][0] == "meta_rule_id1"
-
-
-def test_delete_models():
- client = utilities.register_client()
- req = delete_models(client, "testuser")
- assert req.status_code == 200
-
-
-def test_delete_models_without_id():
- client = utilities.register_client()
- req = delete_models_without_id(client)
- assert req.status_code == 500
-
diff --git a/moon_manager/tests/unit_python/api/test_pdp.py b/moon_manager/tests/unit_python/api/test_pdp.py
index a2d0cb5a..1ac9b84f 100644
--- a/moon_manager/tests/unit_python/api/test_pdp.py
+++ b/moon_manager/tests/unit_python/api/test_pdp.py
@@ -1,6 +1,7 @@
import json
import api.utilities as utilities
-import pytest
+from helpers import data_builder as builder
+from uuid import uuid4
def get_pdp(client):
@@ -16,6 +17,13 @@ def add_pdp(client, data):
return req, pdp
+def update_pdp(client, data, pdp_id):
+ req = client.patch("/pdp/{}".format(pdp_id), data=json.dumps(data),
+ headers={'Content-Type': 'application/json'})
+ pdp = utilities.get_json(req.data)
+ return req, pdp
+
+
def delete_pdp(client, key):
req = client.delete("/pdp/{}".format(key))
return req
@@ -35,9 +43,15 @@ def test_get_pdp():
def test_add_pdp():
+ subject_category_id, object_category_id, action_category_id, meta_rule_id, policy_id = builder.create_new_policy(
+ subject_category_name="subject_category1" + uuid4().hex,
+ object_category_name="object_category1" + uuid4().hex,
+ action_category_name="action_category1" + uuid4().hex,
+ meta_rule_name="meta_rule_1" + uuid4().hex,
+ model_name="model1" + uuid4().hex)
data = {
"name": "testuser",
- "security_pipeline": ["policy_id_1", "policy_id_2"],
+ "security_pipeline": [policy_id],
"keystone_project_id": "keystone_project_id",
"description": "description of testuser"
}
@@ -60,3 +74,128 @@ def test_delete_pdp():
success_req = delete_pdp(client, key)
break
assert success_req.status_code == 200
+
+
+def test_add_pdp_with_empty_user():
+ data = {
+ "name": "",
+ "security_pipeline": ["policy_id_1", "policy_id_2"],
+ "keystone_project_id": "keystone_project_id",
+ "description": "description of testuser"
+ }
+ client = utilities.register_client()
+ req, models = add_pdp(client, data)
+ assert req.status_code == 400
+ assert json.loads(req.data)["message"] == "Key: 'name', [Empty String]"
+
+
+def test_add_pdp_with_user_contain_space():
+ data = {
+ "name": "test user",
+ "security_pipeline": ["policy_id_1", "policy_id_2"],
+ "keystone_project_id": "keystone_project_id",
+ "description": "description of testuser"
+ }
+ client = utilities.register_client()
+ req, models = add_pdp(client, data)
+ assert req.status_code == 400
+ assert json.loads(req.data)["message"] == "Key: 'name', [String contains space]"
+
+
+def test_add_pdp_without_security_pipeline():
+ data = {
+ "name": "testuser",
+ "security_pipeline": [],
+ "keystone_project_id": "keystone_project_id",
+ "description": "description of testuser"
+ }
+ client = utilities.register_client()
+ req, meta_rules = add_pdp(client, data)
+ assert req.status_code == 400
+ assert json.loads(req.data)["message"] == "Key: 'security_pipeline', [Empty Container]"
+
+
+def test_add_pdp_without_keystone():
+ data = {
+ "name": "testuser",
+ "security_pipeline": ["policy_id_1", "policy_id_2"],
+ "keystone_project_id": "",
+ "description": "description of testuser"
+ }
+ client = utilities.register_client()
+ req, meta_rules = add_pdp(client, data)
+ assert req.status_code == 400
+ assert json.loads(req.data)["message"] == "Key: 'keystone_project_id', [Empty String]"
+
+
+def test_update_pdp():
+ subject_category_id, object_category_id, action_category_id, meta_rule_id, policy_id = builder.create_new_policy(
+ subject_category_name="subject_category1"+uuid4().hex,
+ object_category_name="object_category1"+uuid4().hex,
+ action_category_name="action_category1"+uuid4().hex,
+ meta_rule_name="meta_rule_1"+uuid4().hex,
+ model_name="model1"+uuid4().hex)
+ data_add = {
+ "name": "testuser",
+ "security_pipeline": [policy_id],
+ "keystone_project_id": "keystone_project_id",
+ "description": "description of testuser"
+ }
+
+ subject_category_id, object_category_id, action_category_id, meta_rule_id, policy_id_update = builder.create_new_policy(
+ subject_category_name="subject_category1" + uuid4().hex,
+ object_category_name="object_category1" + uuid4().hex,
+ action_category_name="action_category1" + uuid4().hex,
+ meta_rule_name="meta_rule_1" + uuid4().hex,
+ model_name="model1" + uuid4().hex)
+ data_update = {
+ "name": "testuser",
+ "security_pipeline": [policy_id_update],
+ "keystone_project_id": "keystone_project_id_update",
+ "description": "description of testuser"
+ }
+ client = utilities.register_client()
+ req = add_pdp(client, data_add)
+ pdp_id = list(req[1]['pdps'])[0]
+ req_update = update_pdp(client, data_update, pdp_id)
+ assert req_update[0].status_code == 200
+ value = list(req_update[1]["pdps"].values())[0]
+ assert value["keystone_project_id"] == "keystone_project_id_update"
+ request, pdp = get_pdp(client)
+ for key, value in pdp['pdps'].items():
+ if value['name'] == "testuser":
+ delete_pdp(client, key)
+ break
+
+
+def test_update_pdp_without_id():
+ client = utilities.register_client()
+ req_update = update_pdp(client, "testuser", "")
+ assert req_update[0].status_code == 400
+ assert json.loads(req_update[0].data)["message"] == 'Invalid Key :name not found'
+
+
+def test_update_pdp_without_user():
+ data = {
+ "name": "",
+ "security_pipeline": ["policy_id_1", "policy_id_2"],
+ "keystone_project_id": "keystone_project_id",
+ "description": "description of testuser"
+ }
+ client = utilities.register_client()
+ req_update = update_pdp(client, data, "")
+ assert req_update[0].status_code == 400
+ assert json.loads(req_update[0].data)["message"] == "Key: 'name', [Empty String]"
+
+
+def test_update_pdp_without_security_pipeline():
+ data = {
+ "name": "testuser",
+ "security_pipeline": [],
+ "keystone_project_id": "keystone_project_id",
+ "description": "description of testuser"
+ }
+ client = utilities.register_client()
+ req_update = update_pdp(client, data, "")
+ assert req_update[0].status_code == 400
+ assert json.loads(req_update[0].data)["message"] == "Key: 'security_pipeline', [Empty Container]" \ No newline at end of file
diff --git a/moon_manager/tests/unit_python/api/test_perimeter.py b/moon_manager/tests/unit_python/api/test_perimeter.py
index db09780f..322d90c6 100644
--- a/moon_manager/tests/unit_python/api/test_perimeter.py
+++ b/moon_manager/tests/unit_python/api/test_perimeter.py
@@ -2,156 +2,282 @@
# import moon_manager.api
import json
import api.utilities as utilities
+from helpers import data_builder as builder
+from uuid import uuid4
def get_subjects(client):
req = client.get("/subjects")
- assert req.status_code == 200
subjects = utilities.get_json(req.data)
- assert isinstance(subjects, dict)
- assert "subjects" in subjects
- return subjects
+ return req, subjects
def add_subjects(client, name):
+ subject_category_id, object_category_id, action_category_id, meta_rule_id, policy_id = builder.create_new_policy(
+ subject_category_name="subject_category1" + uuid4().hex,
+ object_category_name="object_category1" + uuid4().hex,
+ action_category_name="action_category1" + uuid4().hex,
+ meta_rule_name="meta_rule_1" + uuid4().hex,
+ model_name="model1" + uuid4().hex)
data = {
- "name": name,
+ "name": name + uuid4().hex,
"description": "description of {}".format(name),
"password": "password for {}".format(name),
"email": "{}@moon".format(name)
}
- req = client.post("/subjects", data=json.dumps(data),
+ req = client.post("/policies/{}/subjects".format(policy_id), data=json.dumps(data),
headers={'Content-Type': 'application/json'})
- assert req.status_code == 200
subjects = utilities.get_json(req.data)
+ return req, subjects
+
+
+def delete_subject(client):
+ subjects = get_subjects(client)
+ value = subjects[1]['subjects']
+ id = list(value.keys())[0]
+ policy_id = builder.get_policy_id_with_subject_assignment()
+ return client.delete("/policies/{}/subjects/{}".format(policy_id, id))
+
+
+def delete_subjects_without_perimeter_id(client):
+ req = client.delete("/subjects/{}".format(""))
+ return req
+
+
+def test_perimeter_get_subject():
+ client = utilities.register_client()
+ req, subjects = get_subjects(client)
+ assert req.status_code == 200
assert isinstance(subjects, dict)
- key = list(subjects["subjects"].keys())[0]
+ assert "subjects" in subjects
+
+
+def test_perimeter_add_subject():
+ client = utilities.register_client()
+ req, subjects = add_subjects(client, "testuser")
value = list(subjects["subjects"].values())[0]
+ assert req.status_code == 200
assert "subjects" in subjects
- assert key == "1111111111111"
- assert value['id'] == "1111111111111"
- assert value['name'] == name
- assert value["description"] == "description of {}".format(name)
- assert value["email"] == "{}@moon".format(name)
- return subjects
+ assert value["name"] is not None
+ assert value["email"] is not None
-def add_subjects_without_name(client, name):
+def test_perimeter_add_subject_without_name():
+ client = utilities.register_client()
data = {
- "name": name,
- "description": "description of {}".format(name),
- "password": "password for {}".format(name),
- "email": "{}@moon".format(name)
+ "name": "",
+ "description": "description of {}".format(""),
+ "password": "password for {}".format(""),
+ "email": "{}@moon".format("")
}
- req = client.post("/subjects", data=json.dumps(data),
+ req = client.post("/policies/{}/subjects".format("111"), data=json.dumps(data),
headers={'Content-Type': 'application/json'})
- assert req.status_code == 500
+ assert req.status_code == 400
+ assert json.loads(req.data)["message"] == "Key: 'name', [Empty String]"
-def delete_subject(client, name):
- subjects = get_subjects(client)
- for key, value in subjects['subjects'].items():
- if value['name'] == name:
- req = client.delete("/subjects/{}".format(key))
- assert req.status_code == 200
- break
- subjects = get_subjects(client)
- assert name not in [x['name'] for x in subjects["subjects"].values()]
+def test_perimeter_add_subject_with_name_contain_spaces():
+ client = utilities.register_client()
+ data = {
+ "name": "test user",
+ "description": "description of {}".format("test user"),
+ "password": "password for {}".format("test user"),
+ "email": "{}@moon".format("test user")
+ }
+ req = client.post("/policies/{}/subjects".format("111"), data=json.dumps(data),
+ headers={'Content-Type': 'application/json'})
+ assert req.status_code == 400
+ assert json.loads(req.data)["message"] == "Key: 'name', [String contains space]"
+
+
+def test_perimeter_delete_subject():
+ client = utilities.register_client()
+ req = delete_subject(client)
+ assert req.status_code == 200
-def test_subject():
+def test_perimeter_delete_subjects_without_perimeter_id():
client = utilities.register_client()
- get_subjects(client)
- add_subjects(client, "testuser")
- add_subjects_without_name(client, "")
- delete_subject(client, "testuser")
+ req = delete_subjects_without_perimeter_id(client)
+ assert req.status_code == 400
+ assert json.loads(req.data)["message"] == "400: Subject Unknown"
def get_objects(client):
req = client.get("/objects")
- assert req.status_code == 200
objects = utilities.get_json(req.data)
- assert isinstance(objects, dict)
- assert "objects" in objects
- return objects
+ return req, objects
def add_objects(client, name):
+ subject_category_id, object_category_id, action_category_id, meta_rule_id, policyId = builder.create_new_policy(
+ subject_category_name="subject_category1" + uuid4().hex,
+ object_category_name="object_category1" + uuid4().hex,
+ action_category_name="action_category1" + uuid4().hex,
+ meta_rule_name="meta_rule_1" + uuid4().hex,
+ model_name="model1" + uuid4().hex)
data = {
- "name": name,
+ "name": name + uuid4().hex,
"description": "description of {}".format(name),
}
- req = client.post("/objects", data=json.dumps(data),
+ req = client.post("/policies/{}/objects/".format(policyId), data=json.dumps(data),
headers={'Content-Type': 'application/json'})
- assert req.status_code == 200
objects = utilities.get_json(req.data)
+ return req, objects
+
+
+def delete_object(client):
+ objects = get_objects(client)
+ value = objects[1]['objects']
+ id = list(value.keys())[0]
+ policy_id = builder.get_policy_id_with_object_assignment()
+ return client.delete("/policies/{}/objects/{}".format(policy_id, id))
+
+
+def delete_objects_without_perimeter_id(client):
+ req = client.delete("/objects/{}".format(""))
+ return req
+
+
+def test_perimeter_get_object():
+ client = utilities.register_client()
+ req, objects = get_objects(client)
+ assert req.status_code == 200
assert isinstance(objects, dict)
- key = list(objects["objects"].keys())[0]
+ assert "objects" in objects
+
+
+def test_perimeter_add_object():
+ client = utilities.register_client()
+ req, objects = add_objects(client, "testuser")
value = list(objects["objects"].values())[0]
+ assert req.status_code == 200
assert "objects" in objects
- assert value['name'] == name
- assert value["description"] == "description of {}".format(name)
- return objects
+ assert value['name'] is not None
-def delete_objects(client, name):
- objects = get_objects(client)
- for key, value in objects['objects'].items():
- if value['name'] == name:
- req = client.delete("/objects/{}".format(key))
- assert req.status_code == 200
- break
- objects = get_objects(client)
- assert name not in [x['name'] for x in objects["objects"].values()]
+def test_perimeter_add_object_without_name():
+ client = utilities.register_client()
+ data = {
+ "name": "",
+ "description": "description of {}".format(""),
+ }
+ req = client.post("/policies/{}/objects/".format("111"), data=json.dumps(data),
+ headers={'Content-Type': 'application/json'})
+ assert req.status_code == 400
+ assert json.loads(req.data)["message"] == "Key: 'name', [Empty String]"
-def test_objects():
+def test_perimeter_add_object_with_name_contain_spaces():
client = utilities.register_client()
- get_objects(client)
- add_objects(client, "testuser")
- delete_objects(client, "testuser")
+ data = {
+ "name": "test user",
+ "description": "description of {}".format("test user"),
+ }
+ req = client.post("/policies/{}/objects/".format("111"), data=json.dumps(data),
+ headers={'Content-Type': 'application/json'})
+ assert req.status_code == 400
+ assert json.loads(req.data)["message"] == "Key: 'name', [String contains space]"
+
+
+def test_perimeter_delete_object():
+ client = utilities.register_client()
+ req = delete_object(client)
+ assert req.status_code == 200
+
+
+def test_perimeter_delete_objects_without_perimeter_id():
+ client = utilities.register_client()
+ req = delete_objects_without_perimeter_id(client)
+ assert req.status_code == 400
+ assert json.loads(req.data)["message"] == "400: Object Unknown"
def get_actions(client):
req = client.get("/actions")
- assert req.status_code == 200
actions = utilities.get_json(req.data)
- assert isinstance(actions, dict)
- assert "actions" in actions
- return actions
+ return req, actions
def add_actions(client, name):
+ subject_category_id, object_category_id, action_category_id, meta_rule_id, policyId = builder.create_new_policy(
+ subject_category_name="subject_category1" + uuid4().hex,
+ object_category_name="object_category1" + uuid4().hex,
+ action_category_name="action_category1" + uuid4().hex,
+ meta_rule_name="meta_rule_1" + uuid4().hex,
+ model_name="model1" + uuid4().hex)
data = {
- "name": name,
+ "name": name + uuid4().hex,
"description": "description of {}".format(name),
}
- req = client.post("/actions", data=json.dumps(data),
+ req = client.post("/policies/{}/actions".format(policyId), data=json.dumps(data),
headers={'Content-Type': 'application/json'})
- assert req.status_code == 200
actions = utilities.get_json(req.data)
+ return req, actions
+
+
+def delete_actions(client):
+ actions = get_actions(client)
+ value = actions[1]['actions']
+ id = list(value.keys())[0]
+ policy_id = builder.get_policy_id_with_action_assignment()
+ return client.delete("/policies/{}/actions/{}".format(policy_id, id))
+
+
+def delete_actions_without_perimeter_id(client):
+ req = client.delete("/actions/{}".format(""))
+ return req
+
+
+def test_perimeter_get_actions():
+ client = utilities.register_client()
+ req, actions = get_actions(client)
+ assert req.status_code == 200
assert isinstance(actions, dict)
- key = list(actions["actions"].keys())[0]
+ assert "actions" in actions
+
+
+def test_perimeter_add_actions():
+ client = utilities.register_client()
+ req, actions = add_actions(client, "testuser")
value = list(actions["actions"].values())[0]
+ assert req.status_code == 200
assert "actions" in actions
- assert value['name'] == name
- assert value["description"] == "description of {}".format(name)
- return actions
+ assert value['name'] is not None
-def delete_actions(client, name):
- actions = get_actions(client)
- for key, value in actions['actions'].items():
- if value['name'] == name:
- req = client.delete("/actions/{}".format(key))
- assert req.status_code == 200
- break
- actions = get_actions(client)
- assert name not in [x['name'] for x in actions["actions"].values()]
+def test_perimeter_add_actions_without_name():
+ client = utilities.register_client()
+ data = {
+ "name": "",
+ "description": "description of {}".format(""),
+ }
+ req = client.post("/policies/{}/actions".format("111"), data=json.dumps(data),
+ headers={'Content-Type': 'application/json'})
+ assert req.status_code == 400
+ assert json.loads(req.data)["message"] == "Key: 'name', [Empty String]"
+
+
+def test_perimeter_add_actions_with_name_contain_spaces():
+ client = utilities.register_client()
+ data = {
+ "name": "test user",
+ "description": "description of {}".format("test user"),
+ }
+ req = client.post("/policies/{}/actions".format("111"), data=json.dumps(data),
+ headers={'Content-Type': 'application/json'})
+ assert req.status_code == 400
+ assert json.loads(req.data)["message"] == "Key: 'name', [String contains space]"
+
+
+def test_perimeter_delete_actions():
+ client = utilities.register_client()
+ req = delete_actions(client)
+ assert req.status_code == 200
-def test_actions():
+def test_perimeter_delete_actions_without_perimeter_id():
client = utilities.register_client()
- get_actions(client)
- add_actions(client, "testuser")
- delete_actions(client, "testuser")
+ req = delete_actions_without_perimeter_id(client)
+ assert req.status_code == 400
+ assert json.loads(req.data)["message"] == "400: Action Unknown"
diff --git a/moon_manager/tests/unit_python/api/test_policies.py b/moon_manager/tests/unit_python/api/test_policies.py
index 4d4e387e..cd50f4c7 100644
--- a/moon_manager/tests/unit_python/api/test_policies.py
+++ b/moon_manager/tests/unit_python/api/test_policies.py
@@ -1,5 +1,12 @@
+# Copyright 2018 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 json
+from uuid import uuid4
import api.utilities as utilities
+from helpers import model_helper
def get_policies(client):
@@ -9,10 +16,12 @@ def get_policies(client):
def add_policies(client, name):
+ req = model_helper.add_model(model_id="mls_model_id"+uuid4().hex)
+ model_id = list(req.keys())[0]
data = {
"name": name,
"description": "description of {}".format(name),
- "model_id": "modelId",
+ "model_id": model_id,
"genre": "genre"
}
req = client.post("/policies", data=json.dumps(data),
@@ -24,9 +33,8 @@ def add_policies(client, name):
def delete_policies(client, name):
request, policies = get_policies(client)
for key, value in policies['policies'].items():
- if value['name'] == name:
- req = client.delete("/policies/{}".format(key))
- break
+ req = client.delete("/policies/{}".format(key))
+ break
return req
@@ -44,16 +52,15 @@ def test_get_policies():
def test_add_policies():
+ policy_name = "testuser" + uuid4().hex
client = utilities.register_client()
- req, policies = add_policies(client, "testuser")
+ req, policies = add_policies(client, policy_name)
assert req.status_code == 200
assert isinstance(policies, dict)
value = list(policies["policies"].values())[0]
assert "policies" in policies
- assert value['name'] == "testuser"
- assert value["description"] == "description of {}".format("testuser")
- assert value["model_id"] == "modelId"
- assert value["genre"] == "genre"
+ assert value['name'] == policy_name
+ assert value["description"] == "description of {}".format(policy_name)
def test_delete_policies():
@@ -65,5 +72,6 @@ def test_delete_policies():
def test_delete_policies_without_id():
client = utilities.register_client()
req = delete_policies_without_id(client)
- assert req.status_code == 500
+ assert req.status_code == 400
+ assert json.loads(req.data)["message"] == '400: Policy Unknown'
diff --git a/moon_manager/tests/unit_python/api/test_rules.py b/moon_manager/tests/unit_python/api/test_rules.py
index 86a3d390..af1501e4 100644
--- a/moon_manager/tests/unit_python/api/test_rules.py
+++ b/moon_manager/tests/unit_python/api/test_rules.py
@@ -1,5 +1,8 @@
import api.utilities as utilities
import json
+from helpers import data_builder as builder
+from uuid import uuid4
+from helpers import policy_helper
def get_rules(client, policy_id):
@@ -8,9 +11,45 @@ def get_rules(client, policy_id):
return req, rules
-def add_rules(client, policy_id):
+def add_rules(client):
+ sub_id, obj_id, act_id, meta_rule_id, policy_id = builder.create_new_policy("sub_cat" + uuid4().hex,
+ "obj_cat" + uuid4().hex,
+ "act_cat" + uuid4().hex)
+ sub_data_id = builder.create_subject_data(policy_id, sub_id)
+ obj_data_id = builder.create_object_data(policy_id, obj_id)
+ act_data_id = builder.create_action_data(policy_id, act_id)
data = {
- "meta_rule_id": "meta_rule_id1",
+ "meta_rule_id": meta_rule_id,
+ "rule": [sub_data_id, obj_data_id, act_data_id],
+ "instructions": (
+ {"decision": "grant"},
+ ),
+ "enabled": True
+ }
+ req = client.post("/policies/{}/rules".format(policy_id), data=json.dumps(data),
+ headers={'Content-Type': 'application/json'})
+ rules = utilities.get_json(req.data)
+ return req, rules
+
+
+def add_rules_without_policy_id(client):
+ data = {
+ "meta_rule_id": "meta_rule_id",
+ "rule": ["sub_data_id", "obj_data_id", "act_data_id"],
+ "instructions": (
+ {"decision": "grant"},
+ ),
+ "enabled": True
+ }
+ req = client.post("/policies/{}/rules".format(None), data=json.dumps(data),
+ headers={'Content-Type': 'application/json'})
+ rules = utilities.get_json(req.data)
+ return req, rules
+
+
+def add_rules_without_meta_rule_id(client, policy_id):
+ data = {
+ "meta_rule_id": "",
"rule": ["subject_data_id2", "object_data_id2", "action_data_id2"],
"instructions": (
{"decision": "grant"},
@@ -23,6 +62,20 @@ def add_rules(client, policy_id):
return req, rules
+def add_rules_without_rule(client, policy_id):
+ data = {
+ "meta_rule_id": "meta_rule_id1",
+ "instructions": (
+ {"decision": "grant"},
+ ),
+ "enabled": True
+ }
+ req = client.post("/policies/{}/rules".format(policy_id), data=json.dumps(data),
+ headers={'Content-Type': 'application/json'})
+ rules = utilities.get_json(req.data)
+ return req, rules
+
+
def delete_rules(client, policy_id, meta_rule_id):
req = client.delete("/policies/{}/rules/{}".format(policy_id, meta_rule_id))
return req
@@ -35,24 +88,61 @@ def test_get_rules():
assert req.status_code == 200
assert isinstance(rules, dict)
assert "rules" in rules
+ return req, rules
def test_add_rules():
- policy_id = utilities.get_policy_id()
client = utilities.register_client()
- req, rules = add_rules(client, policy_id)
+ req, rules = add_rules(client, )
assert req.status_code == 200
- assert isinstance(rules, dict)
- value = rules["rules"]
- assert "rules" in rules
- id = list(value.keys())[0]
- assert value[id]["meta_rule_id"] == "meta_rule_id1"
-def test_delete_rules():
+def test_add_rules_without_policy_id():
+ client = utilities.register_client()
+ req, rules = add_rules_without_policy_id(client)
+ assert req.status_code == 400
+ assert json.loads(req.data)["message"] == "400: Policy Unknown"
+
+
+def test_add_rules_without_meta_rule_id():
+ policy_id = utilities.get_policy_id()
client = utilities.register_client()
+ req, rules = add_rules_without_meta_rule_id(client, policy_id)
+ assert req.status_code == 400
+ assert json.loads(req.data)["message"] == "Key: 'meta_rule_id', [Empty String]"
+
+
+def test_add_rules_without_rule():
policy_id = utilities.get_policy_id()
+ client = utilities.register_client()
+ req, rules = add_rules_without_rule(client, policy_id)
+ assert req.status_code == 400
+ assert json.loads(req.data)["message"] == 'Invalid Key :rule not found'
+
+
+def test_delete_rules_with_invalid_parameters():
+ client = utilities.register_client()
+ rules = delete_rules(client, "", "")
+ assert rules.status_code == 404
+
+
+def test_delete_rules_without_policy_id():
+ client = utilities.register_client()
+ subject_category_id, object_category_id, action_category_id, meta_rule_id, policy_id = builder.create_new_policy()
+ sub_data_id = builder.create_subject_data(policy_id, subject_category_id)
+ obj_data_id = builder.create_object_data(policy_id, object_category_id)
+ act_data_id = builder.create_action_data(policy_id, action_category_id)
+ data = {
+ "meta_rule_id": meta_rule_id,
+ "rule": [sub_data_id, obj_data_id, act_data_id],
+ "instructions": (
+ {"decision": "grant"},
+ ),
+ "enabled": True
+ }
+ client.post("/policies/{}/rules".format(policy_id), data=json.dumps(data),
+ headers={'Content-Type': 'application/json'})
req, added_rules = get_rules(client, policy_id)
- id = added_rules["rules"]['rules'][0]['id']
- rules = delete_rules(client, policy_id, id)
+ id = list(added_rules["rules"]["rules"])[0]["id"]
+ rules = delete_rules(client, None, id)
assert rules.status_code == 200
diff --git a/moon_manager/tests/unit_python/api/test_unit_models.py b/moon_manager/tests/unit_python/api/test_unit_models.py
new file mode 100644
index 00000000..d754b976
--- /dev/null
+++ b/moon_manager/tests/unit_python/api/test_unit_models.py
@@ -0,0 +1,186 @@
+# Copyright 2018 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 json
+import api.utilities as utilities
+from helpers import data_builder as builder
+from uuid import uuid4
+
+
+def get_models(client):
+ req = client.get("/models")
+ models = utilities.get_json(req.data)
+ return req, models
+
+
+def add_models(client, name):
+ subject_category_id, object_category_id, action_category_id, meta_rule_id = builder.create_new_meta_rule(
+ subject_category_name="subject_category"+uuid4().hex,
+ object_category_name="object_category"+uuid4().hex, action_category_name="action_category"+uuid4().hex,
+ meta_rule_name="meta_rule" + uuid4().hex)
+ data = {
+ "name": name,
+ "description": "description of {}".format(name),
+ "meta_rules": [meta_rule_id]
+ }
+ req = client.post("/models", data=json.dumps(data),
+ headers={'Content-Type': 'application/json'})
+ models = utilities.get_json(req.data)
+ return req, models
+
+
+def update_model(client, name, model_id):
+ subject_category_id, object_category_id, action_category_id, meta_rule_id = builder.create_new_meta_rule(
+ subject_category_name="subject_category" + uuid4().hex,
+ object_category_name="object_category" + uuid4().hex, action_category_name="action_category" + uuid4().hex,
+ meta_rule_name="meta_rule" + uuid4().hex)
+
+ data = {
+ "name": name,
+ "description": "description of {}".format(name),
+ "meta_rules": [meta_rule_id]
+ }
+ req = client.patch("/models/{}".format(model_id), data=json.dumps(data),
+ headers={'Content-Type': 'application/json'})
+ models = utilities.get_json(req.data)
+ return req, models
+
+
+def add_model_without_meta_rules_ids(client, name):
+ data = {
+ "name": name,
+ "description": "description of {}".format(name),
+ "meta_rules": []
+ }
+ req = client.post("/models", data=json.dumps(data),
+ headers={'Content-Type': 'application/json'})
+ models = utilities.get_json(req.data)
+ return req, models
+
+
+def update_model_without_meta_rules_ids(client, name):
+ data = {
+ "name": name,
+ "description": "description of {}".format(name),
+ "meta_rules": []
+ }
+ req = client.patch("/models", data=json.dumps(data),
+ headers={'Content-Type': 'application/json'})
+ models = utilities.get_json(req.data)
+ return req, models
+
+
+def delete_models(client, name):
+ request, models = get_models(client)
+ for key, value in models['models'].items():
+ if value['name'] == name:
+ req = client.delete("/models/{}".format(key))
+ break
+ return req
+
+
+def delete_models_without_id(client):
+ req = client.delete("/models/{}".format(""))
+ return req
+
+
+def clean_models():
+ client = utilities.register_client()
+ req, models = get_models(client)
+ for key, value in models['models'].items():
+ print(key)
+ print(value)
+ client.delete("/models/{}".format(key))
+
+
+def test_get_models():
+ client = utilities.register_client()
+ req, models = get_models(client)
+ assert req.status_code == 200
+ assert isinstance(models, dict)
+ assert "models" in models
+
+
+def test_add_models():
+ clean_models()
+ client = utilities.register_client()
+ req, models = add_models(client, "testuser")
+ assert req.status_code == 200
+ assert isinstance(models, dict)
+ model_id = list(models["models"])[0]
+ assert "models" in models
+ assert models['models'][model_id]['name'] == "testuser"
+ assert models['models'][model_id]["description"] == "description of {}".format("testuser")
+
+
+def test_delete_models():
+ client = utilities.register_client()
+ req = delete_models(client, "testuser")
+ assert req.status_code == 200
+
+
+def test_delete_models_without_id():
+ client = utilities.register_client()
+ req = delete_models_without_id(client)
+ assert req.status_code == 400
+ assert json.loads(req.data)["message"] == "400: Model Unknown"
+
+
+def test_add_model_with_empty_user():
+ clean_models()
+ client = utilities.register_client()
+ req, models = add_models(client, "")
+ assert req.status_code == 400
+ assert json.loads(req.data)["message"] == "Key: 'name', [Empty String]"
+
+
+def test_add_model_with_user_contain_space():
+ clean_models()
+ client = utilities.register_client()
+ req, models = add_models(client, "test user")
+ assert req.status_code == 400
+ assert json.loads(req.data)["message"] == "Key: 'name', [String contains space]"
+
+
+def test_add_model_without_meta_rules():
+ clean_models()
+ client = utilities.register_client()
+ req, meta_rules = add_model_without_meta_rules_ids(client, "testuser")
+ assert req.status_code == 400
+ assert json.loads(req.data)["message"] == "Key: 'meta_rules', [Empty Container]"
+
+
+def test_update_model():
+ clean_models()
+ client = utilities.register_client()
+ req = add_models(client, "testuser")
+ model_id = list(req[1]['models'])[0]
+ req_update = update_model(client, "testuser", model_id)
+ assert req_update[0].status_code == 200
+ model_id = list(req_update[1]["models"])[0]
+ assert req_update[1]["models"][model_id]["meta_rules"][0] is not None
+ delete_models(client, "testuser")
+
+
+def test_update_meta_rules_without_id():
+ clean_models()
+ client = utilities.register_client()
+ req_update = update_model(client, "testuser", "")
+ assert req_update[0].status_code == 400
+ assert json.loads(req_update[0].data)["message"] == "400: Model Unknown"
+
+
+def test_update_meta_rules_without_user():
+ client = utilities.register_client()
+ req_update = update_model(client, "", "")
+ assert req_update[0].status_code == 400
+ assert json.loads(req_update[0].data)["message"] == "Key: 'name', [Empty String]"
+
+
+def test_update_meta_rules_without_meta_rules():
+ client = utilities.register_client()
+ req_update = update_model_without_meta_rules_ids(client, "testuser")
+ assert req_update[0].status_code == 400
+ assert json.loads(req_update[0].data)["message"] == "Key: 'meta_rules', [Empty Container]"
diff --git a/moon_manager/tests/unit_python/api/utilities.py b/moon_manager/tests/unit_python/api/utilities.py
index 66ca30c5..2e51fec8 100644
--- a/moon_manager/tests/unit_python/api/utilities.py
+++ b/moon_manager/tests/unit_python/api/utilities.py
@@ -1,5 +1,5 @@
import json
-
+from uuid import uuid4
def get_json(data):
return json.loads(data.decode("utf-8"))
@@ -13,14 +13,14 @@ def register_client():
def get_policy_id():
- import api.test_policies as policies
- client = register_client()
- policy_id = ''
- req, policy = policies.get_policies(client)
- for id in policy['policies']:
- if id:
- policy_id = id
- break
- if not policy_id:
- policies.add_policies(client, "testuser")
+ from helpers import policy_helper
+ value = {
+ "name": "test_policy"+uuid4().hex,
+ "model_id": "",
+ "genre": "authz",
+ "description": "test",
+ }
+ policy_helper.add_policies(value=value)
+ req = policy_helper.get_policies()
+ policy_id = list(req.keys())[0]
return policy_id
diff --git a/moon_manager/tests/unit_python/conftest.py b/moon_manager/tests/unit_python/conftest.py
index 902a41a2..d9899231 100644
--- a/moon_manager/tests/unit_python/conftest.py
+++ b/moon_manager/tests/unit_python/conftest.py
@@ -187,12 +187,14 @@ def no_requests(monkeypatch):
'DELETE', 'http://keystone:5000/v3/auth/tokens',
headers={'X-Subject-Token': "111111111"}
)
+
+ def match_request_text(request):
+ # request.url may be None, or '' prevents a TypeError.
+ return 'http://keystone:5000/v3/users?name=testuser' in request.url
+
m.register_uri(
- 'POST', 'http://keystone:5000/v3/users?name=testuser&domain_id=default',
- json={"users": {}}
- )
- m.register_uri(
- 'GET', 'http://keystone:5000/v3/users?name=testuser&domain_id=default',
+ requests_mock.ANY, '/v3/users',
+ additional_matcher=match_request_text,
json={"users": {}}
)
m.register_uri(
diff --git a/moon_manager/tests/unit_python/helpers/__init__.py b/moon_manager/tests/unit_python/helpers/__init__.py
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/moon_manager/tests/unit_python/helpers/__init__.py
diff --git a/moon_manager/tests/unit_python/helpers/assignment_helper.py b/moon_manager/tests/unit_python/helpers/assignment_helper.py
new file mode 100644
index 00000000..22a56e38
--- /dev/null
+++ b/moon_manager/tests/unit_python/helpers/assignment_helper.py
@@ -0,0 +1,49 @@
+# 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'.
+
+def get_action_assignments(policy_id, action_id=None, category_id=None):
+ from python_moondb.core import PolicyManager
+ return PolicyManager.get_action_assignments("", policy_id, action_id, category_id)
+
+
+def add_action_assignment(policy_id, action_id, category_id, data_id):
+ from python_moondb.core import PolicyManager
+ return PolicyManager.add_action_assignment("", policy_id, action_id, category_id, data_id)
+
+
+def delete_action_assignment(policy_id, action_id, category_id, data_id):
+ from python_moondb.core import PolicyManager
+ PolicyManager.delete_action_assignment("", policy_id, action_id, category_id, data_id)
+
+
+def get_object_assignments(policy_id, object_id=None, category_id=None):
+ from python_moondb.core import PolicyManager
+ return PolicyManager.get_object_assignments("", policy_id, object_id, category_id)
+
+
+def add_object_assignment(policy_id, object_id, category_id, data_id):
+ from python_moondb.core import PolicyManager
+ return PolicyManager.add_object_assignment("", policy_id, object_id, category_id, data_id)
+
+
+def delete_object_assignment(policy_id, object_id, category_id, data_id):
+ from python_moondb.core import PolicyManager
+ PolicyManager.delete_object_assignment("", policy_id, object_id, category_id, data_id)
+
+
+def get_subject_assignments(policy_id, subject_id=None, category_id=None):
+ from python_moondb.core import PolicyManager
+ return PolicyManager.get_subject_assignments("", policy_id, subject_id, category_id)
+
+
+def add_subject_assignment(policy_id, subject_id, category_id, data_id):
+ from python_moondb.core import PolicyManager
+ return PolicyManager.add_subject_assignment("", policy_id, subject_id, category_id, data_id)
+
+
+def delete_subject_assignment(policy_id, subject_id, category_id, data_id):
+ from python_moondb.core import PolicyManager
+ PolicyManager.delete_subject_assignment("", policy_id, subject_id, category_id, data_id)
+
diff --git a/moon_manager/tests/unit_python/helpers/category_helper.py b/moon_manager/tests/unit_python/helpers/category_helper.py
new file mode 100644
index 00000000..6c419ca8
--- /dev/null
+++ b/moon_manager/tests/unit_python/helpers/category_helper.py
@@ -0,0 +1,40 @@
+# 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'.
+
+
+def add_subject_category(cat_id=None, value=None):
+ from python_moondb.core import ModelManager
+ category = ModelManager.add_subject_category(user_id=None, category_id=cat_id, value=value)
+ return category
+
+
+def get_subject_category(cat_id=None):
+ from python_moondb.core import ModelManager
+ category = ModelManager.get_subject_categories(user_id=None, category_id=cat_id)
+ return category
+
+
+def add_object_category(cat_id=None, value=None):
+ from python_moondb.core import ModelManager
+ category = ModelManager.add_object_category(user_id=None, category_id=cat_id, value=value)
+ return category
+
+
+def get_object_category(cat_id=None):
+ from python_moondb.core import ModelManager
+ category = ModelManager.get_object_categories(user_id=None, category_id=cat_id)
+ return category
+
+
+def add_action_category(cat_id=None, value=None):
+ from python_moondb.core import ModelManager
+ category = ModelManager.add_action_category(user_id=None, category_id=cat_id, value=value)
+ return category
+
+
+def get_action_category(cat_id=None):
+ from python_moondb.core import ModelManager
+ category = ModelManager.get_action_categories(user_id=None, category_id=cat_id)
+ return category
diff --git a/moon_manager/tests/unit_python/helpers/data_builder.py b/moon_manager/tests/unit_python/helpers/data_builder.py
new file mode 100644
index 00000000..2a7c5979
--- /dev/null
+++ b/moon_manager/tests/unit_python/helpers/data_builder.py
@@ -0,0 +1,209 @@
+# 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'.
+
+from .category_helper import *
+from .policy_helper import *
+from .data_helper import *
+from helpers import model_helper
+from .meta_rule_helper import *
+import api.utilities as utilities
+import json
+
+
+def create_subject_category(name):
+ subject_category = add_subject_category(
+ value={"name": name + uuid4().hex, "description": "description 1"})
+ return list(subject_category.keys())[0]
+
+
+def create_object_category(name):
+ object_category = add_object_category(
+ value={"name": name + uuid4().hex, "description": "description 1"})
+ return list(object_category.keys())[0]
+
+
+def create_action_category(name):
+ action_category = add_action_category(
+ value={"name": name + uuid4().hex, "description": "description 1"})
+ return list(action_category.keys())[0]
+
+
+def create_model(meta_rule_id, model_name="test_model"):
+ value = {
+ "name": model_name + uuid4().hex,
+ "description": "test",
+ "meta_rules": [meta_rule_id]
+
+ }
+ return value
+
+
+def create_policy(model_id, policy_name="policy_1"):
+ value = {
+ "name": policy_name,
+ "model_id": model_id,
+ "genre": "authz",
+ "description": "test",
+ }
+ return value
+
+
+def create_pdp(policies_ids):
+ value = {
+ "name": "test_pdp",
+ "security_pipeline": policies_ids,
+ "keystone_project_id": "keystone_project_id1",
+ "description": "...",
+ }
+ return value
+
+
+def create_new_policy(subject_category_name="subjectCategory", object_category_name="objectCategory",
+ action_category_name="actionCategory",
+ model_name="test_model" + uuid4().hex, policy_name="policy_1" + uuid4().hex,
+ meta_rule_name="meta_rule1" + uuid4().hex):
+ subject_category_id, object_category_id, action_category_id, meta_rule_id = create_new_meta_rule(
+ subject_category_name=subject_category_name + uuid4().hex,
+ object_category_name=object_category_name + uuid4().hex,
+ action_category_name=action_category_name + uuid4().hex, meta_rule_name=meta_rule_name + uuid4().hex)
+ model = model_helper.add_model(value=create_model(meta_rule_id, model_name))
+ model_id = list(model.keys())[0]
+ value = create_policy(model_id, policy_name)
+ policy = add_policies(value=value)
+ assert policy
+ policy_id = list(policy.keys())[0]
+ return subject_category_id, object_category_id, action_category_id, meta_rule_id, policy_id
+
+
+def create_new_meta_rule(subject_category_name="subjectCategory", object_category_name="objectCategory",
+ action_category_name="actionCategory",
+ meta_rule_name="meta_rule1" + uuid4().hex):
+ subject_category_id = create_subject_category(subject_category_name)
+ object_category_id = create_object_category(object_category_name)
+ action_category_id = create_action_category(action_category_name)
+ value = {"name": meta_rule_name,
+ "algorithm": "name of the meta rule algorithm",
+ "subject_categories": [subject_category_id],
+ "object_categories": [object_category_id],
+ "action_categories": [action_category_id]
+ }
+ meta_rule = add_meta_rule(value=value)
+ return subject_category_id, object_category_id, action_category_id, list(meta_rule.keys())[0]
+
+
+def create_subject(policy_id):
+ value = {
+ "name": "testuser" + uuid4().hex,
+ "description": "test",
+ }
+ subject = add_subject(policy_id=policy_id, value=value)
+ return list(subject.keys())[0]
+
+
+def create_object(policy_id):
+ value = {
+ "name": "testobject" + uuid4().hex,
+ "description": "test",
+ }
+ object = add_object(policy_id=policy_id, value=value)
+ return list(object.keys())[0]
+
+
+def create_action(policy_id):
+ value = {
+ "name": "testaction" + uuid4().hex,
+ "description": "test",
+ }
+ action = add_action(policy_id=policy_id, value=value)
+ return list(action.keys())[0]
+
+
+def create_subject_data(policy_id, category_id):
+ value = {
+ "name": "subject-security-level",
+ "description": {"low": "", "medium": "", "high": ""},
+ }
+ subject_data = add_subject_data(policy_id=policy_id, category_id=category_id, value=value).get('data')
+ assert subject_data
+ return list(subject_data.keys())[0]
+
+
+def create_object_data(policy_id, category_id):
+ value = {
+ "name": "object-security-level",
+ "description": {"low": "", "medium": "", "high": ""},
+ }
+ object_data = add_object_data(policy_id=policy_id, category_id=category_id, value=value).get('data')
+ return list(object_data.keys())[0]
+
+
+def create_action_data(policy_id, category_id):
+ value = {
+ "name": "action-type",
+ "description": {"vm-action": "", "storage-action": "", },
+ }
+ action_data = add_action_data(policy_id=policy_id, category_id=category_id, value=value).get('data')
+ return list(action_data.keys())[0]
+
+
+def get_policy_id_with_subject_assignment():
+ client = utilities.register_client()
+ subject_category_id, object_category_id, action_category_id, meta_rule_id, policy_id = create_new_policy(
+ subject_category_name="subject_category1" + uuid4().hex,
+ object_category_name="object_category1" + uuid4().hex,
+ action_category_name="action_category1" + uuid4().hex,
+ meta_rule_name="meta_rule_1" + uuid4().hex)
+ subject_id = create_subject(policy_id)
+ data_id = create_subject_data(policy_id=policy_id, category_id=subject_category_id)
+
+ data = {
+ "id": subject_id,
+ "category_id": subject_category_id,
+ "data_id": data_id
+ }
+ client.post("/policies/{}/subject_assignments".format(policy_id), data=json.dumps(data),
+ headers={'Content-Type': 'application/json'})
+ return policy_id
+
+
+def get_policy_id_with_object_assignment():
+ client = utilities.register_client()
+ subject_category_id, object_category_id, action_category_id, meta_rule_id, policy_id = create_new_policy(
+ subject_category_name="subject_category1" + uuid4().hex,
+ object_category_name="object_category1" + uuid4().hex,
+ action_category_name="action_category1" + uuid4().hex,
+ meta_rule_name="meta_rule_1" + uuid4().hex)
+ object_id = create_object(policy_id)
+ data_id = create_object_data(policy_id=policy_id, category_id=object_category_id)
+
+ data = {
+ "id": object_id,
+ "category_id": object_category_id,
+ "data_id": data_id
+ }
+
+ client.post("/policies/{}/object_assignments".format(policy_id), data=json.dumps(data),
+ headers={'Content-Type': 'application/json'})
+ return policy_id
+
+
+def get_policy_id_with_action_assignment():
+ client = utilities.register_client()
+ subject_category_id, object_category_id, action_category_id, meta_rule_id, policy_id = create_new_policy(
+ subject_category_name="subject_category1" + uuid4().hex,
+ object_category_name="object_category1" + uuid4().hex,
+ action_category_name="action_category1" + uuid4().hex,
+ meta_rule_name="meta_rule_1" + uuid4().hex)
+ action_id = create_action(policy_id)
+ data_id = create_action_data(policy_id=policy_id, category_id=action_category_id)
+
+ data = {
+ "id": action_id,
+ "category_id": action_category_id,
+ "data_id": data_id
+ }
+ client.post("/policies/{}/action_assignments".format(policy_id), data=json.dumps(data),
+ headers={'Content-Type': 'application/json'})
+ return policy_id
diff --git a/moon_manager/tests/unit_python/helpers/data_helper.py b/moon_manager/tests/unit_python/helpers/data_helper.py
new file mode 100644
index 00000000..da6b9376
--- /dev/null
+++ b/moon_manager/tests/unit_python/helpers/data_helper.py
@@ -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'.
+
+
+def get_action_data(policy_id, data_id=None, category_id=None):
+ from python_moondb.core import PolicyManager
+ return PolicyManager.get_action_data("", policy_id, data_id, category_id)
+
+
+def add_action_data(policy_id, data_id=None, category_id=None, value=None):
+ from python_moondb.core import PolicyManager
+ return PolicyManager.add_action_data("", policy_id, data_id, category_id, value)
+
+
+def delete_action_data(policy_id, data_id):
+ from python_moondb.core import PolicyManager
+ PolicyManager.delete_action_data("", policy_id, data_id)
+
+
+def get_object_data(policy_id, data_id=None, category_id=None):
+ from python_moondb.core import PolicyManager
+ return PolicyManager.get_object_data("", policy_id, data_id, category_id)
+
+
+def add_object_data(policy_id, data_id=None, category_id=None, value=None):
+ from python_moondb.core import PolicyManager
+ return PolicyManager.add_object_data("", policy_id, data_id, category_id, value)
+
+
+def delete_object_data(policy_id, data_id):
+ from python_moondb.core import PolicyManager
+ PolicyManager.delete_object_data("", policy_id, data_id)
+
+
+def get_subject_data(policy_id, data_id=None, category_id=None):
+ from python_moondb.core import PolicyManager
+ return PolicyManager.get_subject_data("", policy_id, data_id, category_id)
+
+
+def add_subject_data(policy_id, data_id=None, category_id=None, value=None):
+ from python_moondb.core import PolicyManager
+ return PolicyManager.set_subject_data("", policy_id, data_id, category_id, value)
+
+
+def delete_subject_data(policy_id, data_id):
+ from python_moondb.core import PolicyManager
+ PolicyManager.delete_subject_data("", policy_id, data_id)
+
+
+def get_actions(policy_id, perimeter_id=None):
+ from python_moondb.core import PolicyManager
+ return PolicyManager.get_actions("", policy_id, perimeter_id)
+
+
+def add_action(policy_id, perimeter_id=None, value=None):
+ from python_moondb.core import PolicyManager
+ return PolicyManager.add_action("", policy_id, perimeter_id, value)
+
+
+def delete_action(policy_id, perimeter_id):
+ from python_moondb.core import PolicyManager
+ PolicyManager.delete_action("", policy_id, perimeter_id)
+
+
+def get_objects(policy_id, perimeter_id=None):
+ from python_moondb.core import PolicyManager
+ return PolicyManager.get_objects("", policy_id, perimeter_id)
+
+
+def add_object(policy_id, perimeter_id=None, value=None):
+ from python_moondb.core import PolicyManager
+ return PolicyManager.add_object("", policy_id, perimeter_id, value)
+
+
+def delete_object(policy_id, perimeter_id):
+ from python_moondb.core import PolicyManager
+ PolicyManager.delete_object("", policy_id, perimeter_id)
+
+
+def get_subjects(policy_id, perimeter_id=None):
+ from python_moondb.core import PolicyManager
+ return PolicyManager.get_subjects("", policy_id, perimeter_id)
+
+
+def add_subject(policy_id, perimeter_id=None, value=None):
+ from python_moondb.core import PolicyManager
+ return PolicyManager.add_subject("", policy_id, perimeter_id, value)
+
+
+def delete_subject(policy_id, perimeter_id):
+ from python_moondb.core import PolicyManager
+ PolicyManager.delete_subject("", policy_id, perimeter_id)
+
+
+def get_available_metadata(policy_id):
+ from python_moondb.core import PolicyManager
+ return PolicyManager.get_available_metadata("", policy_id)
diff --git a/moon_manager/tests/unit_python/helpers/meta_rule_helper.py b/moon_manager/tests/unit_python/helpers/meta_rule_helper.py
new file mode 100644
index 00000000..e882706b
--- /dev/null
+++ b/moon_manager/tests/unit_python/helpers/meta_rule_helper.py
@@ -0,0 +1,49 @@
+# 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'.
+
+from helpers import data_builder as builder
+from uuid import uuid4
+
+
+def set_meta_rule(meta_rule_id, value=None):
+ from python_moondb.core import ModelManager
+ if not value:
+ action_category_id = builder.create_action_category("action_category_id1"+uuid4().hex)
+ subject_category_id = builder.create_subject_category("subject_category_id1"+uuid4().hex)
+ object_category_id = builder.create_object_category("object_category_id1"+uuid4().hex)
+ value = {
+ "name": "MLS_meta_rule",
+ "description": "test",
+ "subject_categories": [subject_category_id],
+ "object_categories": [object_category_id],
+ "action_categories": [action_category_id]
+ }
+ return ModelManager.set_meta_rule(user_id=None, meta_rule_id=meta_rule_id, value=value)
+
+
+def add_meta_rule(meta_rule_id=None, value=None):
+ from python_moondb.core import ModelManager
+ if not value:
+ action_category_id = builder.create_action_category("action_category_id1"+uuid4().hex)
+ subject_category_id = builder.create_subject_category("subject_category_id1"+uuid4().hex)
+ object_category_id = builder.create_object_category("object_category_id1"+uuid4().hex)
+ value = {
+ "name": "MLS_meta_rule"+uuid4().hex,
+ "description": "test",
+ "subject_categories": [subject_category_id],
+ "object_categories": [object_category_id],
+ "action_categories": [action_category_id]
+ }
+ return ModelManager.add_meta_rule(user_id=None, meta_rule_id=meta_rule_id, value=value)
+
+
+def get_meta_rules(meta_rule_id=None):
+ from python_moondb.core import ModelManager
+ return ModelManager.get_meta_rules(user_id=None, meta_rule_id=meta_rule_id)
+
+
+def delete_meta_rules(meta_rule_id=None):
+ from python_moondb.core import ModelManager
+ ModelManager.delete_meta_rule(user_id=None, meta_rule_id=meta_rule_id)
diff --git a/moon_manager/tests/unit_python/helpers/model_helper.py b/moon_manager/tests/unit_python/helpers/model_helper.py
new file mode 100644
index 00000000..d2ffb85b
--- /dev/null
+++ b/moon_manager/tests/unit_python/helpers/model_helper.py
@@ -0,0 +1,51 @@
+# 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'.
+
+from helpers import data_builder as builder
+from uuid import uuid4
+
+
+def get_models(model_id=None):
+ from python_moondb.core import ModelManager
+ return ModelManager.get_models(user_id=None, model_id=model_id)
+
+
+def add_model(model_id=None, value=None):
+ from python_moondb.core import ModelManager
+ if not value:
+ subject_category_id, object_category_id, action_category_id, meta_rule_id = builder.create_new_meta_rule(
+ subject_category_name="subject_category1"+uuid4().hex,
+ object_category_name="object_category1"+uuid4().hex,
+ action_category_name="action_category1"+uuid4().hex)
+ name = "MLS" if model_id is None else "MLS " + model_id
+ value = {
+ "name": name,
+ "description": "test",
+ "meta_rules": [meta_rule_id]
+ }
+ return ModelManager.add_model(user_id=None, model_id=model_id, value=value)
+
+
+def delete_models(uuid=None, name=None):
+ from python_moondb.core import ModelManager
+ if not uuid:
+ for model_id, model_value in get_models():
+ if name == model_value['name']:
+ uuid = model_id
+ break
+ ModelManager.delete_model(user_id=None, model_id=uuid)
+
+
+def delete_all_models():
+ from python_moondb.core import ModelManager
+ models_values = get_models()
+ print(models_values)
+ for model_id, model_value in models_values.items():
+ ModelManager.delete_model(user_id=None, model_id=model_id)
+
+
+def update_model(model_id=None, value=None):
+ from python_moondb.core import ModelManager
+ return ModelManager.update_model(user_id=None, model_id=model_id, value=value)
diff --git a/moon_manager/tests/unit_python/helpers/pdp_helper.py b/moon_manager/tests/unit_python/helpers/pdp_helper.py
new file mode 100644
index 00000000..3d169b06
--- /dev/null
+++ b/moon_manager/tests/unit_python/helpers/pdp_helper.py
@@ -0,0 +1,23 @@
+# 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'.
+
+def update_pdp(pdp_id, value):
+ from python_moondb.core import PDPManager
+ return PDPManager.update_pdp("", pdp_id, value)
+
+
+def delete_pdp(pdp_id):
+ from python_moondb.core import PDPManager
+ PDPManager.delete_pdp("", pdp_id)
+
+
+def add_pdp(pdp_id=None, value=None):
+ from python_moondb.core import PDPManager
+ return PDPManager.add_pdp("", pdp_id, value)
+
+
+def get_pdp(pdp_id=None):
+ from python_moondb.core import PDPManager
+ return PDPManager.get_pdp("", pdp_id)
diff --git a/moon_manager/tests/unit_python/helpers/policy_helper.py b/moon_manager/tests/unit_python/helpers/policy_helper.py
new file mode 100644
index 00000000..c932ee3a
--- /dev/null
+++ b/moon_manager/tests/unit_python/helpers/policy_helper.py
@@ -0,0 +1,61 @@
+# 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'.
+
+def get_policies():
+ from python_moondb.core import PolicyManager
+ return PolicyManager.get_policies("admin")
+
+
+def add_policies(policy_id=None, value=None):
+ from python_moondb.core import PolicyManager
+ if not value:
+ value = {
+ "name": "test_policy",
+ "model_id": "",
+ "genre": "authz",
+ "description": "test",
+ }
+ return PolicyManager.add_policy("admin", policy_id=policy_id, value=value)
+
+
+def delete_policies(uuid=None, name=None):
+ from python_moondb.core import PolicyManager
+ if not uuid:
+ for policy_id, policy_value in get_policies():
+ if name == policy_value['name']:
+ uuid = policy_id
+ break
+ PolicyManager.delete_policy("admin", uuid)
+
+
+def update_policy(policy_id, value):
+ from python_moondb.core import PolicyManager
+ return PolicyManager.update_policy("admin", policy_id, value)
+
+
+def get_policy_from_meta_rules(meta_rule_id):
+ from python_moondb.core import PolicyManager
+ return PolicyManager.get_policy_from_meta_rules("admin", meta_rule_id)
+
+
+def get_rules(policy_id=None, meta_rule_id=None, rule_id=None):
+ from python_moondb.core import PolicyManager
+ return PolicyManager.get_rules("", policy_id, meta_rule_id, rule_id)
+
+
+def add_rule(policy_id=None, meta_rule_id=None, value=None):
+ from python_moondb.core import PolicyManager
+ if not value:
+ value = {
+ "rule": ("high", "medium", "vm-action"),
+ "instructions": ({"decision": "grant"}),
+ "enabled": "",
+ }
+ return PolicyManager.add_rule("", policy_id, meta_rule_id, value)
+
+
+def delete_rule(policy_id=None, rule_id=None):
+ from python_moondb.core import PolicyManager
+ PolicyManager.delete_rule("", policy_id, rule_id)
diff --git a/moon_manager/tests/unit_python/requirements.txt b/moon_manager/tests/unit_python/requirements.txt
index 21975ce3..6c6e5bb8 100644
--- a/moon_manager/tests/unit_python/requirements.txt
+++ b/moon_manager/tests/unit_python/requirements.txt
@@ -2,4 +2,4 @@ flask
flask_cors
flask_restful
python_moondb
-python_moonutilities \ No newline at end of file
+python_moonutilities
diff --git a/moon_orchestrator/Changelog b/moon_orchestrator/Changelog
index 31aabf5d..783c9130 100644
--- a/moon_orchestrator/Changelog
+++ b/moon_orchestrator/Changelog
@@ -23,3 +23,7 @@ CHANGES
-----
- add bootstrap file to start Orchestrator with all configuration
+4.4.1
+-----
+- the processing of a request is now performed in a thread
+
diff --git a/moon_orchestrator/Dockerfile b/moon_orchestrator/Dockerfile
index e9f83094..09d12fda 100644
--- a/moon_orchestrator/Dockerfile
+++ b/moon_orchestrator/Dockerfile
@@ -1,8 +1,15 @@
FROM python:3
+LABEL Name=Orchestrator
+LABEL Description="Orchestrator component for the Moon platform"
+LABEL Maintainer="Thomas Duval"
+LABEL Url="https://wiki.opnfv.org/display/moon/Moon+Project+Proposal"
+
+USER root
+
ADD . /root
WORKDIR /root/
-RUN pip3 install -r requirements.txt
-RUN pip3 install .
+RUN pip3 install --no-cache-dir -r requirements.txt
+RUN pip3 install --no-cache-dir .
CMD ["python3", "-m", "moon_orchestrator"] \ No newline at end of file
diff --git a/moon_orchestrator/moon_orchestrator/__init__.py b/moon_orchestrator/moon_orchestrator/__init__.py
index 85c245e0..bc8f2781 100644
--- a/moon_orchestrator/moon_orchestrator/__init__.py
+++ b/moon_orchestrator/moon_orchestrator/__init__.py
@@ -3,4 +3,4 @@
# license which can be found in the file 'LICENSE' in this package distribution
# or at 'http://www.apache.org/licenses/LICENSE-2.0'.
-__version__ = "4.4.0"
+__version__ = "4.4.1"
diff --git a/moon_orchestrator/moon_orchestrator/api/pods.py b/moon_orchestrator/moon_orchestrator/api/pods.py
index 3a01c3a9..389fa5b0 100644
--- a/moon_orchestrator/moon_orchestrator/api/pods.py
+++ b/moon_orchestrator/moon_orchestrator/api/pods.py
@@ -52,27 +52,29 @@ class Pods(Resource):
for _pod_key, _pod_values in self.driver.get_pods().items():
pods[_pod_key] = []
for _pod_value in _pod_values:
- if _pod_value['namespace'] != "moon":
+ if "namespace" in _pod_value and _pod_value['namespace'] != "moon":
continue
pods[_pod_key].append(_pod_value)
return {"pods": pods}
except Exception as e:
return {"result": False, "message": str(e)}, 500
- def __get_pod_with_keystone_pid(self, keystone_pid):
+ def __validate_pod_with_keystone_pid(self, keystone_pid):
for pod_key, pod_values in self.driver.get_pods().items():
- if pod_values[0]['keystone_project_id'] == keystone_pid:
+ if pod_values and "keystone_project_id" in pod_values[0] \
+ and pod_values[0]['keystone_project_id'] == keystone_pid:
return True
- def __get_wrapper(self, slave_name):
+ def __is_slave_exist(self, slave_name):
for slave in self.driver.get_slaves():
- if slave_name == slave["name"] \
- and slave["configured"]:
+ if "name" in slave and "configured" in slave \
+ and slave_name == slave["name"] and slave["configured"]:
return True
def __get_slave_names(self):
for slave in self.driver.get_slaves():
- yield slave["name"]
+ if "name" in slave :
+ yield slave["name"]
@check_auth
def post(self, uuid=None, user_id=None):
@@ -98,27 +100,24 @@ class Pods(Resource):
}
}
"""
- pods = {}
if "security_pipeline" in request.json:
- if self.__get_pod_with_keystone_pid(request.json.get("keystone_project_id")):
+ if self.__validate_pod_with_keystone_pid(request.json.get("keystone_project_id")):
raise exceptions.PipelineConflict
+ if not request.json.get("pdp_id"):
+ raise exceptions.PdpUnknown
+ if not request.json.get("security_pipeline"):
+ raise exceptions.PolicyUnknown
self.driver.create_pipeline(
request.json.get("keystone_project_id"),
request.json.get("pdp_id"),
request.json.get("security_pipeline"),
manager_data=request.json,
slave_name=request.json.get("slave_name"))
- for _pod_key, _pod_values in self.driver.get_pods().items():
- pods[_pod_key] = []
- for _pod_value in _pod_values:
- if _pod_value['namespace'] != "moon":
- continue
- pods[_pod_key].append(_pod_value)
else:
logger.info("------------------------------------")
logger.info(list(self.__get_slave_names()))
logger.info("------------------------------------")
- if self.__get_wrapper(request.json.get("slave_name")):
+ if self.__is_slave_exist(request.json.get("slave_name")):
raise exceptions.WrapperConflict
if request.json.get("slave_name") not in self.__get_slave_names():
raise exceptions.SlaveNameUnknown
@@ -144,8 +143,11 @@ class Pods(Resource):
return {'result': True}
except exceptions.PipelineUnknown:
for slave in self.driver.get_slaves():
- if uuid in (slave['name'], slave["wrapper_name"]):
- self.driver.delete_wrapper(name=slave["wrapper_name"])
+ if "name" in slave and "wrapper_name" in slave:
+ if uuid in (slave['name'], slave["wrapper_name"]):
+ self.driver.delete_wrapper(name=slave["wrapper_name"])
+ else :
+ raise exceptions.SlaveNameUnknown
except Exception as e:
return {"result": False, "message": str(e)}, 500
diff --git a/moon_orchestrator/moon_orchestrator/drivers.py b/moon_orchestrator/moon_orchestrator/drivers.py
index bb0d0c2c..4519f3aa 100644
--- a/moon_orchestrator/moon_orchestrator/drivers.py
+++ b/moon_orchestrator/moon_orchestrator/drivers.py
@@ -203,13 +203,14 @@ class K8S(Driver):
for key, value in pods.items():
# logger.info("ctx={}".format(active_context))
# logger.info("value={}".format(value))
- if active_context["name"] == value[0].get('slave_name'):
- data = dict(active_context)
- data["wrapper_name"] = value[0]['name']
- data["ip"] = value[0].get("ip", "NC")
- data["port"] = value[0].get("external_port", "NC")
- slaves.append(data)
- break
+ if "name" in active_context and value and "name" in value[0]:
+ if active_context["name"] == value[0].get('slave_name'):
+ data = dict(active_context)
+ data["wrapper_name"] = value[0]['name']
+ data["ip"] = value[0].get("ip", "NC")
+ data["port"] = value[0].get("external_port", "NC")
+ slaves.append(data)
+ break
return slaves
for ctx in contexts:
data = dict(ctx)
@@ -217,12 +218,13 @@ class K8S(Driver):
for key, value in pods.items():
# logger.info("ctx={}".format(ctx))
# logger.info("value={}".format(value))
- if ctx["name"] == value[0].get('slave_name'):
- data["wrapper_name"] = value[0]['name']
- data["ip"] = value[0].get("ip", "NC")
- data["port"] = value[0].get("external_port", "NC")
- data["configured"] = True
- break
+ if "name" in ctx and value and "name" in value[0]:
+ if ctx["name"] == value[0].get('slave_name'):
+ data["wrapper_name"] = value[0]['name']
+ data["ip"] = value[0].get("ip", "NC")
+ data["port"] = value[0].get("external_port", "NC")
+ data["configured"] = True
+ break
slaves.append(data)
return slaves
diff --git a/moon_orchestrator/moon_orchestrator/http_server.py b/moon_orchestrator/moon_orchestrator/http_server.py
index 85e29cd0..1cb12618 100644
--- a/moon_orchestrator/moon_orchestrator/http_server.py
+++ b/moon_orchestrator/moon_orchestrator/http_server.py
@@ -158,7 +158,7 @@ class HTTPServer(Server):
})
def run(self):
- self.app.run(host=self._host, port=self._port) # nosec
+ self.app.run(host=self._host, port=self._port, threaded=True) # nosec
@staticmethod
def __filter_str(data):
diff --git a/moon_orchestrator/tests/unit_python/mock_pods.py b/moon_orchestrator/tests/unit_python/mock_pods.py
index 84e6c7ea..59e1b3c0 100644
--- a/moon_orchestrator/tests/unit_python/mock_pods.py
+++ b/moon_orchestrator/tests/unit_python/mock_pods.py
@@ -208,12 +208,25 @@ def patch_k8s(monkeypatch):
'create_namespaced_deployment',
create_namespaced_deployment_mockreturn)
+ def delete_namespaced_deployment_mockreturn(*args, **kwargs):
+ return None
+
+ monkeypatch.setattr(client.ExtensionsV1beta1Api,
+ 'delete_namespaced_deployment',
+ delete_namespaced_deployment_mockreturn)
+
def create_namespaced_service_mockreturn(*args, **kwargs):
return {}
monkeypatch.setattr(client.CoreV1Api,
'create_namespaced_service',
create_namespaced_service_mockreturn)
+ def delete_namespaced_service_mockreturn(*args, **kwargs):
+ return {}
+ monkeypatch.setattr(client.CoreV1Api,
+ 'delete_namespaced_service',
+ delete_namespaced_service_mockreturn)
+
def register_pods(m):
""" Modify the response from Requests module
diff --git a/moon_orchestrator/tests/unit_python/test_pods.py b/moon_orchestrator/tests/unit_python/test_pods.py
index 678645be..5e1b3767 100644
--- a/moon_orchestrator/tests/unit_python/test_pods.py
+++ b/moon_orchestrator/tests/unit_python/test_pods.py
@@ -15,6 +15,7 @@ def test_get_pods(context, monkeypatch):
data = get_json(req.data)
assert isinstance(data, dict)
assert "pods" in data
+ assert data["pods"]
def test_get_pods_failure(context, monkeypatch):
@@ -30,6 +31,7 @@ def test_get_pods_failure(context, monkeypatch):
assert isinstance(data, dict)
assert not data["pods"]
+############################ /post ############################
def test_add_pods_with_pipeline(context, monkeypatch):
patch_k8s(monkeypatch)
@@ -52,7 +54,7 @@ def test_add_pods_with_pipeline(context, monkeypatch):
assert data["pods"]
-def test_add_pods_without_pipeline_with_bad_slave_name(context, monkeypatch):
+def test_add_pods_without_pipeline_with_bad_slave_name_failure(context, monkeypatch):
patch_k8s(monkeypatch)
import moon_orchestrator.server
@@ -89,7 +91,7 @@ def test_add_pods_without_pipeline_with_good_slave_name(context, monkeypatch):
assert data["pods"]
-def test_add_pods_without_pipeline_without_slave_name(context, monkeypatch):
+def test_add_pods_without_pipeline_without_slave_name_failure(context, monkeypatch):
patch_k8s(monkeypatch)
import moon_orchestrator.server
@@ -106,7 +108,7 @@ def test_add_pods_without_pipeline_without_slave_name(context, monkeypatch):
assert 'The slave is unknown.' in data['message']
-def test_add_pods_with_no_data(context, monkeypatch):
+def test_add_pods_with_no_data_failure(context, monkeypatch):
patch_k8s(monkeypatch)
import moon_orchestrator.server
server = moon_orchestrator.server.create_server()
@@ -140,6 +142,146 @@ def test_add_pods_with_no_policies_no_models(context, monkeypatch, no_requests):
assert req.status_code == 200
-def test_delete_pods(context, monkeypatch):
- # TODO
- pass
+def test_add_pods_with_empty_pdp_id_and_keystone_project_id_failure(context, monkeypatch):
+ patch_k8s(monkeypatch)
+
+ import moon_orchestrator.server
+ server = moon_orchestrator.server.create_server()
+ _client = server.app.test_client()
+ data = {
+ "keystone_project_id": "",
+ "pdp_id": "",
+ "security_pipeline": context.get('security_pipeline'),
+ }
+ req = _client.post("/pods", data=json.dumps(data),
+ headers={'Content-Type': 'application/json'})
+ assert req.status_code == 400
+ assert req.data
+ data = get_json(req.data)
+ assert "The pdp is unknown." in data['message']
+
+
+def test_add_pods_with_empty_security_pipeline_failure(context, monkeypatch):
+ patch_k8s(monkeypatch)
+
+ import moon_orchestrator.server
+ server = moon_orchestrator.server.create_server()
+ _client = server.app.test_client()
+ data = {
+ "keystone_project_id": context.get('project_id'),
+ "pdp_id": context.get('pdp_id'),
+ "security_pipeline": "",
+ }
+ req = _client.post("/pods", data=json.dumps(data),
+ headers={'Content-Type': 'application/json'})
+ assert req.status_code == 400
+ assert req.data
+ data = get_json(req.data)
+ assert 'The policy is unknown.' in data['message']
+
+
+def test_add_different_pods_with_same_pdp_id(context, monkeypatch):
+ patch_k8s(monkeypatch)
+
+ import moon_orchestrator.server
+ server = moon_orchestrator.server.create_server()
+ _client = server.app.test_client()
+ data = {
+ "keystone_project_id": context.get('project_id'),
+ "pdp_id": context.get('pdp_id'),
+ "security_pipeline": context.get('security_pipeline'),
+ }
+ req = _client.post("/pods", data=json.dumps(data),
+ headers={'Content-Type': 'application/json'})
+ data["keystone_project_id"] = data["keystone_project_id"] + "x"
+ req = _client.post("/pods", data=json.dumps(data),
+ headers={'Content-Type': 'application/json'})
+ assert req.status_code == 200
+
+
+def test_add_different_pods_with_same_keystone_project_id_failure(context, monkeypatch):
+ patch_k8s(monkeypatch)
+
+ import moon_orchestrator.server
+ server = moon_orchestrator.server.create_server()
+ _client = server.app.test_client()
+ data = {
+ "keystone_project_id": context.get('project_id'),
+ "pdp_id": context.get('pdp_id'),
+ "security_pipeline": context.get('security_pipeline'),
+ }
+ req = _client.post("/pods", data=json.dumps(data),
+ headers={'Content-Type': 'application/json'})
+ data["pdp_id"] = data["pdp_id"] + "xyz"
+ req = _client.post("/pods", data=json.dumps(data),
+ headers={'Content-Type': 'application/json'})
+ assert req.status_code == 409
+ data = get_json(req.data)
+ assert isinstance(data, dict)
+ assert 'A Pipeline already exist for the specified slave.' in data['message']
+
+
+def test_add_pod_with_slave_more_than_once_failure(context, monkeypatch):
+ patch_k8s(monkeypatch)
+
+ import moon_orchestrator.server
+ server = moon_orchestrator.server.create_server()
+ _client = server.app.test_client()
+ data = {
+ "slave_name": "active_context",
+ }
+ req = _client.post("/pods", data=json.dumps(data),
+ headers={'Content-Type': 'application/json'})
+ req = _client.post("/pods", data=json.dumps(data),
+ headers={'Content-Type': 'application/json'})
+ assert req.status_code == 409
+ assert req.data
+ data = get_json(req.data)
+ assert isinstance(data, dict)
+ assert 'A Wrapper already exist for the specified slave.' in data['message']
+
+############################ /delete ############################
+
+def test_delete_pod_valid_uuid(context, monkeypatch):
+ patch_k8s(monkeypatch)
+
+ import moon_orchestrator.server
+ server = moon_orchestrator.server.create_server()
+ _client = server.app.test_client()
+ data = {
+ "keystone_project_id": context.get('project_id'),
+ "pdp_id": context.get('pdp_id'),
+ "security_pipeline": context.get('security_pipeline'),
+ }
+ req = _client.post("/pods", data=json.dumps(data),
+ headers={'Content-Type': 'application/json'})
+ assert req.status_code == 200
+ assert req.data
+ data = get_json(req.data)
+ for key in data["pods"]:
+ req = _client.delete("/pods/{}".format(key))
+ assert req.status_code == 200
+
+def test_delete_pod_Invalid_uuid_failure(context, monkeypatch):
+ patch_k8s(monkeypatch)
+
+ import moon_orchestrator.server
+ server = moon_orchestrator.server.create_server()
+ _client = server.app.test_client()
+
+ req = _client.delete("/pods/invalid")
+ assert req.status_code == 400
+ data = get_json(req.data)
+ assert 'The slave is unknown.' in data['message']
+
+def test_delete_pod_without_uuid_failure(context, monkeypatch):
+ patch_k8s(monkeypatch)
+
+ import moon_orchestrator.server
+ server = moon_orchestrator.server.create_server()
+ _client = server.app.test_client()
+
+ req = _client.delete("/pods/")
+ assert req.status_code == 400
+ data = get_json(req.data)
+ assert 'The slave is unknown.' in data['message'] \ No newline at end of file
diff --git a/moon_pythonfunctest/Dockerfile b/moon_pythonfunctest/Dockerfile
new file mode 100644
index 00000000..8ae093b8
--- /dev/null
+++ b/moon_pythonfunctest/Dockerfile
@@ -0,0 +1,9 @@
+FROM python:3
+
+WORKDIR /usr/src/app
+RUN pip install --no-cache-dir --upgrade requests pytest pyyaml python_moonutilities python_moondb python_moonclient
+
+ADD . /root
+WORKDIR /root
+
+CMD /bin/bash /root/run_func_test.sh
diff --git a/moon_pythonfunctest/README.md b/moon_pythonfunctest/README.md
new file mode 100644
index 00000000..e2a4d14b
--- /dev/null
+++ b/moon_pythonfunctest/README.md
@@ -0,0 +1,8 @@
+# Python Functional Test Docker
+
+## Build
+- `docker image build -t wukongsun/moon_python_func_test .`
+
+## Push to DockerHub
+- `docker login --username=wukongsun`
+- `docker image push wukongsun/moon_python_func_test`
diff --git a/moon_pythonfunctest/run_func_test.sh b/moon_pythonfunctest/run_func_test.sh
new file mode 100755
index 00000000..acd0e1e9
--- /dev/null
+++ b/moon_pythonfunctest/run_func_test.sh
@@ -0,0 +1,15 @@
+#!/usr/bin/env bash
+
+echo "Running functional tests :"
+
+#ls -l /data
+ls -l /data/tests
+
+if [ -f /data/tests/functional_pod/run_functional_tests.sh ];
+then
+ echo "running script..."
+ bash /data/tests/functional_pod/run_functional_tests.sh;
+fi
+
+echo "<END OF JOB>"
+
diff --git a/moon_pythonunittest/requirements.txt b/moon_pythonunittest/requirements.txt
index b611b008..fe107293 100644
--- a/moon_pythonunittest/requirements.txt
+++ b/moon_pythonunittest/requirements.txt
@@ -7,4 +7,5 @@ werkzeug
flask
requests
pytest
-requests_mock \ No newline at end of file
+pytest-cov
+requests_mock
diff --git a/moon_pythonunittest/run_tests.sh b/moon_pythonunittest/run_tests.sh
index 6c586f87..285bd856 100644
--- a/moon_pythonunittest/run_tests.sh
+++ b/moon_pythonunittest/run_tests.sh
@@ -4,10 +4,16 @@ cd /data
pip3 install -r tests/unit_python/requirements.txt --upgrade
pip3 install .
+if [ -d /data/dist ];
+then
+ pip install /data/dist/*.tar.gz --upgrade
+ pip install /data/dist/*.whl --upgrade
+fi
+
if [ -f /data/tests/unit_python/run_tests.sh ];
then
bash /data/tests/unit_python/run_tests.sh;
fi
cd /data/tests/unit_python
-pytest .
+pytest --cov --cov-report term --cov-report html --cov-report xml .
diff --git a/moon_wrapper/Changelog b/moon_wrapper/Changelog
new file mode 100644
index 00000000..071e4ef9
--- /dev/null
+++ b/moon_wrapper/Changelog
@@ -0,0 +1,28 @@
+# Copyright 2018 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
+=======
+
+1.0.0
+-----
+- First version of the manager
+
+2.0.0
+-----
+- Version built inside the Keystone component
+
+3.0.0
+-----
+- Version built outside the Keystone component
+
+4.0.0
+-----
+- First micro-architecture version
+
+4.5.1
+-----
+- use the threading capability of Flask app
diff --git a/moon_wrapper/Dockerfile b/moon_wrapper/Dockerfile
index 77ffaee9..e3ad9020 100644
--- a/moon_wrapper/Dockerfile
+++ b/moon_wrapper/Dockerfile
@@ -1,8 +1,15 @@
FROM python:3
+LABEL Name=Wrapper
+LABEL Description="Wrapper component for the Moon platform"
+LABEL Maintainer="Thomas Duval"
+LABEL Url="https://wiki.opnfv.org/display/moon/Moon+Project+Proposal"
+
+USER root
+
ADD . /root
WORKDIR /root/
-RUN pip3 install -r requirements.txt
-RUN pip3 install .
+RUN pip3 install --no-cache-dir -r requirements.txt
+RUN pip3 install --no-cache-dir .
CMD ["python3", "-m", "moon_wrapper"]
diff --git a/moon_wrapper/moon_wrapper/__init__.py b/moon_wrapper/moon_wrapper/__init__.py
index 903c6518..98a98146 100644
--- a/moon_wrapper/moon_wrapper/__init__.py
+++ b/moon_wrapper/moon_wrapper/__init__.py
@@ -3,4 +3,4 @@
# license which can be found in the file 'LICENSE' in this package distribution
# or at 'http://www.apache.org/licenses/LICENSE-2.0'.
-__version__ = "0.1.0"
+__version__ = "4.5.1"
diff --git a/moon_wrapper/moon_wrapper/api/oslowrapper.py b/moon_wrapper/moon_wrapper/api/oslowrapper.py
index ad9e430a..905c32db 100644
--- a/moon_wrapper/moon_wrapper/api/oslowrapper.py
+++ b/moon_wrapper/moon_wrapper/api/oslowrapper.py
@@ -37,8 +37,14 @@ class OsloWrapper(Resource):
def post(self):
logger.debug("POST {}".format(request.form))
response = flask.make_response("False")
- if self.manage_data():
- response = flask.make_response("True")
+ try:
+ if self.manage_data():
+ response = flask.make_response("True")
+ except exceptions.AuthzException as e:
+ logger.error(e, exc_info=True)
+ except Exception as e:
+ logger.error(e, exc_info=True)
+
response.headers['content-type'] = 'application/octet-stream'
return response
@@ -109,10 +115,10 @@ class OsloWrapper(Resource):
_object,
_action
))
- '''
- [Note] i think here if status != 200, should raise an exception
- '''
+
logger.debug("Get interface {}".format(req.text))
if req.status_code == 200:
if req.json().get("result", False):
return True
+
+ raise exceptions.AuthzException("error in authz request") \ No newline at end of file
diff --git a/moon_wrapper/moon_wrapper/http_server.py b/moon_wrapper/moon_wrapper/http_server.py
index 8027a0d3..dfbaed9f 100644
--- a/moon_wrapper/moon_wrapper/http_server.py
+++ b/moon_wrapper/moon_wrapper/http_server.py
@@ -3,6 +3,7 @@
# license which can be found in the file 'LICENSE' in this package distribution
# or at 'http://www.apache.org/licenses/LICENSE-2.0'.
+import flask
from flask import Flask, jsonify
from flask_restful import Resource, Api
import logging
@@ -112,13 +113,13 @@ class HTTPServer(Server):
def __hook_errors(self):
def get_404_json(e):
- return jsonify({"result": False, "code": 404,
- "description": str(e)}), 404
+ return flask.make_response("False")
+
self.app.register_error_handler(404, get_404_json)
def get_400_json(e):
- return jsonify({"result": False, "code": 400,
- "description": str(e)}), 400
+ return flask.make_response("False")
+
self.app.register_error_handler(400, lambda e: get_400_json)
self.app.register_error_handler(403, exceptions.AuthException)
@@ -135,5 +136,5 @@ class HTTPServer(Server):
)
def run(self):
- self.app.run(host=self._host, port=self._port) # nosec
+ self.app.run(host=self._host, port=self._port, threaded=True) # nosec
diff --git a/moon_wrapper/tests/unit_python/api/test_wrapper.py b/moon_wrapper/tests/unit_python/api/test_wrapper.py
index be3e8576..bd6baf32 100644
--- a/moon_wrapper/tests/unit_python/api/test_wrapper.py
+++ b/moon_wrapper/tests/unit_python/api/test_wrapper.py
@@ -68,4 +68,5 @@ def test_authz_error_no_interface_key(context):
'target': json.dumps(_target),
'credentials': 'null'}
req = client.post("/authz/oslo", data=json.dumps(authz_data))
- assert req.status_code == 403 \ No newline at end of file
+
+ assert req.data == b"False" \ No newline at end of file
diff --git a/moon_wrapper/tests/unit_python/conftest.py b/moon_wrapper/tests/unit_python/conftest.py
index 621c2014..2c332c89 100644
--- a/moon_wrapper/tests/unit_python/conftest.py
+++ b/moon_wrapper/tests/unit_python/conftest.py
@@ -415,7 +415,7 @@ def set_consul_and_db(monkeypatch):
"name": "testuser",
"email": "mail",
"id": "89ba91c18dd54abfbfde7a66936c51a6",
- "partner_id": ""
+ "extra": {}
},
"31fd15ad14784a9696fcc887dddbfaf9": {
"description": "test",
@@ -426,7 +426,7 @@ def set_consul_and_db(monkeypatch):
"name": "adminuser",
"email": "mail",
"id": "31fd15ad14784a9696fcc887dddbfaf9",
- "partner_id": ""
+ "extra": {}
}
}
}
@@ -439,7 +439,7 @@ def set_consul_and_db(monkeypatch):
"name": "vm1",
"description": "test",
"id": "67b8008a3f8d4f8e847eb628f0f7ca0e",
- "partner_id": "",
+ "extra": {},
"policy_list": [
"f8f49a779ceb47b3ac810f01ef71b4e0",
"636cd473324f4c0bbd9102cb5b62a16d"
@@ -449,7 +449,7 @@ def set_consul_and_db(monkeypatch):
"name": "vm0",
"description": "test",
"id": "9089b3d2ce5b4e929ffc7e35b55eba1a",
- "partner_id": "",
+ "extra": {},
"policy_list": [
"f8f49a779ceb47b3ac810f01ef71b4e0",
"636cd473324f4c0bbd9102cb5b62a16d"
@@ -466,7 +466,7 @@ def set_consul_and_db(monkeypatch):
"name": "boot",
"description": "test",
"id": "cdb3df220dc04a6ea3334b994827b068",
- "partner_id": "",
+ "extra": {},
"policy_list": [
"f8f49a779ceb47b3ac810f01ef71b4e0",
"636cd473324f4c0bbd9102cb5b62a16d"
@@ -476,7 +476,7 @@ def set_consul_and_db(monkeypatch):
"name": "stop",
"description": "test",
"id": "cdb3df220dc04a6ea3334b994827b068",
- "partner_id": "",
+ "extra": {},
"policy_list": [
"f8f49a779ceb47b3ac810f01ef71b4e0",
"636cd473324f4c0bbd9102cb5b62a16d"
@@ -486,7 +486,7 @@ def set_consul_and_db(monkeypatch):
"name": "start",
"description": "test",
"id": "9f5112afe9b34a6c894eb87246ccb7aa",
- "partner_id": "",
+ "extra": {},
"policy_list": [
"f8f49a779ceb47b3ac810f01ef71b4e0",
"636cd473324f4c0bbd9102cb5b62a16d"
diff --git a/python_moonclient/Changelog b/python_moonclient/Changelog
index 64ae76ba..9066e449 100644
--- a/python_moonclient/Changelog
+++ b/python_moonclient/Changelog
@@ -1,4 +1,4 @@
-# Copyright 2015 Open Platform for NFV Project, Inc. and its contributors
+# Copyright 2018 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'.
@@ -37,3 +37,38 @@ CHANGES
- moon_get_slaves
- moon_set_slave
- moon_delete_slave
+
+1.3.0
+-----
+- Base the cli on cliff library
+- Commands are:
+ - moon authz send
+ - moon pdp create
+ - moon pdp delete
+ - moon pdp list
+ - moon pdp map
+ - moon policy delete
+ - moon policy list
+ - moon project list
+ - moon slave delete
+ - moon slave list
+ - moon slave set
+
+1.4.0
+-----
+- Add some commands:
+ - moon import
+ - moon export
+ - moon subject category create
+ - moon subject category list
+ - moon object category list
+ - moon action category list
+ - moon subject data create
+ - moon subject data list
+ - moon object data list
+ - moon action data list
+ - moon metarule list
+
+1.4.1
+-----
+- Update exception during configuration
diff --git a/python_moonclient/python_moonclient/__init__.py b/python_moonclient/python_moonclient/__init__.py
index 2c7f8f5c..e3ad9307 100644
--- a/python_moonclient/python_moonclient/__init__.py
+++ b/python_moonclient/python_moonclient/__init__.py
@@ -3,4 +3,4 @@
# license which can be found in the file 'LICENSE' in this package distribution
# or at 'http://www.apache.org/licenses/LICENSE-2.0'.
-__version__ = "1.2.0"
+__version__ = "1.4.1"
diff --git a/python_moonclient/python_moonclient/cli/__init__.py b/python_moonclient/python_moonclient/cli/__init__.py
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/python_moonclient/python_moonclient/cli/__init__.py
diff --git a/python_moonclient/python_moonclient/cli/authz.py b/python_moonclient/python_moonclient/cli/authz.py
new file mode 100644
index 00000000..2f45e847
--- /dev/null
+++ b/python_moonclient/python_moonclient/cli/authz.py
@@ -0,0 +1,53 @@
+import logging
+from cliff.command import Command
+from importlib.machinery import SourceFileLoader
+
+from python_moonclient.core import models, policies, pdp, authz
+from python_moonclient.cli.parser import Parser
+from python_moonclient.cli.projects import ProjectsUtils
+
+logger = logging.getLogger("moonclient.cli.authz")
+
+
+class SendAuthz(Command):
+ """send authorizations to wrapper"""
+
+ def get_parser(self, prog_name):
+ parser = super().get_parser(prog_name)
+ Parser.add_common_options(parser)
+ Parser.add_filename_argument(parser)
+ Parser.add_id_or_name_project_argument(parser)
+ Parser.add_authz_arguments(parser)
+ return parser
+
+ def take_action(self, parsed_args):
+ consul_host = parsed_args.consul_host
+ consul_port = parsed_args.consul_port
+
+ models.init(consul_host, consul_port)
+ policies.init(consul_host, consul_port)
+ pdp.init(consul_host, consul_port)
+
+ if parsed_args.filename:
+ logger.info("Loading: {}".format(parsed_args.filename))
+ m = SourceFileLoader("scenario", parsed_args.filename)
+ scenario = m.load_module()
+
+ keystone_project_id = ProjectsUtils.get_project_id(pdp, parsed_args.id_project, parsed_args.name_project)
+ if keystone_project_id is None:
+ logger.error("Project not found !")
+
+ keystone_project_id = pdp.get_keystone_id(keystone_project_id)
+ time_data = authz.send_requests(
+ scenario,
+ parsed_args.authz_host,
+ parsed_args.authz_port,
+ keystone_project_id,
+ request_second=parsed_args.request_second,
+ limit=parsed_args.limit,
+ dry_run=parsed_args.dry_run,
+ stress_test=parsed_args.stress_test,
+ destination=parsed_args.destination
+ )
+ if not parsed_args.dry_run:
+ authz.save_data(parsed_args.write, time_data) \ No newline at end of file
diff --git a/python_moonclient/python_moonclient/cli/export.py b/python_moonclient/python_moonclient/cli/export.py
new file mode 100644
index 00000000..a16928de
--- /dev/null
+++ b/python_moonclient/python_moonclient/cli/export.py
@@ -0,0 +1,32 @@
+import json
+
+from python_moonclient.core import models, policies, pdp, json_export
+from python_moonclient.cli.parser import Parser
+
+from cliff.command import Command
+
+
+class Export(Command):
+ """dump the complete moon database into a json file"""
+ def get_parser(self, prog_name):
+ parser = super().get_parser(prog_name)
+ Parser.add_filename_argument(parser)
+ Parser.add_common_options(parser)
+ return parser
+
+ def take_action(self, parsed_args):
+ consul_host = parsed_args.consul_host
+ consul_port = parsed_args.consul_port
+
+ models.init(consul_host, consul_port)
+ policies.init(consul_host, consul_port)
+ pdp.init(consul_host, consul_port)
+ json_export.init(consul_host, consul_port)
+ res = json_export.export_to_json()
+ if "content" in res:
+ json_file = open(parsed_args.filename, "w")
+ json.dump(res["content"], json_file)
+ return "Export ok!"
+ else:
+ return "Unexpected results : the returned json does not have the correct syntax"
+
diff --git a/python_moonclient/python_moonclient/cli/import.py b/python_moonclient/python_moonclient/cli/import.py
new file mode 100644
index 00000000..c6c43439
--- /dev/null
+++ b/python_moonclient/python_moonclient/cli/import.py
@@ -0,0 +1,29 @@
+
+from python_moonclient.core import models, policies, pdp, json_import
+from python_moonclient.cli.parser import Parser
+from python_moonclient.cli.projects import ProjectsUtils
+
+from cliff.command import Command
+
+
+class Import(Command):
+ """import a json file describing pdps """
+ def get_parser(self, prog_name):
+ parser = super().get_parser(prog_name)
+ Parser.add_common_options(parser)
+ Parser.add_filename_argument(parser)
+ return parser
+
+ def take_action(self, parsed_args):
+ consul_host = parsed_args.consul_host
+ consul_port = parsed_args.consul_port
+
+ models.init(consul_host, consul_port)
+ policies.init(consul_host, consul_port)
+ pdp.init(consul_host, consul_port)
+ json_import.init(consul_host, consul_port)
+ res = json_import.import_json(parsed_args.filename)
+ if "message" in res:
+ return res["message"]
+ return res
+
diff --git a/python_moonclient/python_moonclient/cli/models.py b/python_moonclient/python_moonclient/cli/models.py
new file mode 100644
index 00000000..922a1830
--- /dev/null
+++ b/python_moonclient/python_moonclient/cli/models.py
@@ -0,0 +1,161 @@
+import logging
+from cliff.lister import Lister
+from cliff.command import Command
+from importlib.machinery import SourceFileLoader
+
+from python_moonclient.core import models, policies, pdp
+from python_moonclient.cli.parser import Parser
+from python_moonclient.cli.projects import ProjectsUtils
+
+logger = logging.getLogger("moonclient.cli.pdps")
+
+
+class ModelUtils:
+ def __init__(self):
+ pass
+
+ @staticmethod
+ def get_model_id(model, parsed_id, parsed_name):
+ modelz = models.check_model()
+ for _model_key, _model_value in modelz["models"].items():
+ if _model_key == parsed_id or _model_value['name'] == parsed_name:
+ # logger.info("Found pdp : [key='{}' , name='{}']".format(_pdp_key, _pdp_value['name']))
+ return _model_key
+ return None
+
+ @staticmethod
+ def get_model_name(pdp, parsed_id, parsed_name):
+ modelz = models.check_model()
+ for _model_key, _model_value in modelz["models"].items():
+ if _model_key == parsed_id or _model_value['name'] == parsed_name:
+ # logger.info("Found pdp : [key='{}' , name='{}']".format(_pdp_key, _pdp_value['name']))
+ return _model_value['name']
+ return None
+
+
+class Models(Lister):
+ """show the list of existing pdps """
+
+ def get_parser(self, prog_name):
+ parser = super().get_parser(prog_name)
+ Parser.add_common_options(parser)
+ return parser
+
+ def take_action(self, parsed_args):
+ consul_host = parsed_args.consul_host
+ consul_port = parsed_args.consul_port
+
+ models.init(consul_host, consul_port)
+ policies.init(consul_host, consul_port)
+ pdp.init(consul_host, consul_port)
+
+ modelz = models.check_model()
+
+ return (('Key', 'Name'),
+ ((_model_key, _model_value['name']) for _model_key, _model_value in
+ modelz["models"].items())
+ )
+
+
+class SubjectCategories(Lister):
+ """show the list of existing categories """
+
+ def get_parser(self, prog_name):
+ parser = super().get_parser(prog_name)
+ Parser.add_common_options(parser)
+
+ return parser
+
+ def take_action(self, parsed_args):
+ consul_host = parsed_args.consul_host
+ consul_port = parsed_args.consul_port
+
+ models.init(consul_host, consul_port)
+ policies.init(consul_host, consul_port)
+ pdp.init(consul_host, consul_port)
+
+ subject_categories = models.check_subject_category()
+ print(subject_categories)
+ return (('Key', 'Name'),
+ ((_model_key, _model_value['name']) for _model_key, _model_value in
+ subject_categories["subject_categories"].items())
+ )
+
+
+class ObjectCategories(Lister):
+ """show the list of existing categories """
+
+ def get_parser(self, prog_name):
+ parser = super().get_parser(prog_name)
+ Parser.add_common_options(parser)
+
+ return parser
+
+ def take_action(self, parsed_args):
+ consul_host = parsed_args.consul_host
+ consul_port = parsed_args.consul_port
+
+ models.init(consul_host, consul_port)
+ policies.init(consul_host, consul_port)
+ pdp.init(consul_host, consul_port)
+
+ object_categories = models.check_object_category()
+ print(object_categories)
+ return (('Key', 'Name'),
+ ((_model_key, _model_value['name']) for _model_key, _model_value in
+ object_categories["object_categories"].items())
+ )
+
+
+class ActionCategories(Lister):
+ """show the list of existing categories """
+
+ def get_parser(self, prog_name):
+ parser = super().get_parser(prog_name)
+ Parser.add_common_options(parser)
+
+ return parser
+
+ def take_action(self, parsed_args):
+ consul_host = parsed_args.consul_host
+ consul_port = parsed_args.consul_port
+
+ models.init(consul_host, consul_port)
+ policies.init(consul_host, consul_port)
+ pdp.init(consul_host, consul_port)
+
+ action_categories = models.check_action_category()
+ print(action_categories)
+ return (('Key', 'Name'),
+ ((_model_key, _model_value['name']) for _model_key, _model_value in
+ action_categories["action_categories"].items())
+ )
+
+
+class SubjectCategoryAdd(Command):
+ """show the list of existing categories """
+
+ def get_parser(self, prog_name):
+ parser = super().get_parser(prog_name)
+ Parser.add_common_options(parser)
+ Parser.add_name_argument(parser)
+
+ return parser
+
+ def take_action(self, parsed_args):
+ consul_host = parsed_args.consul_host
+ consul_port = parsed_args.consul_port
+
+ models.init(consul_host, consul_port)
+ policies.init(consul_host, consul_port)
+ pdp.init(consul_host, consul_port)
+
+ subject_category_id = models.add_subject_category(parsed_args.name)
+ if subject_category_id is not None:
+ print("Subject category created with id {}".format(subject_category_id))
+ else:
+ print("Error while creating subject category")
+ # subject_categories = models.check_subject_category(subject_category_id)
+
+
+
diff --git a/python_moonclient/python_moonclient/cli/parser.py b/python_moonclient/python_moonclient/cli/parser.py
new file mode 100644
index 00000000..edd18a25
--- /dev/null
+++ b/python_moonclient/python_moonclient/cli/parser.py
@@ -0,0 +1,95 @@
+
+class Parser:
+
+ @staticmethod
+ def add_common_options(parser):
+ parser.add_argument('--consul-host', help='Set the name of the consul server (default: 127.0.0.1)', default="127.0.0.1")
+ parser.add_argument('--consul-port', help='Set the port of the consult server (default: 30005)',default="30005")
+ parser.add_argument("--verbose", "-v", action='store_true', help="verbose mode")
+ parser.add_argument("--debug", "-d", action='store_true', help="debug mode")
+
+ @staticmethod
+ def add_filename_argument(parser):
+ parser.add_argument('filename', help='configuration filename in json format')
+
+ @staticmethod
+ def add_name_argument(parser):
+ Parser._add_name_argument(parser)
+
+ @staticmethod
+ def add_policy_argument(parser):
+ group = parser.add_mutually_exclusive_group(required=True)
+ group.add_argument('--policy-name', help='name of the policy')
+ group.add_argument('--policy-id', help='id of the policy')
+
+ @staticmethod
+ def add_category_argument(parser):
+ group = parser.add_mutually_exclusive_group(required=True)
+ group.add_argument('--category-name', help='name of the category')
+ group.add_argument('--category-id', help='id of the category')
+
+ @staticmethod
+ def add_id_or_name_argument(parser):
+ group = parser.add_mutually_exclusive_group(required=True)
+ Parser._add_id_argument(group)
+ Parser._add_name_argument(group)
+
+ @staticmethod
+ def _add_id_argument(parser):
+ parser.add_argument('--id', help='id of the element')
+
+ @staticmethod
+ def _add_name_argument(parser):
+ parser.add_argument('--name', help='name of the element')
+
+ @staticmethod
+ def add_id_or_name_pdp_argument(parser):
+ group = parser.add_mutually_exclusive_group(required=True)
+ Parser._add_id_pdp_argument(group)
+ Parser._add_name_pdp_argument(group)
+
+ @staticmethod
+ def _add_id_pdp_argument(parser):
+ parser.add_argument('--id-pdp', help='id of the pdp')
+
+ @staticmethod
+ def _add_name_pdp_argument(parser):
+ parser.add_argument('--name-pdp', help='name of the pdp')
+
+ @staticmethod
+ def add_id_or_name_project_argument(parser):
+ group = parser.add_mutually_exclusive_group(required=True)
+ Parser._add_id_project_argument(group)
+ Parser._add_name_project_argument(group)
+
+ @staticmethod
+ def _add_id_project_argument(parser):
+ parser.add_argument('--id-project', help='id of the project')
+
+ @staticmethod
+ def _add_name_project_argument(parser):
+ parser.add_argument('--name-project', help='name of the project')
+
+ @staticmethod
+ def add_authz_arguments(parser):
+ parser.add_argument("--dry-run", "-n", action='store_true',
+ help="Dry run", dest="dry_run")
+ parser.add_argument("--destination",
+ help="Set the type of output needed "
+ "(default: wrapper, other possible type: "
+ "interface).",
+ default="wrapper")
+ parser.add_argument("--authz-host",
+ help="Set the name of the authz server to test"
+ "(default: 127.0.0.1).",
+ default="127.0.0.1")
+ parser.add_argument("--authz-port",
+ help="Set the port of the authz server to test"
+ "(default: 31002).",
+ default="31002")
+ parser.add_argument("--stress-test", "-s", action='store_true',
+ dest='stress_test',
+ help="Execute stressing tests (warning delta measures "
+ "will be false, implies -t)")
+ parser.add_argument("--write", "-w", help="Write test data to a JSON file",
+ default="/tmp/data.json")
diff --git a/python_moonclient/python_moonclient/cli/pdps.py b/python_moonclient/python_moonclient/cli/pdps.py
new file mode 100644
index 00000000..f1f8fe35
--- /dev/null
+++ b/python_moonclient/python_moonclient/cli/pdps.py
@@ -0,0 +1,180 @@
+import logging
+from cliff.lister import Lister
+from cliff.command import Command
+from importlib.machinery import SourceFileLoader
+
+from python_moonclient.core import models, policies, pdp
+from python_moonclient.cli.parser import Parser
+from python_moonclient.cli.projects import ProjectsUtils
+
+logger = logging.getLogger("moonclient.cli.pdps")
+
+
+class PdpUtils:
+ def __init__(self):
+ pass
+
+ @staticmethod
+ def get_pdp_id(pdp, parsed_id, parsed_name):
+ pdps = pdp.check_pdp()
+ for _pdp_key, _pdp_value in pdps["pdps"].items():
+ if _pdp_key == parsed_id or _pdp_value['name'] == parsed_name:
+ #logger.info("Found pdp : [key='{}' , name='{}']".format(_pdp_key, _pdp_value['name']))
+ return _pdp_key
+ return None
+
+ @staticmethod
+ def get_pdp_name(pdp, parsed_id, parsed_name):
+ pdps = pdp.check_pdp()
+ for _pdp_key, _pdp_value in pdps["pdps"].items():
+ if _pdp_key == parsed_id or _pdp_value['name'] == parsed_name:
+ #logger.info("Found pdp : [key='{}' , name='{}']".format(_pdp_key, _pdp_value['name']))
+ return _pdp_value['name']
+ return None
+
+class Pdps(Lister):
+ """show the list of existing pdps """
+
+ def get_parser(self, prog_name):
+ parser = super().get_parser(prog_name)
+ Parser.add_common_options(parser)
+ return parser
+
+ def take_action(self, parsed_args):
+ consul_host = parsed_args.consul_host
+ consul_port = parsed_args.consul_port
+
+ models.init(consul_host, consul_port)
+ policies.init(consul_host, consul_port)
+ pdp.init(consul_host, consul_port)
+
+ pdps = pdp.check_pdp()
+
+ return (('Key' , 'Name', 'Project id'),
+ ((_pdp_key, _pdp_value['name'], _pdp_value['keystone_project_id']) for _pdp_key, _pdp_value in pdps["pdps"].items())
+ )
+
+
+class CreatePdp(Command):
+ """create a new pdp from a json file and returns the newly created pdp id"""
+ def get_parser(self, prog_name):
+ parser = super().get_parser(prog_name)
+ Parser.add_common_options(parser)
+ Parser.add_filename_argument(parser)
+ return parser
+
+ def take_action(self, parsed_args):
+
+ requests_log = logging.getLogger("requests.packages.urllib3")
+ requests_log.setLevel(logging.WARNING)
+ requests_log.propagate = True
+
+ consul_host = parsed_args.consul_host
+ consul_port = parsed_args.consul_port
+ # project_id = args.keystone_pid
+
+ models.init(consul_host, consul_port)
+ policies.init(consul_host, consul_port)
+ pdp.init(consul_host, consul_port)
+
+ if parsed_args.filename:
+ logger.info("Loading: {}".format(parsed_args.filename))
+ m = SourceFileLoader("scenario", parsed_args.filename)
+ scenario = m.load_module()
+
+ _models = models.check_model()
+ for _model_id, _model_value in _models['models'].items():
+ if _model_value['name'] == scenario.model_name:
+ model_id = _model_id
+ meta_rule_list = _model_value['meta_rules']
+ models.create_model(scenario, model_id)
+ break
+ else:
+ model_id, meta_rule_list = models.create_model(scenario)
+ policy_id = policies.create_policy(scenario, model_id, meta_rule_list)
+ pdp_id = pdp.create_pdp(scenario, policy_id=policy_id)
+ pdp_name = PdpUtils.get_pdp_name(pdp, pdp_id, None)
+ logger.info("Pdp created : [id='{}', name='{}']".format(pdp_id, pdp_name))
+
+
+class DeletePdp(Command):
+ """delete an existing pdp"""
+ def get_parser(self, prog_name):
+ parser = super().get_parser(prog_name)
+ Parser.add_common_options(parser)
+ Parser.add_id_or_name_argument(parser)
+ return parser
+
+ def take_action(self, parsed_args):
+
+ consul_host = parsed_args.consul_host
+ consul_port = parsed_args.consul_port
+
+ models.init(consul_host, consul_port)
+ policies.init(consul_host, consul_port)
+ pdp.init(consul_host, consul_port)
+
+ _search = PdpUtils.get_pdp_id(pdp, parsed_args.id, parsed_args.name)
+ _pdp_key = _search
+ if _pdp_key is None:
+ logger.error("Error pdp not found ")
+ return
+
+ #if parsed_args.id:
+ # logger.info("Deleting: {}".format(parsed_args.id))
+ # _search = parsed_args.id
+ #if parsed_args.name:
+ # logger.info("Deleting: {}".format(parsed_args.name))
+ # _search = parsed_args.name
+
+ #pdps = pdp.check_pdp()
+ #for _pdp_key, _pdp_value in pdps["pdps"].items():
+ # if _pdp_key == _search or _pdp_value['name'] == _search:
+ logger.info("Found {}".format(_pdp_key))
+ pdp.delete_pdp(_pdp_key)
+
+ pdps = pdp.check_pdp()
+ logger.info("Listing all PDP:")
+ for _pdp_key, _pdp_value in pdps["pdps"].items():
+ if _pdp_key == _search : #or _pdp_value['name'] == _search:
+ logger.error("Error in deleting {}".format(_search))
+
+ return (('Key', 'Name', 'Project id'),
+ ((_pdp_key, _pdp_value['name'], _pdp_value['keystone_project_id']) for _pdp_key, _pdp_value in
+ pdps["pdps"].items())
+ )
+
+
+class MapPdp(Command):
+ """map an existing pdp to a keystone project"""
+ def get_parser(self, prog_name):
+ parser = super().get_parser(prog_name)
+ Parser.add_common_options(parser)
+ Parser.add_id_or_name_pdp_argument(parser)
+ Parser.add_id_or_name_project_argument(parser)
+ return parser
+
+ def take_action(self, parsed_args):
+ consul_host = parsed_args.consul_host
+ consul_port = parsed_args.consul_port
+
+ models.init(consul_host, consul_port)
+ policies.init(consul_host, consul_port)
+ pdp.init(consul_host, consul_port)
+
+ #_pdp_key = PdpUtils.get_pdp_id(pdp, parsed_args.id_pdp, parsed_args.name_pdp)
+ _pdp_name = PdpUtils.get_pdp_name(pdp, parsed_args.id_pdp, parsed_args.name_pdp)
+ if _pdp_name is None:
+ logger.error("Error pdp not found ")
+ return
+
+ #_project_key = ProjectsUtils.get_project_id(pdp, parsed_args.id_project, parsed_args.name_project)
+ _project_name = ProjectsUtils.get_project_name(pdp, parsed_args.id_project, parsed_args.name_project)
+ if _project_name is None:
+ logger.error("Error project not found ")
+ return
+
+ logger.info("Mapping: {}=>{}".format(_pdp_name, _project_name))
+
+ #pdp.map_to_keystone(pdp_id=parsed_args.id_pdp, keystone_project_id=parsed_args.id_project)
+ pdp.map_to_keystone(pdp_id=_pdp_name, keystone_project_id=_project_name)
diff --git a/python_moonclient/python_moonclient/cli/policies.py b/python_moonclient/python_moonclient/cli/policies.py
new file mode 100644
index 00000000..94d13db1
--- /dev/null
+++ b/python_moonclient/python_moonclient/cli/policies.py
@@ -0,0 +1,246 @@
+import logging
+from cliff.command import Command
+from cliff.lister import Lister
+
+from python_moonclient.cli.parser import Parser
+
+from python_moonclient.core import models, policies, pdp
+
+logger = logging.getLogger("moonclient.cli.pdps")
+
+
+class PoliciesUtils:
+ def __init__(self):
+ pass
+
+ @staticmethod
+ def get_policy_id(policies, parsed_id, parsed_name):
+ _policies = policies.check_policy()
+ for _policy_key, _policy_value in _policies["policies"].items():
+ if _policy_key == parsed_id or _policy_value['name'] == parsed_name:
+ #logger.info("Found {}".format(_policy_key))
+ return _policy_key
+ return None
+
+ @staticmethod
+ def get_policy_name(policies, parsed_id, parsed_name):
+ _policies = policies.check_policy()
+ for _policy_key, _policy_value in _policies["policies"].items():
+ if _policy_key == parsed_id or _policy_value['name'] == parsed_name:
+ #logger.info("Found {}".format(_policy_key))
+ return _policy_value['name']
+ return None
+
+class Policies(Lister):
+ """show the list of existing policies"""
+ def get_parser(self, prog_name):
+ parser = super().get_parser(prog_name)
+ Parser.add_common_options(parser)
+ return parser
+
+ def take_action(self, parsed_args):
+ consul_host = parsed_args.consul_host
+ consul_port = parsed_args.consul_port
+
+ models.init(consul_host, consul_port)
+ policies.init(consul_host, consul_port)
+ pdp.init(consul_host, consul_port)
+ _policies = policies.check_policy()
+
+ return (('Key' , 'Name'),
+ ((_policy_key, _policy_value['name']) for _policy_key, _policy_value in _policies["policies"].items())
+ )
+
+
+class Subjects(Lister):
+ def get_parser(self, prog_name):
+ parser = super().get_parser(prog_name)
+ Parser.add_common_options(parser)
+ Parser.add_id_or_name_argument(parser)
+ Parser.add_policy_argument(parser)
+ return parser
+
+ def take_action(self, parsed_args):
+ consul_host = parsed_args.consul_host
+ consul_port = parsed_args.consul_port
+
+ models.init(consul_host, consul_port)
+ policies.init(consul_host, consul_port)
+ pdp.init(consul_host, consul_port)
+
+ _policies = policies.check_subject(parsed_args.id, parsed_args.policy_id)
+
+ return (('Key' , 'Name'),
+ ((_policy_key, _policy_value['name']) for _policy_key, _policy_value in _policies["policies"].items())
+ )
+
+
+
+class DeletePolicy(Command):
+ """delete an existing policy"""
+ def get_parser(self, prog_name):
+ parser = super().get_parser(prog_name)
+ Parser.add_common_options(parser)
+ Parser.add_id_or_name_argument(parser)
+ return parser
+
+ def take_action(self, parsed_args):
+ consul_host = parsed_args.consul_host
+ consul_port = parsed_args.consul_port
+
+ models.init(consul_host, consul_port)
+ policies.init(consul_host, consul_port)
+ pdp.init(consul_host, consul_port)
+
+ policy_id = PoliciesUtils.get_policy_id(policies,parsed_args.id, parsed_args.name)
+ policy_name = PoliciesUtils.get_policy_name(policies, parsed_args.id, parsed_args.name)
+
+ logger.info("Deleting: {}".format(policy_name))
+ pdp.delete_pdp(policy_id)
+
+ _policies = policies.check_policy()
+ #logger.info("Listing all Policies:")
+ for _policy_key, _policy_value in _policies["policies"].items():
+ #print(" {} {}".format(_policy_key, _policy_value['name']))
+ if _policy_key == policy_id:
+ logger.error("Error in deleting {}".format(policy_id))
+
+ return (('Key', 'Value'),
+ ((_policy_key, _policy_value) for _policy_key, _policy_value in _policies["policies"].items())
+ )
+
+
+
+class SubjectDatas(Lister):
+ """list the subject data """
+ def get_parser(self, prog_name):
+ parser = super().get_parser(prog_name)
+ Parser.add_common_options(parser)
+ Parser.add_policy_argument(parser)
+ Parser.add_category_argument(parser)
+ return parser
+
+ def take_action(self, parsed_args):
+ consul_host = parsed_args.consul_host
+ consul_port = parsed_args.consul_port
+
+ models.init(consul_host, consul_port)
+ policies.init(consul_host, consul_port)
+ pdp.init(consul_host, consul_port)
+
+ subject_data = policies.check_subject_data(parsed_args.policy_id, None, parsed_args.category_id)
+ if len(subject_data["subject_data"]) == 0:
+ return (('Key', 'Name'),())
+
+ return (('Key', 'Name'),
+ ((_subject_key, subject_data["subject_data"][0]["data"][_subject_key]['name']) for _subject_key in subject_data["subject_data"][0]["data"].keys())
+ )
+
+
+class ObjectDatas(Lister):
+ """list the object data"""
+ def get_parser(self, prog_name):
+ parser = super().get_parser(prog_name)
+ Parser.add_common_options(parser)
+ Parser.add_policy_argument(parser)
+ Parser.add_category_argument(parser)
+ return parser
+
+ def take_action(self, parsed_args):
+ consul_host = parsed_args.consul_host
+ consul_port = parsed_args.consul_port
+
+ models.init(consul_host, consul_port)
+ policies.init(consul_host, consul_port)
+ pdp.init(consul_host, consul_port)
+
+ object_datas = policies.check_object_data(parsed_args.policy_id, None, parsed_args.category_id)
+
+ if len(object_datas["object_data"]) == 0:
+ return (('Key', 'Name'),())
+ object_data = object_datas["object_data"][0]["data"]
+ res = (('Key', 'Name'),
+ ((_object_key, object_data[_object_key]["value"]['name']) for _object_key in list(object_data))
+ )
+ return res
+
+
+class ActionDatas(Lister):
+ """list the action data"""
+ def get_parser(self, prog_name):
+ parser = super().get_parser(prog_name)
+ Parser.add_common_options(parser)
+ Parser.add_policy_argument(parser)
+ Parser.add_category_argument(parser)
+ return parser
+
+ def take_action(self, parsed_args):
+ consul_host = parsed_args.consul_host
+ consul_port = parsed_args.consul_port
+
+ models.init(consul_host, consul_port)
+ policies.init(consul_host, consul_port)
+ pdp.init(consul_host, consul_port)
+
+ action_datas = policies.check_action_data(parsed_args.policy_id, None, parsed_args.category_id)
+
+ if len(action_datas["action_data"]) == 0:
+ return (('Key', 'Name'),())
+ action_data = action_datas["action_data"][0]["data"]
+ res = (('Key', 'Name'),
+ ((_action_key, action_data[_action_key]["value"]['name']) for _action_key in list(action_data))
+ )
+ return res
+
+
+class MetaRules(Lister):
+ """list the meta rules"""
+ def get_parser(self, prog_name):
+ parser = super().get_parser(prog_name)
+ Parser.add_common_options(parser)
+ return parser
+
+ def take_action(self, parsed_args):
+ consul_host = parsed_args.consul_host
+ consul_port = parsed_args.consul_port
+
+ models.init(consul_host, consul_port)
+ policies.init(consul_host, consul_port)
+ pdp.init(consul_host, consul_port)
+
+ metarule_datas = policies.check_meta_rule()
+
+ if len(metarule_datas["meta_rules"]) == 0:
+ return (('Key', 'Name'),())
+
+ metarule_data = metarule_datas["meta_rules"]
+ res = (('Key', 'Name'),
+ ((_key, metarule_data[_key]['name']) for _key in list(metarule_data))
+ )
+ return res
+
+class CreateSubjectData(Command):
+ """create a subject data according to a policy and a category"""
+ def get_parser(self, prog_name):
+ parser = super().get_parser(prog_name)
+ Parser.add_common_options(parser)
+ Parser.add_policy_argument(parser)
+ Parser.add_category_argument(parser)
+ Parser.add_name_argument(parser)
+ return parser
+
+ def take_action(self, parsed_args):
+ consul_host = parsed_args.consul_host
+ consul_port = parsed_args.consul_port
+
+ models.init(consul_host, consul_port)
+ policies.init(consul_host, consul_port)
+ pdp.init(consul_host, consul_port)
+
+ subject_data_id = policies.add_subject_data(parsed_args.policy_id, parsed_args.category_id, parsed_args.name)
+ if subject_data_id is not None:
+ print("Subject category created with id {}".format(subject_data_id))
+ else:
+ print("Error while creating subject category")
+ subject_data = policies.check_subject_data(parsed_args.policy_id, None, parsed_args.category_id)
+ # subject_categories = models.check_subject_category(subject_category_id)
diff --git a/python_moonclient/python_moonclient/cli/projects.py b/python_moonclient/python_moonclient/cli/projects.py
new file mode 100644
index 00000000..c4653a51
--- /dev/null
+++ b/python_moonclient/python_moonclient/cli/projects.py
@@ -0,0 +1,56 @@
+import logging
+from python_moonclient.core import models, policies, pdp
+from python_moonclient.cli.parser import Parser
+from cliff.lister import Lister
+
+logger = logging.getLogger("moonclient.cli.projects")
+
+
+class ProjectsUtils:
+ def __init__(self):
+ pass
+
+ @staticmethod
+ def get_project_id(pdp, parsed_id, parsed_name):
+ projects = pdp.get_keystone_projects()
+ for _project_value in projects['projects']:
+ if _project_value['id'] == parsed_id or _project_value['name'] == parsed_name:
+ #logger.info("Found project : [key='{}' , name='{}']".format(_project_value['id'], _project_value['name']))
+ return _project_value['id']
+ return None
+
+ @staticmethod
+ def get_project_name(pdp, parsed_id, parsed_name):
+ projects = pdp.get_keystone_projects()
+ for _project_value in projects['projects']:
+ if _project_value['id'] == parsed_id or _project_value['name'] == parsed_name:
+ #logger.info("Found project : [key='{}' , name='{}']".format(_project_value['id'], _project_value['name']))
+ return _project_value['name']
+ return None
+
+
+class Projects(Lister):
+ """show the list of projects"""
+
+ def get_parser(self, prog_name):
+ parser = super().get_parser(prog_name)
+ Parser.add_common_options(parser)
+ return parser
+
+ def take_action(self, parsed_args):
+ consul_host = parsed_args.consul_host
+ consul_port = parsed_args.consul_port
+
+ models.init(consul_host, consul_port)
+ policies.init(consul_host, consul_port)
+ pdp.init(consul_host, consul_port)
+
+ projects = pdp.get_keystone_projects()
+
+ return (('Id' , 'Name'),
+ ((_project['id'], _project['name']) for _project in projects['projects'])
+ )
+
+
+
+
diff --git a/python_moonclient/python_moonclient/cli/slaves.py b/python_moonclient/python_moonclient/cli/slaves.py
new file mode 100644
index 00000000..1880f4c2
--- /dev/null
+++ b/python_moonclient/python_moonclient/cli/slaves.py
@@ -0,0 +1,120 @@
+import logging
+from cliff.lister import Lister
+from cliff.command import Command
+
+from python_moonclient.core import models, policies, pdp, slaves
+from python_moonclient.cli.parser import Parser
+
+logger = logging.getLogger("moonclient.cli.slaves")
+
+
+class SlavesUtils:
+ def __init__(self):
+ pass
+
+ @staticmethod
+ def get_slave_name(slaves, parsed_name):
+ _slaves = slaves.get_slaves()
+ for _slave_value in _slaves['slaves']:
+ if _slave_value['name'] == parsed_name:
+ logger.info("Found {}".format(_slave_value['name']))
+ return _slave_value['name']
+ return None
+
+
+class Slaves(Lister):
+ """show the list of slaves"""
+ def get_parser(self, prog_name):
+ parser = super().get_parser(prog_name)
+ Parser.add_common_options(parser)
+ return parser
+
+ def take_action(self, parsed_args):
+ requests_log = logging.getLogger("requests.packages.urllib3")
+ requests_log.setLevel(logging.WARNING)
+ requests_log.propagate = True
+
+ consul_host = parsed_args.consul_host
+ consul_port = parsed_args.consul_port
+
+ models.init(consul_host, consul_port)
+ policies.init(consul_host, consul_port)
+ pdp.init(consul_host, consul_port)
+ slaves.init(consul_host, consul_port)
+
+ return (('Name', 'Configured'),
+ ((value['name'], value['configured']) for value in slaves.get_slaves().get('slaves', dict()))
+ )
+
+
+class SetSlave(Command):
+ """update an existing slave to a configured state"""
+ def get_parser(self, prog_name):
+ parser = super().get_parser(prog_name)
+ Parser.add_common_options(parser)
+ Parser.add_name_argument(parser)
+ return parser
+
+ def take_action(self, parsed_args):
+ requests_log = logging.getLogger("requests.packages.urllib3")
+ requests_log.setLevel(logging.WARNING)
+ requests_log.propagate = True
+
+ consul_host = parsed_args.consul_host
+ consul_port = parsed_args.consul_port
+
+ models.init(consul_host, consul_port)
+ policies.init(consul_host, consul_port)
+ pdp.init(consul_host, consul_port)
+ slaves.init(consul_host, consul_port)
+
+ slave_input_name = parsed_args.name
+ if parsed_args.name is None:
+ slave_input_name = "kubernetes-admin@kubernetes"
+ slaves.set_slave(slave_input_name)
+
+ #if slave_name is None:
+ # slave_name = "kubernetes-admin@kubernetes"
+
+ #if parsed_args.name:
+ # slave_name = parsed_args.name
+ print(" {} (configured=True)".format(slave_input_name))
+
+ #for value in slaves.set_slave(slave_name).get('slaves', dict()):
+ # if value['configured']:
+ # print(" {} (configured)".format(value['name']))
+ # else:
+ # print(" {} (not configured)".format(value['name']))#
+
+
+class DeleteSlave(Command):
+ """update an existing slave to a unconfigured state"""
+ def get_parser(self, prog_name):
+ parser = super().get_parser(prog_name)
+ Parser.add_common_options(parser)
+ Parser.add_name_argument(parser)
+ return parser
+
+ def take_action(self, parsed_args):
+ requests_log = logging.getLogger("requests.packages.urllib3")
+ requests_log.setLevel(logging.WARNING)
+ requests_log.propagate = True
+
+ consul_host = parsed_args.consul_host
+ consul_port = parsed_args.consul_port
+
+ models.init(consul_host, consul_port)
+ policies.init(consul_host, consul_port)
+ pdp.init(consul_host, consul_port)
+ slaves.init(consul_host, consul_port)
+
+ slave_input_name = parsed_args.name
+ if parsed_args.name is None:
+ slave_input_name = "kubernetes-admin@kubernetes"
+
+ slaves.delete_slave(slave_input_name)
+ print(" {} (configured=False)".format(slave_input_name))
+
+
+
+
diff --git a/python_moonclient/python_moonclient/core/__init__.py b/python_moonclient/python_moonclient/core/__init__.py
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/python_moonclient/python_moonclient/core/__init__.py
diff --git a/python_moonclient/python_moonclient/authz.py b/python_moonclient/python_moonclient/core/authz.py
index b90bf00f..7bf9b57b 100644
--- a/python_moonclient/python_moonclient/authz.py
+++ b/python_moonclient/python_moonclient/core/authz.py
@@ -13,7 +13,7 @@ HOST_KEYSTONE = None
PORT_KEYSTONE = None
lock = threading.Lock()
-logger = logging.getLogger("moonclient.authz")
+logger = logging.getLogger("moonclient.core.authz")
def _construct_payload(creds, current_rule, enforcer, target):
diff --git a/python_moonclient/python_moonclient/core/check_tools.py b/python_moonclient/python_moonclient/core/check_tools.py
new file mode 100644
index 00000000..8138f54e
--- /dev/null
+++ b/python_moonclient/python_moonclient/core/check_tools.py
@@ -0,0 +1,411 @@
+from python_moonclient.core.cli_exceptions import MoonCliException
+
+
+def check_optionnal_result(result):
+ if type(result) is not dict:
+ raise MoonCliException("Unexpected request result. It should be a dictionnary")
+ if "result" in result:
+ check_result(result)
+
+
+def check_result(result):
+ if type(result) is not dict or "result" not in result:
+ raise MoonCliException("Unexpected request result. It should be a dictionnary with a 'result' entry")
+ if result["result"] is None:
+ raise MoonCliException("Unexpected request result. The 'result' entry shall not be null")
+
+
+def _check_generic_in_result(field, result, check_not_null=False):
+ if type(field) is not str or type(result) is not dict or field not in result:
+ raise MoonCliException("Unexpected request result. It should be a dictionnary with a '{}' entry".format(field))
+ if check_not_null is True and result[field] is None:
+ raise MoonCliException("Unexpected request result. The '{}' entry shall not be null".format(field))
+
+
+def check_slaves_in_result(result):
+ _check_generic_in_result("slaves", result)
+
+
+def check_pdp_in_result(result):
+ _check_generic_in_result("pdps", result)
+
+
+def check_model_in_result(result, check_not_null=False):
+ _check_generic_in_result("models", result)
+ if check_not_null is True and result["models"] is None:
+ raise MoonCliException("Unexpected request result. The 'models' entry shall not be null")
+
+
+def check_meta_rule_in_result(result):
+ _check_generic_in_result("meta_rules", result)
+
+
+def check_rule_in_result(result):
+ _check_generic_in_result("rules", result)
+
+
+def check_subject_in_result(result):
+ _check_generic_in_result("subjects", result)
+
+
+def check_subject_category_in_result(result):
+ _check_generic_in_result("subject_categories", result)
+
+
+def check_object_category_in_result(result):
+ _check_generic_in_result("object_categories", result)
+
+
+def check_action_category_in_result(result):
+ _check_generic_in_result("action_categories", result)
+
+
+def check_policy_in_result(result):
+ _check_generic_in_result("policies", result)
+
+
+def check_object_in_result(result):
+ _check_generic_in_result("objects", result)
+
+
+def check_action_in_result(result):
+ _check_generic_in_result("actions", result)
+
+
+def check_subject_assignment_in_result(result):
+ _check_generic_in_result("subject_assignments", result, True)
+
+
+def check_object_assignment_in_result(result):
+ _check_generic_in_result("object_assignments", result, True)
+
+
+def check_action_assignment_in_result(result):
+ _check_generic_in_result("action_assignments", result, True)
+
+
+def check_pdp_id(pdp_id, result):
+ check_pdp_in_result(result)
+ if pdp_id not in result['pdps']:
+ raise MoonCliException("Unexpected request result. Unknown pdp id")
+
+
+def _check_generic_name(field, name, field_elt_id, result, do_check_name=True):
+ if type(field) is str:
+ if result[field] is None:
+ raise MoonCliException("Unexpected request result : {} shall not be empty".format(field))
+ if field_elt_id not in result[field]:
+ raise MoonCliException("Unexpected request result. Unknown {} id".format(field))
+ if "name" not in result[field][field_elt_id]:
+ raise MoonCliException("Unexpected request result : {} with id {} has no name".format(field, field_elt_id))
+ if do_check_name and name != result[field][field_elt_id]["name"]:
+ raise MoonCliException("Unexpected request result : {} with id {} has a bad name. Expected {}".format(field, field_elt_id, name))
+
+
+def check_model_name(name, model_id, result, do_check_name):
+ _check_generic_name("models", name, model_id, result, do_check_name)
+
+
+def check_pdp_name(name, pdp_id, result):
+ _check_generic_name("pdps", name, pdp_id, result)
+
+
+def check_subject_categories_name(name, category_id, result):
+ _check_generic_name("subject_categories", name, category_id, result)
+
+
+def check_object_categories_name(name, category_id, result):
+ _check_generic_name("object_categories", name, category_id, result)
+
+
+def check_action_categories_name(name, category_id, result):
+ _check_generic_name("action_categories", name, category_id, result)
+
+
+def check_meta_rules_name(name, meta_rule_id, result):
+ _check_generic_name("meta_rules", name, meta_rule_id, result, False)
+
+
+def check_policy_name(name, policy_id, result):
+ _check_generic_name("policies", name, policy_id, result)
+
+
+def check_subject_name(name, subject_id, result):
+ _check_generic_name("subjects", name, subject_id, result)
+
+
+def check_object_name(name, object_id, result):
+ _check_generic_name("objects", name, object_id, result)
+
+
+def check_action_name(name, action_id, result):
+ _check_generic_name("actions", name, action_id, result)
+
+
+def check_scat_id_in_dict(scat_id, in_dict):
+ if scat_id not in in_dict:
+ raise MoonCliException("Unexpected request result. Subject category not in result")
+
+
+def check_ocat_id_in_dict(ocat_id, in_dict):
+ if ocat_id not in in_dict:
+ raise MoonCliException("Unexpected request result. Object category not in result")
+
+
+def check_acat_id_in_dict(acat_id, in_dict):
+ if acat_id not in in_dict:
+ raise MoonCliException("Unexpected request result. Action category not in result")
+
+
+def check_policy_id_in_pipeline(policy_id, pipeline):
+ if policy_id not in pipeline:
+ raise MoonCliException("Unexpected request result. The policy id {} shall be in the pipeline".format(policy_id))
+
+
+def _check_generic_policy_in_dict(field, policy_id, in_dict):
+ if type(field) is str:
+ if policy_id is not None:
+ if "policy_list" not in in_dict:
+ raise MoonCliException(
+ "Unexpected request result. The policy list of the {} shall not be empty".format(field))
+ if policy_id not in in_dict["policy_list"]:
+ raise MoonCliException(
+ "Unexpected request result. The policy with id {} shall be in the {}".format(policy_id, field))
+
+
+def check_subject_policy(policy_id, in_dict):
+ _check_generic_policy_in_dict("subject", policy_id, in_dict)
+
+
+def check_object_policy(policy_id, in_dict):
+ _check_generic_policy_in_dict("object", policy_id, in_dict)
+
+
+def check_action_policy(policy_id, in_dict):
+ _check_generic_policy_in_dict("action", policy_id, in_dict)
+
+
+def _check_generic_elt_id(field1, field1_id, field2, field2_id, result):
+ if type(field1) is str and type(field2) is str:
+ if result[field1] is None:
+ raise MoonCliException("Unexpected request result: {} shall not be empty".format(field1))
+ if field1_id not in result[field1]:
+ raise MoonCliException("Unexpected request result. Unknown {} with id".format(field1))
+ if field2 not in result[field1][field1_id]:
+ raise MoonCliException("Unexpected request result. {} element with id {} has no {} field".format(field1, field1_id, field2))
+ if field2_id != result[field1][field1_id][field2]:
+ raise MoonCliException(
+ "Unexpected request result. {} element with id {} has a bad {} id. Expected {}".format(field1, field1_id, field2, field2_id))
+
+
+def check_policy_model_id(model_id, policy_id, result):
+ _check_generic_elt_id("policies", policy_id, "model_id", model_id, result)
+
+
+def check_pdp_project_id(project_id, pdp_id, result):
+ _check_generic_elt_id("pdps", pdp_id, "keystone_project_id", project_id, result)
+
+
+def check_subject_description(description, in_dict):
+ if description is not None:
+ if "description" not in in_dict:
+ raise MoonCliException(
+ "Unexpected request result. The description of the subject shall not be empty")
+ if description not in in_dict["description"]:
+ raise MoonCliException(
+ "Unexpected request result. The description {} shall be in the subject".format(description))
+
+
+def check_meta_rules_list_in_model(meta_rule_list, model_id, result):
+ if result["models"] is None:
+ raise MoonCliException("Unexpected request result. results shall not be empty")
+ if model_id not in result['models']:
+ raise MoonCliException("Unexpected request result. Unknown Model id")
+ if "meta_rules" not in result['models'][model_id]:
+ raise MoonCliException("Unexpected request result. Meta rules related to model with id {} are empty".format(model_id))
+ if meta_rule_list != result['models'][model_id]["meta_rules"]:
+ raise MoonCliException("Unexpected request result. Meta rule of model with id {} are different from those expected".format(model_id))
+
+
+def check_name_in_slaves(name, slaves):
+ if name is None:
+ raise MoonCliException("The slave name must be provided !")
+ names = map(lambda x: x['name'], slaves)
+ if name not in names:
+ raise MoonCliException("The slave '{}' was not found !".format(name))
+
+
+def _check_generic_data_data(field,result):
+ if type(field) is str:
+ if field not in result:
+ raise MoonCliException("Unexpected request result. The {} field shall be in result".format(field))
+ # if "data" not in resulti[field]:
+ # raise MoonCliException("Unexpected request result. The data field shall be in result['{}']".format(field))
+
+
+def _check_id_in_generic_data_data(field, data_id, result):
+ if type(field) is str:
+ _check_generic_data_data(field, result)
+ for _data in result[field]:
+ if data_id not in list(_data['data'].keys()):
+ raise MoonCliException("Unexpected request result. Data id {} not in {}".format(data_id, field))
+
+
+def _check_id_not_in_generic_data_data(field, data_id, result):
+ if type(field) is str:
+ _check_generic_data_data(field, result)
+ for _data in result[field]:
+ if data_id in list(_data['data'].keys()):
+ raise MoonCliException("Unexpected request result. Data id {} shall not be in {}".format(data_id, field))
+
+
+def _check_category_in_generic_data_data(field, category_id, result):
+ _check_generic_data_data(field, result)
+ for _data in result[field]:
+ if category_id != _data["category_id"]:
+ raise MoonCliException("Unexpected request result. Category id {} not in {} data".format(category_id, field))
+
+
+def check_subject_data_data(result):
+ _check_generic_data_data("subject_data", result)
+
+
+def check_id_in_subject_data_data(data_id, result):
+ _check_id_in_generic_data_data("subject_data", data_id, result)
+
+
+def check_id_not_in_subject_data_data(data_id, result):
+ _check_id_not_in_generic_data_data("subject_data", data_id, result)
+
+
+def check_category_id_in_subject_data_data(category_id, result):
+ _check_category_in_generic_data_data('subject_data', category_id, result)
+
+
+def check_object_data_data(result):
+ _check_generic_data_data("object_data", result)
+
+
+def check_id_in_object_data_data(data_id, result):
+ _check_id_in_generic_data_data("object_data", data_id, result)
+
+
+def check_id_not_in_object_data_data(data_id, result):
+ _check_id_not_in_generic_data_data("object_data", data_id, result)
+
+
+def check_category_id_in_object_data_data(category_id, result):
+ _check_category_in_generic_data_data('object_data', category_id, result)
+
+
+def check_action_data_data(result):
+ _check_generic_data_data("action_data", result)
+
+
+def check_id_in_action_data_data(data_id, result):
+ _check_id_in_generic_data_data("action_data", data_id, result)
+
+
+def check_id_not_in_action_data_data(data_id, result):
+ _check_id_not_in_generic_data_data("action_data", data_id, result)
+
+
+def check_category_id_in_action_data_data(category_id, result):
+ _check_category_in_generic_data_data('action_data', category_id, result)
+
+
+def _check_generic_assignments(field, field_id_name, field_id, field_cat_id, field_data_id, result):
+ if type(field) is str and type(field_id_name) is str:
+ for key in result[field]:
+ if field_id_name not in result[field][key]:
+ raise MoonCliException("Unexpected request result. subject_id not in result[{}] data".format(field))
+ if "category_id" not in result[field][key]:
+ raise MoonCliException("Unexpected request result. category_id not in result[{}] data".format(field))
+ if "assignments" not in result[field][key]:
+ raise MoonCliException("Unexpected request result. assignments not in result[{}] data".format(field))
+ if result[field][key][field_id_name] == field_id and \
+ result[field][key]["category_id"] == field_cat_id:
+ if field_data_id not in result[field][key]["assignments"]:
+ raise MoonCliException(
+ "Unexpected request result. {} data with id {} not in result[{}][]['assignements'] data".format(field, field_data_id, field))
+
+
+def check_subject_assignements(subject_id, subject_act_id, subject_data_id, result):
+ _check_generic_assignments("subject_assignments", "subject_id", subject_id, subject_act_id, subject_data_id, result)
+
+
+def check_object_assignements(object_id, object_act_id, object_data_id, result):
+ _check_generic_assignments("object_assignments", "object_id", object_id, object_act_id, object_data_id, result)
+
+
+def check_action_assignements(action_id, action_act_id, action_data_id, result):
+ _check_generic_assignments("action_assignments", "action_id", action_id, action_act_id, action_data_id, result)
+
+
+def _check_not_generic_assignments(field, field_id_name, field_id, field_cat_id, field_data_id, result):
+ if type(field) is str and type(field_id_name) is str:
+ for key in result[field]:
+ if field_id_name not in result[field][key]:
+ raise MoonCliException("Unexpected request result. subject_id not in result[{}] data".format(field))
+ if "category_id" not in result[field][key]:
+ raise MoonCliException("Unexpected request result. category_id not in result[{}] data".format(field))
+ if "assignments" not in result[field][key]:
+ raise MoonCliException("Unexpected request result. assignments not in result[{}] data".format(field))
+ if result[field][key]['subject_id'] == field_id and \
+ result[field][key]["category_id"] == field_cat_id:
+ if field_data_id in result[field][key]["assignments"]:
+ raise MoonCliException(
+ "Unexpected request result. {} data with id {} shall not be in result[{}][]['assignements'] data".format(field, field_data_id, field))
+
+
+def check_not_subject_assignements(subject_id, subject_act_id, subject_data_id, result):
+ _check_not_generic_assignments("subject_assignments", "subject_id", subject_id, subject_act_id, subject_data_id, result)
+
+
+def check_not_object_assignements(object_id, object_act_id, object_data_id, result):
+ _check_not_generic_assignments("object_assignments", "object_id", object_id, object_act_id, object_data_id, result)
+
+
+def check_not_action_assignements(action_id, action_act_id, action_data_id, result):
+ _check_not_generic_assignments("action_assignments", "action_id", action_id, action_act_id, action_data_id, result)
+
+
+def check_policy_id_in_dict(policy_id, in_dict):
+ if "policy_id" not in in_dict:
+ raise MoonCliException("Unexpected request result. policy_id not in result")
+ if policy_id != in_dict["policy_id"]:
+ raise MoonCliException("Unexpected request result. Bad policy id in result, expected {}".format(policy_id))
+
+
+def check_meta_rule_id_in_dict(meta_rule_id, in_dict):
+ if "meta_rule_id" not in in_dict:
+ raise MoonCliException("Unexpected request result. meta_rule_id not in result")
+ if meta_rule_id != in_dict["meta_rule_id"]:
+ raise MoonCliException("Unexpected request result. Bad meta rule id in result, expected {}".format(meta_rule_id))
+
+
+def check_rule_in_dict(rule, in_dict):
+ if "rule" not in in_dict:
+ raise MoonCliException("Unexpected request result. rule not in result")
+ if rule != in_dict["rule"]:
+ raise MoonCliException(
+ "Unexpected request result. Bad rule in result, expected {}".format(rule))
+
+
+def check_rule_id_in_list(meta_rule_id, rule_id, rule, in_dict):
+ for item in in_dict:
+ if "meta_rule_id" not in item:
+ raise MoonCliException("Unexpected request result. meta_rule_id field not in result")
+ if meta_rule_id == item["meta_rule_id"]:
+ if rule_id == item["id"]:
+ if rule != item["rule"]:
+ raise MoonCliException("Unexpected request result. Bad rule in result, expected {}".format(rule))
+
+
+def check_rule_id_not_in_list(rule_id, in_dict):
+ found_rule = False
+ for item in in_dict:
+ if rule_id == item["id"]:
+ found_rule = True
+ if found_rule is True:
+ raise MoonCliException("Unexpected request result. Rule with id {} shall not be in result".format(rule_id)) \ No newline at end of file
diff --git a/python_moonclient/python_moonclient/core/cli_exceptions.py b/python_moonclient/python_moonclient/core/cli_exceptions.py
new file mode 100644
index 00000000..2ec2ed18
--- /dev/null
+++ b/python_moonclient/python_moonclient/core/cli_exceptions.py
@@ -0,0 +1,7 @@
+class MoonCliException(Exception):
+ def __init__(self, message):
+
+ # Call the base class constructor with the parameters it needs
+ super(MoonCliException, self).__init__(message)
+
+
diff --git a/python_moonclient/python_moonclient/config.py b/python_moonclient/python_moonclient/core/config.py
index 300ebf1a..f8e3fe29 100644
--- a/python_moonclient/python_moonclient/config.py
+++ b/python_moonclient/python_moonclient/core/config.py
@@ -7,7 +7,9 @@ def get_configuration(consul_host, consul_port, key):
url = "http://{}:{}/v1/kv/{}".format(consul_host, consul_port, key)
req = requests.get(url)
if req.status_code != 200:
- raise Exception("xxx")
+ raise Exception("Exception when retrieving configuration from Consul: {} {}".format(
+ req.status_code, req.text
+ ))
data = req.json()
if len(data) == 1:
data = data[0]
diff --git a/python_moonclient/python_moonclient/core/json_export.py b/python_moonclient/python_moonclient/core/json_export.py
new file mode 100644
index 00000000..53c1b1f0
--- /dev/null
+++ b/python_moonclient/python_moonclient/core/json_export.py
@@ -0,0 +1,26 @@
+import logging
+import requests
+import copy
+from python_moonclient.core import config
+
+
+logger = logging.getLogger("moonclient.core.export_json")
+
+URL = None
+HEADERS = None
+
+def init(consul_host, consul_port):
+ conf_data = config.get_config_data(consul_host, consul_port)
+ global URL, HEADERS
+ URL = "http://{}:{}".format(
+ conf_data['manager_host'],
+ conf_data['manager_port'])
+ URL = URL + "{}"
+ HEADERS = {"content-type": "application/json"}
+
+
+def export_to_json():
+ req = requests.get(URL.format("/export"))
+ req.raise_for_status()
+ result = req.json()
+ return result \ No newline at end of file
diff --git a/python_moonclient/python_moonclient/core/json_import.py b/python_moonclient/python_moonclient/core/json_import.py
new file mode 100644
index 00000000..a724476b
--- /dev/null
+++ b/python_moonclient/python_moonclient/core/json_import.py
@@ -0,0 +1,29 @@
+import logging
+import requests
+import copy
+from python_moonclient.core import config
+
+
+logger = logging.getLogger("moonclient.core.import_json")
+
+URL = None
+HEADERS = None
+
+def init(consul_host, consul_port):
+ conf_data = config.get_config_data(consul_host, consul_port)
+ global URL, HEADERS
+ URL = "http://{}:{}".format(
+ conf_data['manager_host'],
+ conf_data['manager_port'])
+ URL = URL + "{}"
+ HEADERS = {"content-type": "application/json"}
+
+
+def import_json(file_name):
+ files = {'file': open(file_name, 'rb')}
+ req = requests.post(URL.format("/import"), files=files)
+ result = req.json()
+ if isinstance(result,dict) and "message" in result:
+ req.reason = result["message"]
+ req.raise_for_status()
+ return result \ No newline at end of file
diff --git a/python_moonclient/python_moonclient/models.py b/python_moonclient/python_moonclient/core/models.py
index 069c673b..709b4a7a 100644
--- a/python_moonclient/python_moonclient/models.py
+++ b/python_moonclient/python_moonclient/core/models.py
@@ -1,9 +1,10 @@
import logging
import requests
import copy
-from . import config
+from python_moonclient.core import config
+from python_moonclient.core.check_tools import *
-logger = logging.getLogger("moonclient.models")
+logger = logging.getLogger("moonclient.core.models")
URL = None
@@ -38,18 +39,13 @@ def init(consul_host, consul_port):
HEADERS = {"content-type": "application/json"}
-def check_model(model_id=None, check_model_name=True):
+def check_model(model_id=None, do_check_model_name=True):
req = requests.get(URL.format("/models"))
- assert req.status_code == 200
+ req.raise_for_status()
result = req.json()
- assert type(result) is dict
- assert "models" in result
+ check_model_in_result(result)
if model_id:
- assert result["models"]
- assert model_id in result['models']
- assert "name" in result['models'][model_id]
- if check_model_name:
- assert model_template["name"] == result['models'][model_id]["name"]
+ check_model_name(model_template["name"], model_id, result, do_check_model_name)
return result
@@ -57,135 +53,112 @@ def add_model(name=None):
if name:
model_template['name'] = name
req = requests.post(URL.format("/models"), json=model_template, headers=HEADERS)
- assert req.status_code == 200
+ req.raise_for_status()
result = req.json()
- assert type(result) is dict
+ check_model_in_result(result)
model_id = list(result['models'].keys())[0]
- if "result" in result:
- assert result["result"]
- assert "name" in result['models'][model_id]
- assert model_template["name"] == result['models'][model_id]["name"]
+ check_model_name(model_template["name"], model_id, result, True)
return model_id
def delete_model(model_id):
req = requests.delete(URL.format("/models/{}".format(model_id)))
- assert req.status_code == 200
+ req.raise_for_status()
result = req.json()
- assert type(result) is dict
- assert "result" in result
- assert result["result"]
+ check_result(result)
def add_subject_category(name="subject_cat_1"):
category_template["name"] = name
req = requests.post(URL.format("/subject_categories"), json=category_template, headers=HEADERS)
- assert req.status_code == 200
+ req.raise_for_status()
result = req.json()
- assert type(result) is dict
- assert "subject_categories" in result
+
+ check_subject_category_in_result(result)
category_id = list(result['subject_categories'].keys())[0]
- if "result" in result:
- assert result["result"]
- assert "name" in result['subject_categories'][category_id]
- assert category_template["name"] == result['subject_categories'][category_id]["name"]
+ check_optionnal_result(result)
+ check_subject_categories_name(category_template["name"], category_id, result)
return category_id
-def check_subject_category(category_id):
+def check_subject_category(category_id=None):
req = requests.get(URL.format("/subject_categories"))
- assert req.status_code == 200
+ req.raise_for_status()
result = req.json()
- assert type(result) is dict
- assert "subject_categories" in result
- if "result" in result:
- assert result["result"]
- assert category_id in result['subject_categories']
- assert "name" in result['subject_categories'][category_id]
- assert category_template["name"] == result['subject_categories'][category_id]["name"]
+
+ check_subject_category_in_result(result)
+ check_optionnal_result(result)
+ if category_id is not None:
+ check_subject_categories_name(category_template["name"], category_id, result)
+ return result
def delete_subject_category(category_id):
req = requests.delete(URL.format("/subject_categories/{}".format(category_id)))
- assert req.status_code == 200
+ req.raise_for_status()
result = req.json()
- assert type(result) is dict
- if "result" in result:
- assert result["result"]
+ check_optionnal_result(result)
def add_object_category(name="object_cat_1"):
category_template["name"] = name
req = requests.post(URL.format("/object_categories"), json=category_template, headers=HEADERS)
- assert req.status_code == 200
+ req.raise_for_status()
result = req.json()
- assert type(result) is dict
- assert "object_categories" in result
+ check_object_category_in_result(result)
category_id = list(result['object_categories'].keys())[0]
- if "result" in result:
- assert result["result"]
- assert "name" in result['object_categories'][category_id]
- assert category_template["name"] == result['object_categories'][category_id]["name"]
+ check_optionnal_result(result)
+ check_object_categories_name(category_template["name"], category_id, result)
return category_id
-def check_object_category(category_id):
+def check_object_category(category_id=None):
req = requests.get(URL.format("/object_categories"))
- assert req.status_code == 200
+ req.raise_for_status()
result = req.json()
- assert type(result) is dict
- assert "object_categories" in result
- if "result" in result:
- assert result["result"]
- assert category_id in result['object_categories']
- assert "name" in result['object_categories'][category_id]
- assert category_template["name"] == result['object_categories'][category_id]["name"]
+ check_object_category_in_result(result)
+ check_optionnal_result(result)
+ if category_id is not None:
+ check_object_categories_name(category_template["name"], category_id, result)
+ return result
def delete_object_category(category_id):
req = requests.delete(URL.format("/object_categories/{}".format(category_id)))
- assert req.status_code == 200
+ req.raise_for_status()
result = req.json()
- assert type(result) is dict
- if "result" in result:
- assert result["result"]
+ check_optionnal_result(result)
def add_action_category(name="action_cat_1"):
category_template["name"] = name
req = requests.post(URL.format("/action_categories"), json=category_template, headers=HEADERS)
- assert req.status_code == 200
+ req.raise_for_status()
result = req.json()
- assert type(result) is dict
- assert "action_categories" in result
+ check_action_category_in_result(result)
category_id = list(result['action_categories'].keys())[0]
- if "result" in result:
- assert result["result"]
- assert "name" in result['action_categories'][category_id]
- assert category_template["name"] == result['action_categories'][category_id]["name"]
+ check_optionnal_result(result)
+ check_action_categories_name(category_template["name"], category_id, result)
return category_id
-def check_action_category(category_id):
+def check_action_category(category_id=None):
req = requests.get(URL.format("/action_categories"))
- assert req.status_code == 200
+ req.raise_for_status()
result = req.json()
- assert type(result) is dict
- assert "action_categories" in result
- if "result" in result:
- assert result["result"]
- assert category_id in result['action_categories']
- assert "name" in result['action_categories'][category_id]
- assert category_template["name"] == result['action_categories'][category_id]["name"]
+ print(result)
+ check_action_category_in_result(result)
+ check_optionnal_result(result)
+ if category_id is not None:
+ check_action_categories_name(category_template["name"], category_id, result)
+ return result
def delete_action_category(category_id):
req = requests.delete(URL.format("/action_categories/{}".format(category_id)))
- assert req.status_code == 200
+ req.raise_for_status()
result = req.json()
- assert type(result) is dict
- if "result" in result:
- assert result["result"]
+ check_optionnal_result(result)
def add_categories_and_meta_rule(name="test_meta_rule"):
@@ -198,15 +171,12 @@ def add_categories_and_meta_rule(name="test_meta_rule"):
_meta_rule_template["object_categories"].append(ocat_id)
_meta_rule_template["action_categories"].append(acat_id)
req = requests.post(URL.format("/meta_rules"), json=_meta_rule_template, headers=HEADERS)
- assert req.status_code == 200
+ req.raise_for_status()
result = req.json()
- assert type(result) is dict
- assert "meta_rules" in result
+ check_meta_rule_in_result(result)
meta_rule_id = list(result['meta_rules'].keys())[0]
- if "result" in result:
- assert result["result"]
- assert "name" in result['meta_rules'][meta_rule_id]
- assert _meta_rule_template["name"] == result['meta_rules'][meta_rule_id]["name"]
+ check_optionnal_result(result)
+ check_meta_rules_name(_meta_rule_template["name"], meta_rule_id, result)
return meta_rule_id, scat_id, ocat_id, acat_id
@@ -220,63 +190,54 @@ def add_meta_rule(name="test_meta_rule", scat=[], ocat=[], acat=[]):
_meta_rule_template["action_categories"] = []
_meta_rule_template["action_categories"].extend(acat)
req = requests.post(URL.format("/meta_rules"), json=_meta_rule_template, headers=HEADERS)
- assert req.status_code == 200
+ req.raise_for_status()
result = req.json()
- assert type(result) is dict
- assert "meta_rules" in result
+ check_meta_rule_in_result(result)
meta_rule_id = list(result['meta_rules'].keys())[0]
- if "result" in result:
- assert result["result"]
- assert "name" in result['meta_rules'][meta_rule_id]
- assert _meta_rule_template["name"] == result['meta_rules'][meta_rule_id]["name"]
+ check_optionnal_result(result)
+ check_meta_rules_name(_meta_rule_template["name"], meta_rule_id, result)
return meta_rule_id
def check_meta_rule(meta_rule_id, scat_id=None, ocat_id=None, acat_id=None):
req = requests.get(URL.format("/meta_rules"))
- assert req.status_code == 200
+ req.raise_for_status()
result = req.json()
- assert type(result) is dict
- assert "meta_rules" in result
- if "result" in result:
- assert result["result"]
+ check_meta_rule_in_result(result)
+ check_optionnal_result(result)
if not meta_rule_id:
return result
- assert meta_rule_id in result['meta_rules']
- assert "name" in result['meta_rules'][meta_rule_id]
+ check_meta_rules_name(None, meta_rule_id, result)
if scat_id:
- assert scat_id in result['meta_rules'][meta_rule_id]["subject_categories"]
+ check_scat_id_in_dict(scat_id, result['meta_rules'][meta_rule_id]["subject_categories"])
if ocat_id:
- assert ocat_id in result['meta_rules'][meta_rule_id]["object_categories"]
+ check_ocat_id_in_dict(ocat_id, result['meta_rules'][meta_rule_id]["object_categories"])
if acat_id:
- assert acat_id in result['meta_rules'][meta_rule_id]["action_categories"]
+ check_acat_id_in_dict(acat_id, result['meta_rules'][meta_rule_id]["action_categories"])
+ return result
def delete_meta_rule(meta_rule_id):
req = requests.delete(URL.format("/meta_rules/{}".format(meta_rule_id)))
- assert req.status_code == 200
+ req.raise_for_status()
result = req.json()
- assert type(result) is dict
- if "result" in result:
- assert result["result"]
+ check_optionnal_result(result)
def add_meta_rule_to_model(model_id, meta_rule_id):
- model = check_model(model_id, check_model_name=False)['models']
+ model = check_model(model_id, do_check_model_name=False)['models']
meta_rule_list = model[model_id]["meta_rules"]
if meta_rule_id not in meta_rule_list:
meta_rule_list.append(meta_rule_id)
req = requests.patch(URL.format("/models/{}".format(model_id)),
json={"meta_rules": meta_rule_list},
headers=HEADERS)
- assert req.status_code == 200
+ req.raise_for_status()
result = req.json()
- assert type(result) is dict
+ check_model_in_result(result)
model_id = list(result['models'].keys())[0]
- if "result" in result:
- assert result["result"]
- assert "meta_rules" in result['models'][model_id]
- assert meta_rule_list == result['models'][model_id]["meta_rules"]
+ check_optionnal_result(result)
+ check_meta_rules_list_in_model(meta_rule_list, model_id, result)
def create_model(scenario, model_id=None):
diff --git a/python_moonclient/python_moonclient/pdp.py b/python_moonclient/python_moonclient/core/pdp.py
index 6841a276..4e9e404c 100644
--- a/python_moonclient/python_moonclient/pdp.py
+++ b/python_moonclient/python_moonclient/core/pdp.py
@@ -1,9 +1,11 @@
import sys
import logging
import requests
-from python_moonclient import config
+from python_moonclient.core import config
+from python_moonclient.core.check_tools import *
-logger = logging.getLogger("python_moonclient.pdp")
+
+logger = logging.getLogger("python_moonclient.core.pdp")
URL = None
HEADERS = None
@@ -63,7 +65,7 @@ def get_keystone_projects():
req = requests.post("{}/auth/tokens".format(KEYSTONE_SERVER), json=data_auth, headers=HEADERS)
logger.debug("{}/auth/tokens".format(KEYSTONE_SERVER))
logger.debug(req.text)
- assert req.status_code in (200, 201)
+ req.raise_for_status()
TOKEN = req.headers['X-Subject-Token']
HEADERS['X-Auth-Token'] = TOKEN
req = requests.get("{}/projects".format(KEYSTONE_SERVER), headers=HEADERS)
@@ -77,11 +79,11 @@ def get_keystone_projects():
}
}
req = requests.post("{}/auth/tokens".format(KEYSTONE_SERVER), json=data_auth, headers=HEADERS)
- assert req.status_code in (200, 201)
+ req.raise_for_status()
TOKEN = req.headers['X-Subject-Token']
HEADERS['X-Auth-Token'] = TOKEN
req = requests.get("{}/projects".format(KEYSTONE_SERVER), headers=HEADERS)
- assert req.status_code in (200, 201)
+ req.raise_for_status()
return req.json()
@@ -101,25 +103,19 @@ def get_keystone_id(pdp_name):
return keystone_project_id
+
def check_pdp(pdp_id=None, keystone_project_id=None, moon_url=None):
_URL = URL
if moon_url:
_URL = moon_url
req = requests.get(_URL + "/pdp")
- assert req.status_code == 200
+ req.raise_for_status()
result = req.json()
- assert type(result) is dict
- assert "pdps" in result
+ check_pdp_in_result(result)
if pdp_id:
- assert result["pdps"]
- assert pdp_id in result['pdps']
- assert "name" in result['pdps'][pdp_id]
- assert pdp_template["name"] == result['pdps'][pdp_id]["name"]
+ check_pdp_name(pdp_template["name"], pdp_id, result)
if keystone_project_id:
- assert result["pdps"]
- assert pdp_id in result['pdps']
- assert "keystone_project_id" in result['pdps'][pdp_id]
- assert keystone_project_id == result['pdps'][pdp_id]["keystone_project_id"]
+ check_pdp_project_id(keystone_project_id, pdp_id, result)
return result
@@ -130,54 +126,42 @@ def add_pdp(name="test_pdp", policy_id=None):
req = requests.post(URL + "/pdp", json=pdp_template, headers=HEADERS)
logger.debug(req.status_code)
logger.debug(req)
- assert req.status_code == 200
+ req.raise_for_status()
result = req.json()
- assert type(result) is dict
+ check_pdp_in_result(result)
pdp_id = list(result['pdps'].keys())[0]
- if "result" in result:
- assert result["result"]
- assert "name" in result['pdps'][pdp_id]
- assert pdp_template["name"] == result['pdps'][pdp_id]["name"]
+ check_pdp_name(pdp_template["name"], pdp_id, result)
return pdp_id
def update_pdp(pdp_id, policy_id=None):
req = requests.get(URL + "/pdp/{}".format(pdp_id))
- assert req.status_code == 200
+ req.raise_for_status()
result = req.json()
- assert type(result) is dict
- assert "pdps" in result
- assert pdp_id in result['pdps']
+ check_pdp_id(pdp_id, result)
pipeline = result['pdps'][pdp_id]["security_pipeline"]
if policy_id not in pipeline:
pipeline.append(policy_id)
req = requests.patch(URL + "/pdp/{}".format(pdp_id),
json={"security_pipeline": pipeline})
- assert req.status_code == 200
+ req.raise_for_status()
result = req.json()
- assert type(result) is dict
- assert "pdps" in result
- assert pdp_id in result['pdps']
+ check_pdp_id(pdp_id, result)
req = requests.get(URL + "/pdp/{}".format(pdp_id))
- assert req.status_code == 200
+ req.raise_for_status()
result = req.json()
- assert type(result) is dict
- assert "pdps" in result
- assert pdp_id in result['pdps']
- assert policy_id in pipeline
+ check_pdp_id(pdp_id, result)
+ check_policy_id_in_pipeline(pdp_id, pipeline)
def map_to_keystone(pdp_id, keystone_project_id):
req = requests.patch(URL + "/pdp/{}".format(pdp_id),
json={"keystone_project_id": keystone_project_id},
headers=HEADERS)
- assert req.status_code == 200
+ req.raise_for_status()
result = req.json()
- assert type(result) is dict
- if "result" in result:
- assert result["result"]
- assert pdp_id in result['pdps']
+ check_pdp_id(pdp_id, result)
# assert "name" in result['pdps'][pdp_id]
# assert pdp_template["name"] == result['pdps'][pdp_id]["name"]
return pdp_id
@@ -185,11 +169,9 @@ def map_to_keystone(pdp_id, keystone_project_id):
def delete_pdp(pdp_id):
req = requests.delete(URL + "/pdp/{}".format(pdp_id))
- assert req.status_code == 200
+ req.raise_for_status()
result = req.json()
- assert type(result) is dict
- assert "result" in result
- assert result["result"]
+ check_result(result)
def create_pdp(scenario, policy_id=None, project_id=None):
@@ -208,4 +190,4 @@ def create_pdp(scenario, policy_id=None, project_id=None):
return pdp_id
_pdp_id = add_pdp(name=scenario.pdp_name, policy_id=policy_id)
# map_to_keystone(pdp_id=_pdp_id, keystone_project_id=project_id)
- return _pdp_id \ No newline at end of file
+ return _pdp_id
diff --git a/python_moonclient/python_moonclient/policies.py b/python_moonclient/python_moonclient/core/policies.py
index 0fae63c2..46d918aa 100644
--- a/python_moonclient/python_moonclient/policies.py
+++ b/python_moonclient/python_moonclient/core/policies.py
@@ -1,8 +1,9 @@
import logging
import requests
-from . import config, models
+from python_moonclient.core import models, config
+from python_moonclient.core.check_tools import *
-logger = logging.getLogger("moonclient.policies")
+logger = logging.getLogger("moonclient.core.policies")
URL = None
HEADERS = None
@@ -65,15 +66,11 @@ def init(consul_host, consul_port):
def check_policy(policy_id=None):
req = requests.get(URL.format("/policies"))
- assert req.status_code == 200
+ req.raise_for_status()
result = req.json()
- assert type(result) is dict
- assert "policies" in result
+ check_policy_in_result(result)
if policy_id:
- assert result["policies"]
- assert policy_id in result['policies']
- assert "name" in result['policies'][policy_id]
- assert policy_template["name"] == result['policies'][policy_id]["name"]
+ check_policy_name(policy_template["name"], policy_id, result)
return result
@@ -81,37 +78,31 @@ def add_policy(name="test_policy", genre="authz"):
policy_template["name"] = name
policy_template["genre"] = genre
req = requests.post(URL.format("/policies"), json=policy_template, headers=HEADERS)
- assert req.status_code == 200
+ req.raise_for_status()
result = req.json()
- assert type(result) is dict
+ check_policy_in_result(result)
policy_id = list(result['policies'].keys())[0]
- if "result" in result:
- assert result["result"]
- assert "name" in result['policies'][policy_id]
- assert policy_template["name"] == result['policies'][policy_id]["name"]
+ check_optionnal_result(result)
+ check_policy_name(policy_template["name"], policy_id, result)
return policy_id
def update_policy(policy_id, model_id):
req = requests.patch(URL.format("/policies/{}".format(policy_id)),
json={"model_id": model_id}, headers=HEADERS)
- assert req.status_code == 200
+ req.raise_for_status()
result = req.json()
- assert type(result) is dict
+ check_policy_in_result(result)
policy_id = list(result['policies'].keys())[0]
- if "result" in result:
- assert result["result"]
- assert "model_id" in result['policies'][policy_id]
- assert model_id == result['policies'][policy_id]["model_id"]
+ check_optionnal_result(result)
+ check_policy_model_id(model_id, policy_id, result)
def delete_policy(policy_id):
req = requests.delete(URL.format("/policies/{}".format(policy_id)))
- assert req.status_code == 200
+ req.raise_for_status()
result = req.json()
- assert type(result) is dict
- assert "result" in result
- assert result["result"]
+ check_result(result)
def add_subject(policy_id=None, name="test_subject"):
@@ -124,9 +115,9 @@ def add_subject(policy_id=None, name="test_subject"):
logger.debug(URL.format("/subjects"))
req = requests.post(URL.format("/subjects"), json=subject_template, headers=HEADERS)
logger.debug(req.text)
- assert req.status_code == 200
+ req.raise_for_status()
result = req.json()
- assert "subjects" in result
+ check_subject_in_result(result)
subject_id = list(result['subjects'].keys())[0]
return subject_id
@@ -141,16 +132,11 @@ def update_subject(subject_id, policy_id=None, description=None):
else:
req = requests.patch(URL.format("/subjects/{}".format(subject_id)),
json={"description": description})
- assert req.status_code == 200
+ req.raise_for_status()
result = req.json()
- assert "subjects" in result
- assert "name" in result["subjects"][subject_id]
- assert subject_template["name"] == result["subjects"][subject_id]["name"]
- assert "policy_list" in result["subjects"][subject_id]
- if policy_id:
- assert policy_id in result["subjects"][subject_id]["policy_list"]
- if description:
- assert description in result["subjects"][subject_id]["description"]
+ check_subject_name(subject_template["name"], subject_id, result)
+ check_subject_policy(policy_id, result["subjects"][subject_id])
+ check_subject_description(description, result["subjects"][subject_id])
def check_subject(subject_id=None, policy_id=None):
@@ -158,14 +144,10 @@ def check_subject(subject_id=None, policy_id=None):
req = requests.get(URL.format("/policies/{}/subjects".format(policy_id)))
else:
req = requests.get(URL.format("/subjects"))
- assert req.status_code == 200
+ req.raise_for_status()
result = req.json()
- assert "subjects" in result
- assert "name" in result["subjects"][subject_id]
- assert subject_template["name"] == result["subjects"][subject_id]["name"]
- if policy_id:
- assert "policy_list" in result["subjects"][subject_id]
- assert policy_id in result["subjects"][subject_id]["policy_list"]
+ check_subject_name(subject_template["name"], subject_id, result)
+ check_subject_policy(policy_id, result["subjects"][subject_id])
def delete_subject(subject_id, policy_id=None):
@@ -173,25 +155,20 @@ def delete_subject(subject_id, policy_id=None):
req = requests.delete(URL.format("/policies/{}/subjects/{}".format(policy_id, subject_id)))
else:
req = requests.delete(URL.format("/subjects/{}".format(subject_id)))
- assert req.status_code == 200
+ req.raise_for_status()
result = req.json()
- assert type(result) is dict
- assert "result" in result
- assert result["result"]
+ check_result(result)
if policy_id:
req = requests.get(URL.format("/policies/{}/subjects".format(policy_id)))
else:
req = requests.get(URL.format("/subjects"))
- assert req.status_code == 200
+ req.raise_for_status()
result = req.json()
- assert "subjects" in result
+ check_subject_in_result(result)
if subject_id in result["subjects"]:
- assert "name" in result["subjects"][subject_id]
- assert subject_template["name"] == result["subjects"][subject_id]["name"]
- if policy_id:
- assert "policy_list" in result["subjects"][subject_id]
- assert policy_id not in result["subjects"][subject_id]["policy_list"]
+ check_subject_name(subject_template["name"], subject_id, result)
+ check_subject_policy(policy_id, result["subjects"][subject_id])
def add_object(policy_id=None, name="test_object"):
@@ -201,22 +178,20 @@ def add_object(policy_id=None, name="test_object"):
json=object_template, headers=HEADERS)
else:
req = requests.post(URL.format("/objects"), json=object_template, headers=HEADERS)
- assert req.status_code == 200
+ req.raise_for_status()
result = req.json()
- assert "objects" in result
+ check_object_in_result(result)
object_id = list(result['objects'].keys())[0]
return object_id
def update_object(object_id, policy_id):
req = requests.patch(URL.format("/policies/{}/objects/{}".format(policy_id, object_id)), json={})
- assert req.status_code == 200
+ req.raise_for_status()
result = req.json()
- assert "objects" in result
- assert "name" in result["objects"][object_id]
- assert object_template["name"] == result["objects"][object_id]["name"]
- assert "policy_list" in result["objects"][object_id]
- assert policy_id in result["objects"][object_id]["policy_list"]
+ check_object_in_result(result)
+ check_object_name(object_template["name"] , object_id, result)
+ check_object_policy(policy_id, result["objects"][object_id])
def check_object(object_id=None, policy_id=None):
@@ -224,14 +199,12 @@ def check_object(object_id=None, policy_id=None):
req = requests.get(URL.format("/policies/{}/objects".format(policy_id)))
else:
req = requests.get(URL.format("/objects"))
- assert req.status_code == 200
+ req.raise_for_status()
result = req.json()
- assert "objects" in result
- assert "name" in result["objects"][object_id]
- assert object_template["name"] == result["objects"][object_id]["name"]
+ check_object_in_result(result)
+ check_object_name(object_template["name"], object_id, result)
if policy_id:
- assert "policy_list" in result["objects"][object_id]
- assert policy_id in result["objects"][object_id]["policy_list"]
+ check_object_policy(policy_id, result["objects"][object_id])
def delete_object(object_id, policy_id=None):
@@ -239,25 +212,21 @@ def delete_object(object_id, policy_id=None):
req = requests.delete(URL.format("/policies/{}/objects/{}".format(policy_id, object_id)))
else:
req = requests.delete(URL.format("/objects/{}".format(object_id)))
- assert req.status_code == 200
+ req.raise_for_status()
result = req.json()
- assert type(result) is dict
- assert "result" in result
- assert result["result"]
+ check_result(result)
if policy_id:
req = requests.get(URL.format("/policies/{}/objects".format(policy_id)))
else:
req = requests.get(URL.format("/objects"))
- assert req.status_code == 200
+ req.raise_for_status()
result = req.json()
- assert "objects" in result
+ check_object_in_result(result)
if object_id in result["objects"]:
- assert "name" in result["objects"][object_id]
- assert object_template["name"] == result["objects"][object_id]["name"]
+ check_object_name(object_template["name"], object_id, result)
if policy_id:
- assert "policy_list" in result["objects"][object_id]
- assert policy_id not in result["objects"][object_id]["policy_list"]
+ check_object_policy(policy_id, result["objects"][object_id])
def add_action(policy_id=None, name="test_action"):
@@ -267,22 +236,20 @@ def add_action(policy_id=None, name="test_action"):
json=action_template, headers=HEADERS)
else:
req = requests.post(URL.format("/actions"), json=action_template, headers=HEADERS)
- assert req.status_code == 200
+ req.raise_for_status()
result = req.json()
- assert "actions" in result
+ check_action_in_result(result)
action_id = list(result['actions'].keys())[0]
return action_id
def update_action(action_id, policy_id):
req = requests.patch(URL.format("/policies/{}/actions/{}".format(policy_id, action_id)), json={})
- assert req.status_code == 200
+ req.raise_for_status()
result = req.json()
- assert "actions" in result
- assert "name" in result["actions"][action_id]
- assert action_template["name"] == result["actions"][action_id]["name"]
- assert "policy_list" in result["actions"][action_id]
- assert policy_id in result["actions"][action_id]["policy_list"]
+ check_action_in_result(result)
+ check_action_name(action_template["name"], action_id, result)
+ check_action_policy(policy_id, result["actions"][action_id])
def check_action(action_id=None, policy_id=None):
@@ -290,14 +257,12 @@ def check_action(action_id=None, policy_id=None):
req = requests.get(URL.format("/policies/{}/actions".format(policy_id)))
else:
req = requests.get(URL.format("/actions"))
- assert req.status_code == 200
+ req.raise_for_status()
result = req.json()
- assert "actions" in result
- assert "name" in result["actions"][action_id]
- assert action_template["name"] == result["actions"][action_id]["name"]
+ check_action_in_result(result)
+ check_action_name(action_template["name"], action_id, result)
if policy_id:
- assert "policy_list" in result["actions"][action_id]
- assert policy_id in result["actions"][action_id]["policy_list"]
+ check_action_policy(policy_id, result["actions"][action_id])
def delete_action(action_id, policy_id=None):
@@ -305,127 +270,117 @@ def delete_action(action_id, policy_id=None):
req = requests.delete(URL.format("/policies/{}/actions/{}".format(policy_id, action_id)))
else:
req = requests.delete(URL.format("/actions/{}".format(action_id)))
- assert req.status_code == 200
+ req.raise_for_status()
result = req.json()
- assert type(result) is dict
- assert "result" in result
- assert result["result"]
+ check_result(result)
if policy_id:
req = requests.get(URL.format("/policies/{}/actions".format(policy_id)))
else:
req = requests.get(URL.format("/actions"))
- assert req.status_code == 200
+ req.raise_for_status()
result = req.json()
- assert "actions" in result
+ check_action_in_result(result)
if action_id in result["actions"]:
- assert "name" in result["actions"][action_id]
- assert action_template["name"] == result["actions"][action_id]["name"]
+ check_action_name(action_template["name"], action_id, result)
if policy_id:
- assert "policy_list" in result["actions"][action_id]
- assert policy_id not in result["actions"][action_id]["policy_list"]
+ check_action_policy(policy_id, result["actions"][action_id])
def add_subject_data(policy_id, category_id, name="subject_data1"):
subject_data_template['name'] = name
req = requests.post(URL.format("/policies/{}/subject_data/{}".format(policy_id, category_id)),
json=subject_data_template, headers=HEADERS)
- assert req.status_code == 200
+ req.raise_for_status()
result = req.json()
- assert "subject_data" in result
+ check_subject_data_data(result)
subject_id = list(result['subject_data']['data'].keys())[0]
return subject_id
def check_subject_data(policy_id, data_id, category_id):
req = requests.get(URL.format("/policies/{}/subject_data/{}".format(policy_id, category_id)))
- assert req.status_code == 200
+ req.raise_for_status()
result = req.json()
- assert "subject_data" in result
- for _data in result['subject_data']:
- assert data_id in list(_data['data'].keys())
- assert category_id == _data["category_id"]
+ print(result)
+ if data_id is not None:
+ check_id_in_subject_data_data(data_id, result)
+ check_category_id_in_subject_data_data(category_id, result)
+ return result
def delete_subject_data(policy_id, category_id, data_id):
req = requests.delete(URL.format("/policies/{}/subject_data/{}/{}".format(policy_id, category_id, data_id)),
headers=HEADERS)
- assert req.status_code == 200
+ req.raise_for_status()
req = requests.get(URL.format("/policies/{}/subject_data/{}".format(policy_id, category_id)))
- assert req.status_code == 200
+ req.raise_for_status()
result = req.json()
- assert "subject_data" in result
- for _data in result['subject_data']:
- assert data_id not in list(_data['data'].keys())
- assert category_id == _data["category_id"]
+ check_id_not_in_subject_data_data(data_id, result)
+ check_category_id_in_subject_data_data(category_id, result)
def add_object_data(policy_id, category_id, name="object_data1"):
object_data_template['name'] = name
req = requests.post(URL.format("/policies/{}/object_data/{}".format(policy_id, category_id)),
json=object_data_template, headers=HEADERS)
- assert req.status_code == 200
+ req.raise_for_status()
result = req.json()
- assert "object_data" in result
+ check_object_data_data(result)
object_id = list(result['object_data']['data'].keys())[0]
return object_id
def check_object_data(policy_id, data_id, category_id):
req = requests.get(URL.format("/policies/{}/object_data/{}".format(policy_id, category_id)))
- assert req.status_code == 200
+ req.raise_for_status()
result = req.json()
- assert "object_data" in result
- for _data in result['object_data']:
- assert data_id in list(_data['data'].keys())
- assert category_id == _data["category_id"]
-
+ if data_id is not None:
+ check_id_in_object_data_data(data_id, result)
+ check_category_id_in_object_data_data(category_id, result)
+ return result
def delete_object_data(policy_id, category_id, data_id):
req = requests.delete(URL.format("/policies/{}/object_data/{}/{}".format(policy_id, category_id, data_id)),
headers=HEADERS)
- assert req.status_code == 200
+ req.raise_for_status()
req = requests.get(URL.format("/policies/{}/object_data/{}".format(policy_id, category_id)))
- assert req.status_code == 200
+ req.raise_for_status()
result = req.json()
- assert "object_data" in result
- for _data in result['object_data']:
- assert data_id not in list(_data['data'].keys())
- assert category_id == _data["category_id"]
+ check_id_not_in_object_data_data(data_id, result)
+ check_category_id_in_object_data_data(category_id, result)
def add_action_data(policy_id, category_id, name="action_data1"):
action_data_template['name'] = name
req = requests.post(URL.format("/policies/{}/action_data/{}".format(policy_id, category_id)),
json=action_data_template, headers=HEADERS)
- assert req.status_code == 200
+ req.raise_for_status()
result = req.json()
- assert "action_data" in result
+ check_action_data_data(result)
action_id = list(result['action_data']['data'].keys())[0]
return action_id
def check_action_data(policy_id, data_id, category_id):
req = requests.get(URL.format("/policies/{}/action_data/{}".format(policy_id, category_id)))
- assert req.status_code == 200
+ req.raise_for_status()
result = req.json()
- assert "action_data" in result
- for _data in result['action_data']:
- assert data_id in list(_data['data'].keys())
- assert category_id == _data["category_id"]
-
+ print(result)
+ if data_id is not None:
+ check_id_in_action_data_data(data_id, result)
+ check_category_id_in_action_data_data(category_id, result)
+ return result
def delete_action_data(policy_id, category_id, data_id):
req = requests.delete(URL.format("/policies/{}/action_data/{}/{}".format(policy_id, category_id, data_id)),
headers=HEADERS)
- assert req.status_code == 200
+ req.raise_for_status()
req = requests.get(URL.format("/policies/{}/action_data/{}".format(policy_id, category_id)))
- assert req.status_code == 200
+ req.raise_for_status()
result = req.json()
- assert "action_data" in result
- for _data in result['action_data']:
- assert data_id not in list(_data['data'].keys())
- assert category_id == _data["category_id"]
+ check_id_not_in_action_data_data(data_id, result)
+ check_category_id_in_action_data_data(category_id, result)
def add_subject_assignments(policy_id, subject_id, subject_cat_id, subject_data_id):
@@ -435,58 +390,36 @@ def add_subject_assignments(policy_id, subject_id, subject_cat_id, subject_data_
"category_id": subject_cat_id,
"data_id": subject_data_id
}, headers=HEADERS)
- assert req.status_code == 200
+ req.raise_for_status()
result = req.json()
- assert "subject_assignments" in result
- assert result["subject_assignments"]
+ check_subject_assignment_in_result(result)
def check_subject_assignments(policy_id, subject_id, subject_cat_id, subject_data_id):
req = requests.get(URL.format("/policies/{}/subject_assignments/{}/{}/{}".format(
policy_id, subject_id, subject_cat_id, subject_data_id)))
- assert req.status_code == 200
+ req.raise_for_status()
result = req.json()
- assert "subject_assignments" in result
- assert result["subject_assignments"]
- for key in result["subject_assignments"]:
- assert "subject_id" in result["subject_assignments"][key]
- assert "category_id" in result["subject_assignments"][key]
- assert "assignments" in result["subject_assignments"][key]
- if result["subject_assignments"][key]['subject_id'] == subject_id and \
- result["subject_assignments"][key]["category_id"] == subject_cat_id:
- assert subject_data_id in result["subject_assignments"][key]["assignments"]
+ check_subject_assignment_in_result(result)
+ check_subject_assignements(subject_id, subject_cat_id, subject_data_id, result)
def check_object_assignments(policy_id, object_id, object_cat_id, object_data_id):
req = requests.get(URL.format("/policies/{}/object_assignments/{}/{}/{}".format(
policy_id, object_id, object_cat_id, object_data_id)))
- assert req.status_code == 200
+ req.raise_for_status()
result = req.json()
- assert "object_assignments" in result
- assert result["object_assignments"]
- for key in result["object_assignments"]:
- assert "object_id" in result["object_assignments"][key]
- assert "category_id" in result["object_assignments"][key]
- assert "assignments" in result["object_assignments"][key]
- if result["object_assignments"][key]['object_id'] == object_id and \
- result["object_assignments"][key]["category_id"] == object_cat_id:
- assert object_data_id in result["object_assignments"][key]["assignments"]
+ check_object_assignment_in_result(result)
+ check_object_assignements(object_id, object_cat_id, object_data_id, result)
def check_action_assignments(policy_id, action_id, action_cat_id, action_data_id):
req = requests.get(URL.format("/policies/{}/action_assignments/{}/{}/{}".format(
policy_id, action_id, action_cat_id, action_data_id)))
- assert req.status_code == 200
+ req.raise_for_status()
result = req.json()
- assert "action_assignments" in result
- assert result["action_assignments"]
- for key in result["action_assignments"]:
- assert "action_id" in result["action_assignments"][key]
- assert "category_id" in result["action_assignments"][key]
- assert "assignments" in result["action_assignments"][key]
- if result["action_assignments"][key]['action_id'] == action_id and \
- result["action_assignments"][key]["category_id"] == action_cat_id:
- assert action_data_id in result["action_assignments"][key]["assignments"]
+ check_action_assignment_in_result(result)
+ check_action_assignements(action_id, action_cat_id, action_data_id, result)
def add_object_assignments(policy_id, object_id, object_cat_id, object_data_id):
@@ -496,10 +429,9 @@ def add_object_assignments(policy_id, object_id, object_cat_id, object_data_id):
"category_id": object_cat_id,
"data_id": object_data_id
}, headers=HEADERS)
- assert req.status_code == 200
+ req.raise_for_status()
result = req.json()
- assert "object_assignments" in result
- assert result["object_assignments"]
+ check_object_assignment_in_result(result)
def add_action_assignments(policy_id, action_id, action_cat_id, action_data_id):
@@ -509,79 +441,54 @@ def add_action_assignments(policy_id, action_id, action_cat_id, action_data_id):
"category_id": action_cat_id,
"data_id": action_data_id
}, headers=HEADERS)
- assert req.status_code == 200
+ req.raise_for_status()
result = req.json()
- assert "action_assignments" in result
- assert result["action_assignments"]
+ check_action_assignment_in_result(result)
def delete_subject_assignment(policy_id, subject_id, subject_cat_id, subject_data_id):
req = requests.delete(URL.format("/policies/{}/subject_assignments/{}/{}/{}".format(
policy_id, subject_id, subject_cat_id, subject_data_id)))
- assert req.status_code == 200
+ req.raise_for_status()
result = req.json()
- assert "result" in result
- assert result["result"]
+ check_result(result)
req = requests.get(URL.format("/policies/{}/subject_assignments/{}/{}/{}".format(
policy_id, subject_id, subject_cat_id, subject_data_id)))
- assert req.status_code == 200
+ req.raise_for_status()
result = req.json()
- assert "subject_assignments" in result
- assert result["subject_assignments"]
- for key in result["subject_assignments"]:
- assert "subject_id" in result["subject_assignments"][key]
- assert "category_id" in result["subject_assignments"][key]
- assert "assignments" in result["subject_assignments"][key]
- if result["subject_assignments"][key]['subject_id'] == subject_id and \
- result["subject_assignments"][key]["category_id"] == subject_cat_id:
- assert subject_data_id not in result["subject_assignments"][key]["assignments"]
+ check_subject_assignment_in_result(result)
+ check_not_subject_assignements(subject_id, subject_cat_id, subject_data_id, result)
def delete_object_assignment(policy_id, object_id, object_cat_id, object_data_id):
req = requests.delete(URL.format("/policies/{}/object_assignments/{}/{}/{}".format(
policy_id, object_id, object_cat_id, object_data_id)))
- assert req.status_code == 200
+ req.raise_for_status()
result = req.json()
- assert "result" in result
- assert result["result"]
+ check_result(result)
req = requests.get(URL.format("/policies/{}/object_assignments/{}/{}/{}".format(
policy_id, object_id, object_cat_id, object_data_id)))
- assert req.status_code == 200
+ req.raise_for_status()
result = req.json()
- assert "object_assignments" in result
- assert result["object_assignments"]
- for key in result["object_assignments"]:
- assert "object_id" in result["object_assignments"][key]
- assert "category_id" in result["object_assignments"][key]
- assert "assignments" in result["object_assignments"][key]
- if result["object_assignments"][key]['object_id'] == object_id and \
- result["object_assignments"][key]["category_id"] == object_cat_id:
- assert object_data_id not in result["object_assignments"][key]["assignments"]
+ check_object_assignment_in_result(result)
+ check_not_object_assignements(object_id, object_cat_id, object_data_id, result)
def delete_action_assignment(policy_id, action_id, action_cat_id, action_data_id):
req = requests.delete(URL.format("/policies/{}/action_assignments/{}/{}/{}".format(
policy_id, action_id, action_cat_id, action_data_id)))
- assert req.status_code == 200
+ req.raise_for_status()
result = req.json()
- assert "result" in result
- assert result["result"]
+ check_result(result)
req = requests.get(URL.format("/policies/{}/action_assignments/{}/{}/{}".format(
policy_id, action_id, action_cat_id, action_data_id)))
- assert req.status_code == 200
+ req.raise_for_status()
result = req.json()
- assert "action_assignments" in result
- assert result["action_assignments"]
- for key in result["action_assignments"]:
- assert "action_id" in result["action_assignments"][key]
- assert "category_id" in result["action_assignments"][key]
- assert "assignments" in result["action_assignments"][key]
- if result["action_assignments"][key]['action_id'] == action_id and \
- result["action_assignments"][key]["category_id"] == action_cat_id:
- assert action_data_id not in result["action_assignments"][key]["assignments"]
+ check_action_assignment_in_result(result)
+ check_not_action_assignements(action_id, action_cat_id, action_data_id, result)
def add_rule(policy_id, meta_rule_id, rule, instructions={"chain": [{"security_pipeline": "rbac"}]}):
@@ -593,55 +500,45 @@ def add_rule(policy_id, meta_rule_id, rule, instructions={"chain": [{"security_p
"enabled": True
},
headers=HEADERS)
- assert req.status_code == 200
- result = req.json()
- assert "rules" in result
- try:
- rule_id = list(result["rules"].keys())[0]
- except Exception as e:
- return False
- assert "policy_id" in result["rules"][rule_id]
- assert policy_id == result["rules"][rule_id]["policy_id"]
- assert "meta_rule_id" in result["rules"][rule_id]
- assert meta_rule_id == result["rules"][rule_id]["meta_rule_id"]
- assert rule == result["rules"][rule_id]["rule"]
+ req.raise_for_status()
+ result = req.json()
+ check_rule_in_result(result)
+ rule_id = list(result["rules"].keys())[0]
+ check_policy_id_in_dict(policy_id, result["rules"][rule_id])
+ check_meta_rule_id_in_dict(meta_rule_id, result["rules"][rule_id])
+ check_rule_in_dict(rule, result["rules"][rule_id])
return rule_id
def check_rule(policy_id, meta_rule_id, rule_id, rule):
req = requests.get(URL.format("/policies/{}/rules".format(policy_id)))
- assert req.status_code == 200
+ req.raise_for_status()
result = req.json()
- assert "rules" in result
- assert "policy_id" in result["rules"]
- assert policy_id == result["rules"]["policy_id"]
- for item in result["rules"]["rules"]:
- assert "meta_rule_id" in item
- if meta_rule_id == item["meta_rule_id"]:
- if rule_id == item["id"]:
- assert rule == item["rule"]
+ check_rule_in_result(result)
+ check_policy_id_in_dict(policy_id, result["rules"])
+ check_rule_id_in_list(meta_rule_id, rule_id, rule, result["rules"]["rules"])
def delete_rule(policy_id, rule_id):
req = requests.delete(URL.format("/policies/{}/rules/{}".format(policy_id, rule_id)))
- assert req.status_code == 200
+ req.raise_for_status()
result = req.json()
- assert "result" in result
- assert result["result"]
-
+ check_result(result)
req = requests.get(URL.format("/policies/{}/rules".format(policy_id)))
- assert req.status_code == 200
+ req.raise_for_status()
result = req.json()
- assert "rules" in result
- assert "policy_id" in result["rules"]
- assert policy_id == result["rules"]["policy_id"]
- found_rule = False
- for item in result["rules"]["rules"]:
- if rule_id == item["id"]:
- found_rule = True
- assert not found_rule
+ check_rule_in_result(result)
+ check_policy_id_in_dict(policy_id, result["rules"])
+ check_rule_id_not_in_list(rule_id, result["rules"]["rules"])
+def check_meta_rule():
+ req = requests.get(URL.format("/meta_rules/"))
+ req.raise_for_status()
+ result = req.json()
+ print(result)
+ return result
+
def create_policy(scenario, model_id, meta_rule_list):
logger.info("Creating policy {}".format(scenario.policy_name))
_policies = check_policy()
diff --git a/python_moonclient/python_moonclient/slaves.py b/python_moonclient/python_moonclient/core/slaves.py
index 3554341d..112b56f3 100644
--- a/python_moonclient/python_moonclient/slaves.py
+++ b/python_moonclient/python_moonclient/core/slaves.py
@@ -1,9 +1,9 @@
import logging
import requests
-import copy
-from . import config
+from python_moonclient.core import config
+from python_moonclient.core.check_tools import *
-logger = logging.getLogger("moonclient.slaves")
+logger = logging.getLogger("moonclient.core.slaves")
URL = None
@@ -20,19 +20,19 @@ def init(consul_host, consul_port):
HEADERS = {"content-type": "application/json"}
+
+
def get_slaves():
req = requests.get(URL.format("/slaves"))
- assert req.status_code == 200
+ req.raise_for_status()
result = req.json()
- assert type(result) is dict
- assert "slaves" in result
+ check_slaves_in_result(result)
return result
def set_slave(name):
slaves = get_slaves().get("slaves", [])
- names = map(lambda x: x['name'], slaves)
- assert name in names
+ check_name_in_slaves(name, slaves)
req = requests.patch(URL.format("/slaves/{}".format(name)),
headers=HEADERS,
json={
@@ -40,17 +40,15 @@ def set_slave(name):
"variable": "configured",
"value": True
})
- assert req.status_code == 200
+ req.raise_for_status()
result = req.json()
- assert type(result) is dict
- assert "slaves" in result
+ check_slaves_in_result(result)
return get_slaves()
def delete_slave(name):
slaves = get_slaves().get("slaves", [])
- names = map(lambda x: x['name'], slaves)
- assert name in names
+ check_name_in_slaves(name, slaves)
req = requests.patch(URL.format("/slaves/{}".format(name)),
headers=HEADERS,
json={
@@ -58,4 +56,7 @@ def delete_slave(name):
"variable": "configured",
"value": False
})
+ req.raise_for_status()
+ result = req.json()
+ check_slaves_in_result(result)
return get_slaves()
diff --git a/python_moonclient/python_moonclient/moon.py b/python_moonclient/python_moonclient/moon.py
new file mode 100644
index 00000000..f8cf027d
--- /dev/null
+++ b/python_moonclient/python_moonclient/moon.py
@@ -0,0 +1,41 @@
+import sys
+import python_moonclient
+
+from cliff.app import App
+from cliff.commandmanager import CommandManager
+
+
+class Moon(App):
+
+ def __init__(self):
+ super(Moon, self).__init__(
+ description='Moon client',
+ version=python_moonclient.__version__,
+ command_manager=CommandManager('moon'),
+ deferred_help=True,
+ )
+
+
+def main(argv=sys.argv[1:]):
+ myapp = Moon()
+ return myapp.run(argv)
+
+
+if __name__ == '__main__':
+ #import python_moonclient.python_moonclient.core.import_json
+ #import python_moonclient.python_moonclient.core.models
+ #import python_moonclient.core.policies.init as init_policy
+ #import python_moonclient.core.pdp.init as init_pdp
+ #consul_host = "consul"
+ #consul_port = "8005"
+
+ #init_model(consul_host, consul_port)
+ #init_policy.init(consul_host, consul_port)
+ #init_pdp.init(consul_host, consul_port)
+ #import_json('/home/fcellier/moon/tests/functional/scenario_available/rbac.json')
+
+
+ sys.exit(Moon(sys.argv[1:]))
+
+
+
diff --git a/python_moonclient/python_moonclient/parse.py b/python_moonclient/python_moonclient/parse.py
deleted file mode 100644
index d31b3ebd..00000000
--- a/python_moonclient/python_moonclient/parse.py
+++ /dev/null
@@ -1,81 +0,0 @@
-import logging
-import argparse
-
-
-logger = logging.getLogger("python_moonclient.parse")
-
-
-def parse():
- requests_log = logging.getLogger("requests.packages.urllib3")
- requests_log.setLevel(logging.WARNING)
- requests_log.propagate = True
-
- parser = argparse.ArgumentParser()
- parser.add_argument('filename', help='scenario filename', nargs="*")
- parser.add_argument("--verbose", "-v", action='store_true',
- help="verbose mode")
- parser.add_argument("--debug", "-d", action='store_true',
- help="debug mode")
- parser.add_argument("--dry-run", "-n", action='store_true',
- help="Dry run", dest="dry_run")
- parser.add_argument("--destination",
- help="Set the type of output needed "
- "(default: wrapper, other possible type: "
- "interface).",
- default="wrapper")
- parser.add_argument("--consul-host",
- help="Set the name of the consul server"
- "(default: 127.0.0.1).",
- default="127.0.0.1")
- parser.add_argument("--consul-port",
- help="Set the port of the consult server"
- "(default: 30005).",
- default="30005")
- parser.add_argument("--authz-host",
- help="Set the name of the authz server to test"
- "(default: 127.0.0.1).",
- default="127.0.0.1")
- parser.add_argument("--authz-port",
- help="Set the port of the authz server to test"
- "(default: 31002).",
- default="31002")
- parser.add_argument("--keystone-pid", "--keystone-project-id",
- help="Set the Keystone project ID"
- "(default: None).",
- default=None)
- parser.add_argument("--stress-test", "-s", action='store_true',
- dest='stress_test',
- help="Execute stressing tests (warning delta measures "
- "will be false, implies -t)")
- parser.add_argument("--write", "-w", help="Write test data to a JSON file",
- default="/tmp/data.json")
- parser.add_argument("--pdp", help="Test on pdp PDP")
- parser.add_argument("--request-per-second",
- help="Number of requests per seconds",
- type=int, dest="request_second", default=-1)
- parser.add_argument("--limit", help="Limit request to LIMIT", type=int,
- default=500)
-
- args = parser.parse_args()
-
- FORMAT = '%(asctime)-15s %(levelname)s %(message)s'
- if args.debug:
- logging.basicConfig(
- format=FORMAT,
- level=logging.DEBUG)
- elif args.verbose:
- logging.basicConfig(
- format=FORMAT,
- level=logging.INFO)
- else:
- logging.basicConfig(
- format=FORMAT,
- level=logging.WARNING)
-
- if args.stress_test:
- args.testonly = True
-
- if args.filename:
- logger.info("Loading: {}".format(args.filename[0]))
-
- return args
diff --git a/python_moonclient/python_moonclient/scripts.py b/python_moonclient/python_moonclient/scripts.py
deleted file mode 100644
index 74ed47fc..00000000
--- a/python_moonclient/python_moonclient/scripts.py
+++ /dev/null
@@ -1,235 +0,0 @@
-import logging
-from importlib.machinery import SourceFileLoader
-from . import parse, models, policies, pdp, authz, slaves
-
-
-logger = logging.getLogger("moonclient.scripts")
-
-
-def get_keystone_projects():
- args = parse.parse()
- consul_host = args.consul_host
- consul_port = args.consul_port
-
- models.init(consul_host, consul_port)
- policies.init(consul_host, consul_port)
- pdp.init(consul_host, consul_port)
-
- projects = pdp.get_keystone_projects()
-
- for _project in projects['projects']:
- print(" {} {}".format(_project['id'], _project['name']))
-
-
-def create_pdp():
- requests_log = logging.getLogger("requests.packages.urllib3")
- requests_log.setLevel(logging.WARNING)
- requests_log.propagate = True
-
- args = parse.parse()
- consul_host = args.consul_host
- consul_port = args.consul_port
- # project_id = args.keystone_pid
-
- models.init(consul_host, consul_port)
- policies.init(consul_host, consul_port)
- pdp.init(consul_host, consul_port)
-
- if args.filename:
- logger.info("Loading: {}".format(args.filename[0]))
- m = SourceFileLoader("scenario", args.filename[0])
- scenario = m.load_module()
-
- _models = models.check_model()
- for _model_id, _model_value in _models['models'].items():
- if _model_value['name'] == scenario.model_name:
- model_id = _model_id
- meta_rule_list = _model_value['meta_rules']
- models.create_model(scenario, model_id)
- break
- else:
- model_id, meta_rule_list = models.create_model(scenario)
- policy_id = policies.create_policy(scenario, model_id, meta_rule_list)
- pdp_id = pdp.create_pdp(scenario, policy_id=policy_id)
-
-
-def send_authz_to_wrapper():
- args = parse.parse()
- consul_host = args.consul_host
- consul_port = args.consul_port
-
- models.init(consul_host, consul_port)
- policies.init(consul_host, consul_port)
- pdp.init(consul_host, consul_port)
-
- if args.filename:
- logger.info("Loading: {}".format(args.filename[0]))
- m = SourceFileLoader("scenario", args.filename[0])
- scenario = m.load_module()
-
- keystone_project_id = pdp.get_keystone_id(args.pdp)
- time_data = authz.send_requests(
- scenario,
- args.authz_host,
- args.authz_port,
- keystone_project_id,
- request_second=args.request_second,
- limit=args.limit,
- dry_run=args.dry_run,
- stress_test=args.stress_test,
- destination=args.destination
- )
- if not args.dry_run:
- authz.save_data(args.write, time_data)
-
-
-def get_pdp():
- args = parse.parse()
- consul_host = args.consul_host
- consul_port = args.consul_port
-
- models.init(consul_host, consul_port)
- policies.init(consul_host, consul_port)
- pdp.init(consul_host, consul_port)
-
- pdps = pdp.check_pdp()
- for _pdp_key, _pdp_value in pdps["pdps"].items():
- print(" {} {} ({})".format(_pdp_key, _pdp_value['name'],
- _pdp_value['keystone_project_id']))
-
-
-def delete_pdp():
- args = parse.parse()
- consul_host = args.consul_host
- consul_port = args.consul_port
-
- models.init(consul_host, consul_port)
- policies.init(consul_host, consul_port)
- pdp.init(consul_host, consul_port)
-
- if args.filename:
- logger.info("Deleting: {}".format(args.filename[0]))
- _search = args.filename[0]
- pdps = pdp.check_pdp()
- for _pdp_key, _pdp_value in pdps["pdps"].items():
- if _pdp_key == _search or _pdp_value['name'] == _search:
- logger.info("Found {}".format(_pdp_key))
- pdp.delete_pdp(_pdp_key)
- pdps = pdp.check_pdp()
- logger.info("Listing all PDP:")
- for _pdp_key, _pdp_value in pdps["pdps"].items():
- print(" {} {}".format(_pdp_key, _pdp_value['name']))
- if _pdp_key == _search or _pdp_value['name'] == _search:
- logger.error("Error in deleting {}".format(_search))
-
-
-def delete_policy():
- args = parse.parse()
- consul_host = args.consul_host
- consul_port = args.consul_port
-
- models.init(consul_host, consul_port)
- policies.init(consul_host, consul_port)
- pdp.init(consul_host, consul_port)
-
- if args.filename:
- logger.info("Deleting: {}".format(args.filename[0]))
- _search = args.filename[0]
- _policies = policies.check_policy()
- for _policy_key, _policy_value in _policies["policies"].items():
- if _policy_key == _search or _policy_value['name'] == _search:
- logger.info("Found {}".format(_policy_key))
- pdp.delete_pdp(_policy_key)
- _policies = policies.check_policy()
- logger.info("Listing all Policies:")
- for _policy_key, _policy_value in _policies["policies"].items():
- print(" {} {}".format(_policy_key, _policy_value['name']))
- if _policy_key == _search or _policy_value['name'] == _search:
- logger.error("Error in deleting {}".format(_search))
-
-
-def map_pdp_to_project():
- args = parse.parse()
- consul_host = args.consul_host
- consul_port = args.consul_port
-
- models.init(consul_host, consul_port)
- policies.init(consul_host, consul_port)
- pdp.init(consul_host, consul_port)
-
- if args.filename and len(args.filename) == 2:
- logger.info("Mapping: {}=>{}".format(args.filename[0], args.filename[1]))
- # TODO: check if pdp_id and keystone_project_id exist
- pdp.map_to_keystone(pdp_id=args.filename[0], keystone_project_id=args.filename[1])
-
-
-def get_slaves():
- requests_log = logging.getLogger("requests.packages.urllib3")
- requests_log.setLevel(logging.WARNING)
- requests_log.propagate = True
-
- args = parse.parse()
- consul_host = args.consul_host
- consul_port = args.consul_port
-
- models.init(consul_host, consul_port)
- policies.init(consul_host, consul_port)
- pdp.init(consul_host, consul_port)
- slaves.init(consul_host, consul_port)
-
- for value in slaves.get_slaves().get('slaves', dict()):
- if value['configured']:
- print(" {} (configured)".format(value['name']))
- else:
- print(" {} (not configured)".format(value['name']))
-
-
-def set_slave():
- requests_log = logging.getLogger("requests.packages.urllib3")
- requests_log.setLevel(logging.WARNING)
- requests_log.propagate = True
-
- args = parse.parse()
- consul_host = args.consul_host
- consul_port = args.consul_port
-
- models.init(consul_host, consul_port)
- policies.init(consul_host, consul_port)
- pdp.init(consul_host, consul_port)
- slaves.init(consul_host, consul_port)
-
- slave_name = "kubernetes-admin@kubernetes"
- if args.filename:
- slave_name = args.filename
- for value in slaves.set_slave(slave_name).get('slaves', dict()):
- if value['configured']:
- print(" {} (configured)".format(value['name']))
- else:
- print(" {} (not configured)".format(value['name']))
-
-
-def delete_slave():
- requests_log = logging.getLogger("requests.packages.urllib3")
- requests_log.setLevel(logging.WARNING)
- requests_log.propagate = True
-
- args = parse.parse()
- consul_host = args.consul_host
- consul_port = args.consul_port
-
- models.init(consul_host, consul_port)
- policies.init(consul_host, consul_port)
- pdp.init(consul_host, consul_port)
- slaves.init(consul_host, consul_port)
-
- slave_name = "kubernetes-admin@kubernetes"
- if args.filename:
- slave_name = args.filename
- for value in slaves.delete_slave(slave_name).get('slaves', dict()):
- if value['configured']:
- print(" {} (configured)".format(value['name']))
- else:
- print(" {} (not configured)".format(value['name']))
-
-
-
diff --git a/python_moonclient/requirements.txt b/python_moonclient/requirements.txt
index 5b80e5f2..bbcd8cd5 100644
--- a/python_moonclient/requirements.txt
+++ b/python_moonclient/requirements.txt
@@ -1,3 +1,4 @@
werkzeug
flask
-requests \ No newline at end of file
+requests
+cliff
diff --git a/python_moonclient/setup.py b/python_moonclient/setup.py
index dcb90365..4a3a8233 100644
--- a/python_moonclient/setup.py
+++ b/python_moonclient/setup.py
@@ -5,6 +5,7 @@
from setuptools import setup, find_packages
import python_moonclient
+import python_moonclient.core
with open('requirements.txt') as f:
required = f.read().splitlines()
@@ -42,17 +43,33 @@ setup(
entry_points={
'console_scripts': [
- 'moon_get_keystone_projects = python_moonclient.scripts:get_keystone_projects',
- 'moon_get_pdp = python_moonclient.scripts:get_pdp',
- 'moon_create_pdp = python_moonclient.scripts:create_pdp',
- 'moon_delete_pdp = python_moonclient.scripts:delete_pdp',
- 'moon_delete_policy = python_moonclient.scripts:delete_policy',
- 'moon_map_pdp_to_project = python_moonclient.scripts:map_pdp_to_project',
- 'moon_send_authz_to_wrapper = python_moonclient.scripts:send_authz_to_wrapper',
- 'moon_get_slaves = python_moonclient.scripts:get_slaves',
- 'moon_set_slave = python_moonclient.scripts:set_slave',
- 'moon_delete_slave = python_moonclient.scripts:delete_slave'
+ 'moon = python_moonclient.moon:main'
],
+ 'moon': [
+ 'pdp_list = python_moonclient.cli.pdps:Pdps',
+ 'pdp_create = python_moonclient.cli.pdps:CreatePdp',
+ 'pdp_delete = python_moonclient.cli.pdps:DeletePdp',
+ 'pdp_map = python_moonclient.cli.pdps:MapPdp',
+ 'policy_list = python_moonclient.cli.policies:Policies',
+ 'policy_delete = python_moonclient.cli.policies:DeletePolicy',
+ 'project_list = python_moonclient.cli.projects:Projects',
+ 'slave_list = python_moonclient.cli.slaves:Slaves',
+ 'slave_set = python_moonclient.cli.slaves:SetSlave',
+ 'slave_delete = python_moonclient.cli.slaves:DeleteSlave',
+ 'authz_send = python_moonclient.cli.authz:SendAuthz',
+ 'import = python_moonclient.cli.import:Import',
+ 'export = python_moonclient.cli.export:Export',
+ 'model_list = python_moonclient.cli.models:Models',
+ 'subject_data_list = python_moonclient.cli.policies:SubjectDatas',
+ 'object_data_list = python_moonclient.cli.policies:ObjectDatas',
+ 'action_data_list = python_moonclient.cli.policies:ActionDatas',
+ 'subject_category_list = python_moonclient.cli.models:SubjectCategories',
+ 'object_category_list = python_moonclient.cli.models:ObjectCategories',
+ 'action_category_list = python_moonclient.cli.models:ActionCategories',
+ 'subject_category_create = python_moonclient.cli.models:SubjectCategoryAdd',
+ 'subject_data_create = python_moonclient.cli.policies:CreateSubjectData',
+ 'metarule_list = python_moonclient.cli.policies:MetaRules'
+ ],
}
)
diff --git a/python_moonclient/tests/unit_python/conf/conf_action_assignments.py b/python_moonclient/tests/unit_python/conf/conf_action_assignments.py
new file mode 100644
index 00000000..43c4db59
--- /dev/null
+++ b/python_moonclient/tests/unit_python/conf/conf_action_assignments.py
@@ -0,0 +1,51 @@
+from .conf_all import *
+
+POST_ACTION_ASSIGNMENT = {
+ "action_assignments":{
+ "1":{
+ "policy_id": "1",
+ "action_id": "2",
+ "category_id": "1",
+ "assignments": ["1"]
+ }
+ }
+}
+
+POST_OTHER_ACTION_ASSIGNMENT = {
+ "action_assignments":{
+ "2":{
+ "policy_id": "1",
+ "action_id": "2",
+ "category_id": "1",
+ "assignments": ["2"]
+ }
+ }
+}
+
+DELETE_ACTION_ASSIGNMENT = {
+ "action_assignments":{
+
+ }
+}
+
+
+def conf_action_assignments(m):
+ m.register_uri(
+ 'GET', 'http://manager:30001/policies/2/action_assignments/2/1/1',
+ [{'headers': {'X-Subject-Token': "111111111"}, 'json': POST_ACTION_ASSIGNMENT},
+ {'headers': {'X-Subject-Token': "111111111"}, 'json': DELETE_ACTION_ASSIGNMENT}]
+ )
+ m.register_uri(
+ 'GET', 'http://manager:30001/policies/2/action_assignments/2/1/2',
+ headers={'X-Subject-Token': "111111111"},
+ json=POST_OTHER_ACTION_ASSIGNMENT
+ )
+ m.register_uri(
+ 'POST', 'http://manager:30001/policies/2/action_assignments',
+ headers={'X-Subject-Token': "111111111"},
+ json=POST_ACTION_ASSIGNMENT
+ )
+ m.register_uri(
+ 'DELETE', 'http://manager:30001/policies/2/action_assignments/2/1/1',
+ json=RESULT_OK
+ ) \ No newline at end of file
diff --git a/python_moonclient/tests/unit_python/conf/conf_action_categories.py b/python_moonclient/tests/unit_python/conf/conf_action_categories.py
new file mode 100644
index 00000000..909befb2
--- /dev/null
+++ b/python_moonclient/tests/unit_python/conf/conf_action_categories.py
@@ -0,0 +1,32 @@
+
+
+ACTION_CATEGORIES = {
+ "action_categories": {
+ "1": {
+ "name": "action_cat_1",
+ "description": "description of the category"
+ }
+ }
+}
+
+POST_ACTION_CATEGORIES = {
+ "action_categories": {
+ "1": {
+ "name": "action_cat_1",
+ "description": "description of the category"
+ }
+ }
+}
+
+
+def conf_action_categories(m):
+ m.register_uri(
+ 'GET', 'http://manager:30001/action_categories',
+ headers={'X-Subject-Token': "111111111"},
+ json=ACTION_CATEGORIES
+ )
+ m.register_uri(
+ 'POST', 'http://manager:30001/action_categories',
+ headers={'X-Subject-Token': "111111111"},
+ json=POST_ACTION_CATEGORIES
+ ) \ No newline at end of file
diff --git a/python_moonclient/tests/unit_python/conf/conf_action_data.py b/python_moonclient/tests/unit_python/conf/conf_action_data.py
new file mode 100644
index 00000000..fb6f501c
--- /dev/null
+++ b/python_moonclient/tests/unit_python/conf/conf_action_data.py
@@ -0,0 +1,66 @@
+from .conf_all import *
+
+ACTION_DATA = {
+ "action_data":[{
+ "policy_id": "1",
+ "category_id": "1",
+ "data": {
+ "1": {
+ "name": "name of the data",
+ "description": "description of the data"
+ }
+ }
+ }]
+}
+
+POST_ACTION_DATA = {
+ "action_data":{
+ "policy_id": "1",
+ "category_id": "1",
+ "data": {
+ "1": {
+ "name": "name of the data",
+ "description": "description of the data"
+ }
+ }
+ }
+}
+
+POST_OTHER_ACTION_DATA = {
+ "action_data":{
+ "policy_id": "1",
+ "category_id": "1",
+ "data": {
+ "2": {
+ "name": "name of the data",
+ "description": "description of the data"
+ }
+ }
+ }
+}
+
+DELETE_ACTION_DATA= {
+ "action_data":[{
+ "policy_id": "1",
+ "category_id": "1",
+ "data":{}
+ }]
+}
+
+
+def conf_action_data(m):
+ m.register_uri(
+ 'POST', 'http://manager:30001/policies/2/action_data/1',
+ [{'headers': {'X-Subject-Token': "111111111"}, 'json': POST_ACTION_DATA},
+ {'headers': {'X-Subject-Token': "111111111"}, 'json': POST_OTHER_ACTION_DATA}]
+ )
+ m.register_uri(
+ 'GET', 'http://manager:30001/policies/2/action_data/1',
+ [{'headers': {'X-Subject-Token': "111111111"}, 'json': ACTION_DATA},
+ {'headers': {'X-Subject-Token': "111111111"}, 'json': DELETE_ACTION_DATA}]
+ )
+ m.register_uri(
+ 'DELETE', 'http://manager:30001/policies/2/action_data/1/1',
+ headers={'X-Subject-Token': "111111111"},
+ json=RESULT_OK
+ ) \ No newline at end of file
diff --git a/python_moonclient/tests/unit_python/conf/conf_actions.py b/python_moonclient/tests/unit_python/conf/conf_actions.py
new file mode 100644
index 00000000..4e6784dd
--- /dev/null
+++ b/python_moonclient/tests/unit_python/conf/conf_actions.py
@@ -0,0 +1,111 @@
+from .conf_all import *
+
+ACTIONS = {
+ "actions":{
+ "1": {
+ "name": "name of the action",
+ "keystone_id": "1",
+ "description": "a description",
+ "policy_list": ["1"]
+ }
+ }
+}
+
+ACTIONS_AFTER_POST = {
+ "actions":{
+ "1": {
+ "name": "name of the action",
+ "keystone_id": "1",
+ "description": "a description",
+ "policy_list": ["1"]
+ },
+ "2": {
+ "name": "test_action",
+ "keystone_id": "1",
+ "description": "a description",
+ "policy_list": []
+ }
+ }
+}
+
+ACTIONS_AFTER_PATCH = {
+ "actions":{
+ "1": {
+ "name": "name of the action",
+ "keystone_id": "1",
+ "description": "a description",
+ "policy_list": ["1"]
+ },
+ "2": {
+ "name": "test_action",
+ "keystone_id": "1",
+ "description": "a description",
+ "policy_list": ["2"]
+ }
+ }
+}
+
+
+POST_ACTIONS = {
+ "actions":{
+ "2": {
+ "name": "test_action",
+ "keystone_id": "1",
+ "description": "a description",
+ "policy_list": []
+ }
+ }
+}
+
+PATCH_ACTIONS = {
+ "actions":{
+ "2": {
+ "name": "test_action",
+ "keystone_id": "1",
+ "description": "a description",
+ "policy_list": ["2"]
+ }
+ }
+}
+
+def conf_actions(m):
+ m.register_uri(
+ 'GET', 'http://manager:30001/actions',
+ headers={'X-Subject-Token': "111111111"},
+ json=ACTIONS
+ )
+ m.register_uri(
+ 'POST', 'http://manager:30001/actions',
+ headers={'X-Subject-Token': "111111111"},
+ json=POST_ACTIONS
+ )
+ m.register_uri(
+ 'DELETE', 'http://manager:30001/actions/2',
+ headers={'X-Subject-Token': "111111111"},
+ json=RESULT_OK
+ )
+ m.register_uri(
+ 'PATCH', 'http://manager:30001/policies/2/actions/2',
+ headers={'X-Subject-Token': "111111111"},
+ json=PATCH_ACTIONS
+ )
+ m.register_uri(
+ 'GET', 'http://manager:30001/policies/2/actions',
+ headers={'X-Subject-Token': "111111111"},
+ json=ACTIONS_AFTER_PATCH
+ )
+ m.register_uri(
+ 'POST', 'http://manager:30001/policies/2/actions',
+ headers={'X-Subject-Token': "111111111"},
+ json=POST_ACTIONS
+ )
+ m.register_uri(
+ 'GET', 'http://manager:30001/policies/2/actions/2',
+ headers={'X-Subject-Token': "111111111"},
+ json=PATCH_ACTIONS
+ )
+ m.register_uri(
+ 'DELETE', 'http://manager:30001/policies/2/actions/2',
+ headers={'X-Subject-Token': "111111111"},
+ json=RESULT_OK
+ ) \ No newline at end of file
diff --git a/python_moonclient/tests/unit_python/conf/conf_all.py b/python_moonclient/tests/unit_python/conf/conf_all.py
new file mode 100644
index 00000000..b87d4fe7
--- /dev/null
+++ b/python_moonclient/tests/unit_python/conf/conf_all.py
@@ -0,0 +1 @@
+RESULT_OK = {"result": "OK"}
diff --git a/python_moonclient/tests/unit_python/conf/conf_meta_rules.py b/python_moonclient/tests/unit_python/conf/conf_meta_rules.py
new file mode 100644
index 00000000..67c14ddf
--- /dev/null
+++ b/python_moonclient/tests/unit_python/conf/conf_meta_rules.py
@@ -0,0 +1,44 @@
+from .conf_all import *
+
+
+META_RULES = {
+ "meta_rules": {
+ "1": {
+ "name": "test_meta_rule",
+ "algorithm": "name of the meta rule algorithm",
+ "subject_categories": ["1"],
+ "object_categories": ["1"],
+ "action_categories": ["1"]
+ }
+ }
+}
+
+POST_META_RULES = {
+ "meta_rules": {
+ "1": {
+ "name": "test_meta_rule",
+ "algorithm": "name of the meta rule algorithm",
+ "subject_categories": ["1"],
+ "object_categories": ["1"],
+ "action_categories": ["1"]
+ }
+ }
+}
+
+
+def conf_meta_rules(m):
+ m.register_uri(
+ 'GET', 'http://manager:30001/meta_rules',
+ headers={'X-Subject-Token': "111111111"},
+ json=META_RULES
+ )
+ m.register_uri(
+ 'POST', 'http://manager:30001/meta_rules',
+ headers={'X-Subject-Token': "111111111"},
+ json=POST_META_RULES
+ )
+ m.register_uri(
+ 'DELETE', 'http://manager:30001/meta_rules/1',
+ headers={'X-Subject-Token': "111111111"},
+ json=RESULT_OK
+ )
diff --git a/python_moonclient/tests/unit_python/conf/conf_models.py b/python_moonclient/tests/unit_python/conf/conf_models.py
new file mode 100644
index 00000000..930af88f
--- /dev/null
+++ b/python_moonclient/tests/unit_python/conf/conf_models.py
@@ -0,0 +1,94 @@
+from .conf_all import *
+
+
+MODELS = {
+ "models": {
+ "1": {
+ "name": "model 1",
+ "description": "description model 1",
+ "meta_rules": [{
+ "meta_rule_id": "1"
+ }, {
+ "meta_rule_id": "2"
+ }]
+ },
+ "2": {
+ "name": "model 2",
+ "description": "description model 2",
+ "meta_rules": ["2"]
+ },
+ "3": {
+ "name": "test_model",
+ "description": "description model 3",
+ "meta_rules": ["2"]
+ }
+ }
+}
+
+POST_MODEL = {
+ "models": {
+ "3": {
+ "name": "test_model",
+ "description": "description model 3",
+ "meta_rules": ["2"]
+ }
+ }
+}
+
+PATCH_MODEL = {
+ "models": {
+ "3": {
+ "name": "test_model",
+ "description": "description model 3",
+ "meta_rules": ["2", "1"]
+ }
+ }
+}
+
+
+MODELS_AFTER_POST = {
+"models": {
+ "1": {
+ "name": "model 1",
+ "description": "description model 1",
+ "meta_rules": [{
+ "meta_rule_id": "1"
+ }, {
+ "meta_rule_id": "2"
+ }]
+ },
+ "2": {
+ "name": "model 2",
+ "description": "description model 2",
+ "meta_rules": ["2"]
+ },
+ "3": {
+ "name": "test_model",
+ "description": "description model 3",
+ "meta_rules": ["1", "2"]
+ }
+ }
+}
+
+
+def conf_models(m):
+ m.register_uri(
+ 'GET', 'http://manager:30001/models',
+ [{'json': MODELS, 'headers': {'X-Subject-Token': "111111111"}},
+ {'json': MODELS_AFTER_POST, 'headers': {'X-Subject-Token': "111111111"}}]
+ )
+ m.register_uri(
+ 'POST', 'http://manager:30001/models',
+ headers={'X-Subject-Token': "111111111"},
+ json=POST_MODEL
+ )
+ m.register_uri(
+ 'PATCH', 'http://manager:30001/models/3',
+ headers={'X-Subject-Token': "111111111"},
+ json=PATCH_MODEL
+ )
+ m.register_uri(
+ 'DELETE', 'http://manager:30001/models/3',
+ headers={'X-Subject-Token': "111111111"},
+ json=RESULT_OK
+ ) \ No newline at end of file
diff --git a/python_moonclient/tests/unit_python/conf/conf_object_assignments.py b/python_moonclient/tests/unit_python/conf/conf_object_assignments.py
new file mode 100644
index 00000000..9e88e03e
--- /dev/null
+++ b/python_moonclient/tests/unit_python/conf/conf_object_assignments.py
@@ -0,0 +1,51 @@
+from .conf_all import *
+
+POST_OBJECT_ASSIGNMENT = {
+ "object_assignments":{
+ "1":{
+ "policy_id": "1",
+ "object_id": "2",
+ "category_id": "1",
+ "assignments": ["1"]
+ }
+ }
+}
+
+POST_OTHER_OBJECT_ASSIGNMENT = {
+ "object_assignments":{
+ "2":{
+ "policy_id": "1",
+ "object_id": "2",
+ "category_id": "1",
+ "assignments": ["2"]
+ }
+ }
+}
+
+DELETE_OBJECT_ASSIGNMENT = {
+ "object_assignments":{
+
+ }
+}
+
+
+def conf_object_assignments(m):
+ m.register_uri(
+ 'GET', 'http://manager:30001/policies/2/object_assignments/2/1/1',
+ [{'headers': {'X-Subject-Token': "111111111"}, 'json': POST_OBJECT_ASSIGNMENT},
+ {'headers': {'X-Subject-Token': "111111111"}, 'json': DELETE_OBJECT_ASSIGNMENT}]
+ )
+ m.register_uri(
+ 'GET', 'http://manager:30001/policies/2/object_assignments/2/1/2',
+ headers={'X-Subject-Token': "111111111"},
+ json=POST_OTHER_OBJECT_ASSIGNMENT
+ )
+ m.register_uri(
+ 'POST', 'http://manager:30001/policies/2/object_assignments',
+ headers={'X-Subject-Token': "111111111"},
+ json=POST_OBJECT_ASSIGNMENT
+ )
+ m.register_uri(
+ 'DELETE', 'http://manager:30001/policies/2/object_assignments/2/1/1',
+ json=RESULT_OK
+ ) \ No newline at end of file
diff --git a/python_moonclient/tests/unit_python/conf/conf_object_categories.py b/python_moonclient/tests/unit_python/conf/conf_object_categories.py
new file mode 100644
index 00000000..a942f9c6
--- /dev/null
+++ b/python_moonclient/tests/unit_python/conf/conf_object_categories.py
@@ -0,0 +1,31 @@
+
+OBJECT_CATEGORIES = {
+ "object_categories": {
+ "1": {
+ "name": "object_cat_1",
+ "description": "description of the category"
+ }
+ }
+}
+
+POST_OBJECT_CATEGORIES = {
+ "object_categories": {
+ "1": {
+ "name": "object_cat_1",
+ "description": "description of the category"
+ }
+ }
+}
+
+
+def conf_object_categories(m):
+ m.register_uri(
+ 'GET', 'http://manager:30001/object_categories',
+ headers={'X-Subject-Token': "111111111"},
+ json=OBJECT_CATEGORIES
+ )
+ m.register_uri(
+ 'POST', 'http://manager:30001/object_categories',
+ headers={'X-Subject-Token': "111111111"},
+ json=POST_OBJECT_CATEGORIES
+ )
diff --git a/python_moonclient/tests/unit_python/conf/conf_object_data.py b/python_moonclient/tests/unit_python/conf/conf_object_data.py
new file mode 100644
index 00000000..8fa81d69
--- /dev/null
+++ b/python_moonclient/tests/unit_python/conf/conf_object_data.py
@@ -0,0 +1,67 @@
+
+from .conf_all import *
+
+OBJECT_DATA = {
+ "object_data":[{
+ "policy_id": "1",
+ "category_id": "1",
+ "data": {
+ "1": {
+ "name": "name of the data",
+ "description": "description of the data"
+ }
+ }
+ }]
+}
+
+POST_OBJECT_DATA = {
+ "object_data":{
+ "policy_id": "1",
+ "category_id": "1",
+ "data": {
+ "1": {
+ "name": "name of the data",
+ "description": "description of the data"
+ }
+ }
+ }
+}
+
+POST_OTHER_OBJECT_DATA = {
+ "object_data":{
+ "policy_id": "1",
+ "category_id": "1",
+ "data": {
+ "2": {
+ "name": "name of the data",
+ "description": "description of the data"
+ }
+ }
+ }
+}
+
+DELETE_OBJECT_DATA= {
+ "object_data":[{
+ "policy_id": "1",
+ "category_id": "1",
+ "data":{}
+ }]
+}
+
+
+def conf_object_data(m):
+ m.register_uri(
+ 'POST', 'http://manager:30001/policies/2/object_data/1',
+ [{'headers': {'X-Subject-Token': "111111111"}, 'json': POST_OBJECT_DATA},
+ {'headers': {'X-Subject-Token': "111111111"}, 'json': POST_OTHER_OBJECT_DATA}]
+ )
+ m.register_uri(
+ 'GET', 'http://manager:30001/policies/2/object_data/1',
+ [{'headers': {'X-Subject-Token': "111111111"}, 'json': OBJECT_DATA},
+ {'headers': {'X-Subject-Token': "111111111"}, 'json': DELETE_OBJECT_DATA}]
+ )
+ m.register_uri(
+ 'DELETE', 'http://manager:30001/policies/2/object_data/1/1',
+ headers={'X-Subject-Token': "111111111"},
+ json=RESULT_OK
+ )
diff --git a/python_moonclient/tests/unit_python/conf/conf_objects.py b/python_moonclient/tests/unit_python/conf/conf_objects.py
new file mode 100644
index 00000000..cf3e7aa4
--- /dev/null
+++ b/python_moonclient/tests/unit_python/conf/conf_objects.py
@@ -0,0 +1,112 @@
+from .conf_all import *
+
+OBJECTS = {
+ "objects":{
+ "1": {
+ "name": "name of the object",
+ "keystone_id": "1",
+ "description": "a description",
+ "policy_list": ["1"]
+ }
+ }
+}
+
+OBJECTS_AFTER_POST = {
+ "objects":{
+ "1": {
+ "name": "name of the object",
+ "keystone_id": "1",
+ "description": "a description",
+ "policy_list": ["1"]
+ },
+ "2": {
+ "name": "test_object",
+ "keystone_id": "1",
+ "description": "a description",
+ "policy_list": []
+ }
+ }
+}
+
+OBJECTS_AFTER_PATCH = {
+ "objects":{
+ "1": {
+ "name": "name of the object",
+ "keystone_id": "1",
+ "description": "a description",
+ "policy_list": ["1"]
+ },
+ "2": {
+ "name": "test_object",
+ "keystone_id": "1",
+ "description": "a description",
+ "policy_list": ["2"]
+ }
+ }
+}
+
+
+POST_OBJECTS = {
+ "objects":{
+ "2": {
+ "name": "test_object",
+ "keystone_id": "1",
+ "description": "a description",
+ "policy_list": []
+ }
+ }
+}
+
+PATCH_OBJECTS = {
+ "objects":{
+ "2": {
+ "name": "test_object",
+ "keystone_id": "1",
+ "description": "a description",
+ "policy_list": ["2"]
+ }
+ }
+}
+
+def conf_objects(m):
+ m.register_uri(
+ 'GET', 'http://manager:30001/objects',
+ [{'json': OBJECTS, 'headers': {'X-Subject-Token': "111111111"}},
+ {'json': OBJECTS_AFTER_POST, 'headers': {'X-Subject-Token': "111111111"}},
+ {'json': OBJECTS, 'headers': {'X-Subject-Token': "111111111"}}]
+ )
+ m.register_uri(
+ 'POST', 'http://manager:30001/objects',
+ headers={'X-Subject-Token': "111111111"},
+ json=POST_OBJECTS
+ )
+ m.register_uri(
+ 'DELETE', 'http://manager:30001/objects/2',
+ headers={'X-Subject-Token': "111111111"},
+ json=RESULT_OK
+ )
+ m.register_uri(
+ 'PATCH', 'http://manager:30001/policies/2/objects/2',
+ headers={'X-Subject-Token': "111111111"},
+ json=PATCH_OBJECTS
+ )
+ m.register_uri(
+ 'GET', 'http://manager:30001/policies/2/objects',
+ headers={'X-Subject-Token': "111111111"},
+ json=OBJECTS_AFTER_PATCH
+ )
+ m.register_uri(
+ 'POST', 'http://manager:30001/policies/2/objects',
+ headers={'X-Subject-Token': "111111111"},
+ json=POST_OBJECTS
+ )
+ m.register_uri(
+ 'GET', 'http://manager:30001/policies/2/objects/2',
+ headers={'X-Subject-Token': "111111111"},
+ json=PATCH_OBJECTS
+ )
+ m.register_uri(
+ 'DELETE', 'http://manager:30001/policies/2/objects/2',
+ headers={'X-Subject-Token': "111111111"},
+ json=RESULT_OK
+ )
diff --git a/python_moonclient/tests/unit_python/conf/conf_pdps.py b/python_moonclient/tests/unit_python/conf/conf_pdps.py
new file mode 100644
index 00000000..1090fccb
--- /dev/null
+++ b/python_moonclient/tests/unit_python/conf/conf_pdps.py
@@ -0,0 +1,95 @@
+from .conf_all import *
+
+PDPS = {
+ "pdps": {
+ "1": {
+ "name": "...",
+ "security_pipeline": [],
+ "keystone_project_id": "",
+ "description": "...",
+ }
+ }
+ }
+
+
+POST_PDP = {
+ "pdps": {
+ "2": {
+ "name": "test_pdp",
+ "security_pipeline": [],
+ "keystone_project_id": "",
+ "description": "..."
+ }
+ }
+ }
+
+PATCH_PDP = {
+ "pdps": {
+ "2": {
+ "name": "test_pdp",
+ "security_pipeline": [],
+ "keystone_project_id": "0c4e939acacf4376bdcd1129f1a054ad",
+ "description": "..."
+ }
+ }
+ }
+
+PDPS_AFTER_POST = {
+ "pdps": {
+ "1": {
+ "name": "...",
+ "security_pipeline": [],
+ "keystone_project_id": "",
+ "description": "...",
+ },
+
+ "2": {
+ "name": "test_pdp",
+ "security_pipeline": [],
+ "keystone_project_id": "",
+ "description": "...",
+ }
+ }
+ }
+
+PDPS_AFTER_PATCH = {
+ "pdps": {
+ "1": {
+ "name": "...",
+ "security_pipeline": [],
+ "keystone_project_id": "",
+ "description": "...",
+ },
+
+ "2": {
+ "name": "test_pdp",
+ "security_pipeline": [],
+ "keystone_project_id": "0c4e939acacf4376bdcd1129f1a054ad",
+ "description": "...",
+ }
+ }
+ }
+
+def conf_pdps(m):
+ m.register_uri(
+ 'GET', 'http://manager:30001/pdp',
+ [{'json': PDPS, 'headers': {'X-Subject-Token': "111111111"}},
+ {'json': PDPS_AFTER_POST, 'headers': {'X-Subject-Token': "111111111"}},
+ {'json': PDPS_AFTER_PATCH, 'headers': {'X-Subject-Token': "111111111"}},
+ {'json': PDPS, 'headers': {'X-Subject-Token': "111111111"}}]
+ )
+ m.register_uri(
+ 'POST', 'http://manager:30001/pdp',
+ headers={'X-Subject-Token': "111111111"},
+ json=POST_PDP
+ )
+ m.register_uri(
+ 'PATCH', 'http://manager:30001/pdp/2',
+ headers={'X-Subject-Token': "111111111"},
+ json=PATCH_PDP
+ )
+ m.register_uri(
+ 'DELETE', 'http://manager:30001/pdp/2',
+ headers={'X-Subject-Token': "111111111"},
+ json=RESULT_OK
+ ) \ No newline at end of file
diff --git a/python_moonclient/tests/unit_python/conf/conf_policies.py b/python_moonclient/tests/unit_python/conf/conf_policies.py
new file mode 100644
index 00000000..bf6883bc
--- /dev/null
+++ b/python_moonclient/tests/unit_python/conf/conf_policies.py
@@ -0,0 +1,78 @@
+from .conf_all import *
+
+POLICIES = {
+ "policies":{
+ "1": {
+ "name": "test_policy",
+ "model_id": "1",
+ "genre": "authz",
+ "description": "Description of the policy",
+ }
+ }
+}
+
+POLICIES_AFTER_POST= {
+ "policies":{
+ "1": {
+ "name": "test_policy",
+ "model_id": "1",
+ "genre": "authz",
+ "description": "Description of the policy",
+ },
+ "2": {
+ "name": "test_policy",
+ "model_id": "",
+ "genre": "",
+ "description": "Description of the policy",
+ }
+ }
+}
+
+
+POST_POLICIES ={
+ "policies":{
+ "2": {
+ "name": "test_policy",
+ "model_id": "",
+ "genre": "",
+ "description": "Description of the policy",
+ }
+ }
+}
+
+
+PATCH_POLICIES ={
+ "policies":{
+ "2": {
+ "name": "test_policy",
+ "model_id": "3",
+ "genre": "authz",
+ "description": "Description of the policy",
+ }
+ }
+}
+
+
+def conf_policies(m):
+ m.register_uri(
+ 'GET', 'http://manager:30001/policies',
+ [{'json': POLICIES, 'headers': {'X-Subject-Token': "111111111"}},
+ {'json': POLICIES_AFTER_POST, 'headers': {'X-Subject-Token': "111111111"}},
+ {'json': POLICIES, 'headers': {'X-Subject-Token': "111111111"}}]
+
+ )
+ m.register_uri(
+ 'POST', 'http://manager:30001/policies',
+ headers={'X-Subject-Token': "111111111"},
+ json=POST_POLICIES
+ )
+ m.register_uri(
+ 'PATCH', 'http://manager:30001/policies/2',
+ headers={'X-Subject-Token': "111111111"},
+ json=PATCH_POLICIES
+ )
+ m.register_uri(
+ 'DELETE', 'http://manager:30001/policies/2',
+ headers={'X-Subject-Token': "111111111"},
+ json=RESULT_OK
+ ) \ No newline at end of file
diff --git a/python_moonclient/tests/unit_python/conf/conf_projects.py b/python_moonclient/tests/unit_python/conf/conf_projects.py
new file mode 100644
index 00000000..63be05e0
--- /dev/null
+++ b/python_moonclient/tests/unit_python/conf/conf_projects.py
@@ -0,0 +1,44 @@
+
+
+PROJECTS = {
+ "projects": [
+ {
+ "is_domain": False,
+ "description": None,
+ "domain_id": "admin",
+ "enabled": True,
+ "id": "0c4e939acacf4376bdcd1129f1a054ad",
+ "links": {
+ "self": "http://example.com/identity/v3/projects/0c4e939acacf4376bdcd1129f1a054ad"
+ },
+ "name": "admin",
+ "parent_id": None,
+ "tags": []
+ },
+ {
+ "is_domain": False,
+ "description": None,
+ "domain_id": "default",
+ "enabled": True,
+ "id": "0cbd49cbf76d405d9c86562e1d579bd3",
+ "links": {
+ "self": "http://example.com/identity/v3/projects/0cbd49cbf76d405d9c86562e1d579bd3"
+ },
+ "name": "demo",
+ "parent_id": None,
+ "tags": []
+ }
+ ]
+}
+
+
+def conf_projects(m):
+ m.register_uri(
+ 'GET', 'http://keystone:5000/v3/projects',
+ headers={'X-Subject-Token': "111111111"},
+ json=PROJECTS
+ )
+ m.register_uri(
+ 'POST', 'http://keystone:5000/v3/auth/tokens',
+ headers={'X-Subject-Token': "111111111"}
+ )
diff --git a/python_moonclient/tests/unit_python/conf/conf_rules.py b/python_moonclient/tests/unit_python/conf/conf_rules.py
new file mode 100644
index 00000000..30b8c682
--- /dev/null
+++ b/python_moonclient/tests/unit_python/conf/conf_rules.py
@@ -0,0 +1,46 @@
+from .conf_all import *
+
+RULES = {
+ "rules":{
+ "policy_id": "2",
+ "rules": [{
+ "meta_rule_id": "1",
+ "id": "1",
+ "rule": ["1", "1", "1"]
+ }]
+ }
+}
+
+POST_RULES = {
+ "rules":{
+ "1":{
+ "policy_id": "2",
+ "meta_rule_id": "1",
+ "rule": ["1", "1", "1"]
+ }
+ }
+}
+
+DELETE_RULES = {
+ "rules":{
+ "policy_id": "2",
+ "rules": []
+ }
+}
+
+
+def conf_rule_assignments(m):
+ m.register_uri(
+ 'GET', 'http://manager:30001/policies/2/rules',
+ [{'headers': {'X-Subject-Token': "111111111"}, 'json': RULES},
+ {'headers': {'X-Subject-Token': "111111111"}, 'json': DELETE_RULES}]
+ )
+ m.register_uri(
+ 'POST', 'http://manager:30001/policies/2/rules',
+ [{'headers': {'X-Subject-Token': "111111111"}, 'json': POST_RULES}]
+ )
+ m.register_uri(
+ 'DELETE', 'http://manager:30001/policies/2/rules/1',
+ headers={'X-Subject-Token': "111111111"},
+ json=RESULT_OK
+ ) \ No newline at end of file
diff --git a/python_moonclient/tests/unit_python/conf/conf_subject_assignments.py b/python_moonclient/tests/unit_python/conf/conf_subject_assignments.py
new file mode 100644
index 00000000..92b689c0
--- /dev/null
+++ b/python_moonclient/tests/unit_python/conf/conf_subject_assignments.py
@@ -0,0 +1,51 @@
+from .conf_all import *
+
+POST_SUBJECT_ASSIGNMENT = {
+ "subject_assignments":{
+ "1":{
+ "policy_id": "1",
+ "subject_id": "2",
+ "category_id": "1",
+ "assignments": ["1"]
+ }
+ }
+}
+
+DELETE_SUBJECT_ASSIGNMENT = {
+ "subject_assignments":{
+
+ }
+}
+
+POST_OTHER_SUBJECT_ASSIGNMENT = {
+ "subject_assignments":{
+ "2":{
+ "policy_id": "1",
+ "subject_id": "2",
+ "category_id": "1",
+ "assignments": ["2"]
+ }
+ }
+}
+
+
+def conf_subject_assignments(m):
+ m.register_uri(
+ 'GET', 'http://manager:30001/policies/2/subject_assignments/2/1/1',
+ [{'headers': {'X-Subject-Token': "111111111"}, 'json': POST_SUBJECT_ASSIGNMENT},
+ {'headers': {'X-Subject-Token': "111111111"}, 'json': DELETE_SUBJECT_ASSIGNMENT}]
+ )
+ m.register_uri(
+ 'GET', 'http://manager:30001/policies/2/subject_assignments/2/1/2',
+ headers={'X-Subject-Token': "111111111"},
+ json=POST_OTHER_SUBJECT_ASSIGNMENT
+ )
+ m.register_uri(
+ 'POST', 'http://manager:30001/policies/2/subject_assignments',
+ headers={'X-Subject-Token': "111111111"},
+ json=POST_SUBJECT_ASSIGNMENT
+ )
+ m.register_uri(
+ 'DELETE', 'http://manager:30001/policies/2/subject_assignments/2/1/1',
+ json=RESULT_OK
+ ) \ No newline at end of file
diff --git a/python_moonclient/tests/unit_python/conf/conf_subject_categories.py b/python_moonclient/tests/unit_python/conf/conf_subject_categories.py
new file mode 100644
index 00000000..e59a458a
--- /dev/null
+++ b/python_moonclient/tests/unit_python/conf/conf_subject_categories.py
@@ -0,0 +1,30 @@
+
+SUBJECT_CATEGORIES = {
+ "subject_categories": {
+ "1": {
+ "name": "subject_cat_1",
+ "description": "description of the category"
+ }
+ }
+}
+
+POST_SUBJECT_CATEGORIES = {
+ "subject_categories": {
+ "1": {
+ "name": "subject_cat_1",
+ "description": "description of the category"
+ }
+ }
+}
+
+def conf_subject_categories(m):
+ m.register_uri(
+ 'GET', 'http://manager:30001/subject_categories',
+ headers={'X-Subject-Token': "111111111"},
+ json=SUBJECT_CATEGORIES
+ )
+ m.register_uri(
+ 'POST', 'http://manager:30001/subject_categories',
+ headers={'X-Subject-Token': "111111111"},
+ json=POST_SUBJECT_CATEGORIES
+ )
diff --git a/python_moonclient/tests/unit_python/conf/conf_subject_data.py b/python_moonclient/tests/unit_python/conf/conf_subject_data.py
new file mode 100644
index 00000000..19db217d
--- /dev/null
+++ b/python_moonclient/tests/unit_python/conf/conf_subject_data.py
@@ -0,0 +1,67 @@
+from .conf_all import *
+
+SUBJECT_DATA = {
+ "subject_data":[{
+ "policy_id": "1",
+ "category_id": "1",
+ "data": {
+ "1": {
+ "name": "name of the data",
+ "description": "description of the data"
+ }
+ }
+ }]
+}
+
+POST_SUBJECT_DATA = {
+ "subject_data":{
+ "policy_id": "1",
+ "category_id": "1",
+ "data": {
+ "1": {
+ "name": "name of the data",
+ "description": "description of the data"
+ }
+ }
+ }
+}
+
+
+POST_OTHER_SUBJECT_DATA = {
+ "subject_data":{
+ "policy_id": "1",
+ "category_id": "1",
+ "data": {
+ "2": {
+ "name": "name of the data",
+ "description": "description of the data"
+ }
+ }
+ }
+}
+
+DELETE_SUBJECT_DATA= {
+ "subject_data":[{
+ "policy_id": "1",
+ "category_id": "1",
+ "data":{}
+ }]
+}
+
+
+def conf_subject_data(m):
+ m.register_uri(
+ 'POST', 'http://manager:30001/policies/2/subject_data/1',
+ [{'headers': {'X-Subject-Token': "111111111"}, 'json': POST_SUBJECT_DATA},
+ {'headers': {'X-Subject-Token': "111111111"}, 'json': POST_OTHER_SUBJECT_DATA}]
+ )
+ m.register_uri(
+ 'GET', 'http://manager:30001/policies/2/subject_data/1',
+ [{'headers': {'X-Subject-Token': "111111111"}, 'json': SUBJECT_DATA},
+ {'headers': {'X-Subject-Token': "111111111"}, 'json': DELETE_SUBJECT_DATA}]
+ )
+ m.register_uri(
+ 'DELETE', 'http://manager:30001/policies/2/subject_data/1/1',
+ headers={'X-Subject-Token': "111111111"},
+ json=RESULT_OK
+ ) \ No newline at end of file
diff --git a/python_moonclient/tests/unit_python/conf/conf_subjects.py b/python_moonclient/tests/unit_python/conf/conf_subjects.py
new file mode 100644
index 00000000..bde6093f
--- /dev/null
+++ b/python_moonclient/tests/unit_python/conf/conf_subjects.py
@@ -0,0 +1,112 @@
+from .conf_all import *
+
+SUBJECTS = {
+ "subjects":{
+ "1": {
+ "name": "name of the subject",
+ "keystone_id": "1",
+ "description": "a description",
+ "policy_list": ["1"]
+ }
+ }
+}
+
+SUBJECTS_AFTER_POST= {
+ "subjects":{
+ "1": {
+ "name": "name of the subject",
+ "keystone_id": "1",
+ "description": "a description",
+ "policy_list": ["1"]
+ },
+ "2": {
+ "name": "test_subject",
+ "keystone_id": "1",
+ "description": "a description",
+ "policy_list": []
+ }
+ }
+}
+
+SUBJECTS_AFTER_PATCH= {
+ "subjects":{
+ "1": {
+ "name": "name of the subject",
+ "keystone_id": "1",
+ "description": "a description",
+ "policy_list": ["1"]
+ },
+ "2": {
+ "name": "test_subject",
+ "keystone_id": "1",
+ "description": "a description",
+ "policy_list": ["2"]
+ }
+ }
+}
+
+POST_SUBJECTS = {
+ "subjects":{
+ "2": {
+ "name": "test_subject",
+ "keystone_id": "1",
+ "description": "a description",
+ "policy_list": []
+ }
+ }
+}
+
+
+PATCH_SUBJECTS = {
+ "subjects":{
+ "2": {
+ "name": "test_subject",
+ "keystone_id": "1",
+ "description": "a description",
+ "policy_list": ["2"]
+ }
+ }
+}
+
+def conf_subjects(m):
+ m.register_uri(
+ 'GET', 'http://manager:30001/subjects',
+ [{'json': SUBJECTS, 'headers': {'X-Subject-Token': "111111111"}},
+ {'json': SUBJECTS_AFTER_POST, 'headers': {'X-Subject-Token': "111111111"}},
+ {'json': SUBJECTS, 'headers': {'X-Subject-Token': "111111111"}}]
+ )
+ m.register_uri(
+ 'POST', 'http://manager:30001/subjects',
+ headers={'X-Subject-Token': "111111111"},
+ json=POST_SUBJECTS
+ )
+ m.register_uri(
+ 'DELETE', 'http://manager:30001/subjects/2',
+ headers={'X-Subject-Token': "111111111"},
+ json=RESULT_OK
+ )
+ m.register_uri(
+ 'PATCH', 'http://manager:30001/policies/2/subjects/2',
+ headers={'X-Subject-Token': "111111111"},
+ json=PATCH_SUBJECTS
+ )
+ m.register_uri(
+ 'GET', 'http://manager:30001/policies/2/subjects',
+ headers={'X-Subject-Token': "111111111"},
+ json=SUBJECTS_AFTER_PATCH
+ )
+ m.register_uri(
+ 'POST', 'http://manager:30001/policies/2/subjects',
+ headers={'X-Subject-Token': "111111111"},
+ json=POST_SUBJECTS
+ )
+ m.register_uri(
+ 'GET', 'http://manager:30001/policies/2/subjects/2',
+ headers={'X-Subject-Token': "111111111"},
+ json=PATCH_SUBJECTS
+ )
+ m.register_uri(
+ 'DELETE', 'http://manager:30001/policies/2/subjects/2',
+ headers={'X-Subject-Token': "111111111"},
+ json=RESULT_OK
+ ) \ No newline at end of file
diff --git a/python_moonclient/tests/unit_python/conftest.py b/python_moonclient/tests/unit_python/conftest.py
index e98f48c5..bd3e5f4d 100644
--- a/python_moonclient/tests/unit_python/conftest.py
+++ b/python_moonclient/tests/unit_python/conftest.py
@@ -2,6 +2,25 @@ import pytest
import requests_mock
from . import mock_config
+from .conf.conf_projects import *
+from .conf.conf_models import *
+from .conf.conf_pdps import *
+from .conf.conf_action_categories import *
+from .conf.conf_object_categories import *
+from .conf.conf_subject_categories import *
+from .conf.conf_meta_rules import *
+from .conf.conf_action_assignments import *
+from .conf.conf_object_assignments import *
+from .conf.conf_subject_assignments import *
+from .conf.conf_policies import *
+from .conf.conf_subjects import *
+from .conf.conf_objects import *
+from .conf.conf_actions import *
+from .conf.conf_subject_data import *
+from .conf.conf_object_data import *
+from .conf.conf_action_data import *
+from .conf.conf_rules import *
+
@pytest.fixture(autouse=True)
def no_requests(monkeypatch):
@@ -9,4 +28,25 @@ def no_requests(monkeypatch):
"""
with requests_mock.Mocker(real_http=True) as m:
mock_config.register_consul(m)
+
+ conf_projects(m)
+ conf_models(m)
+ conf_pdps(m)
+ conf_action_categories(m)
+ conf_object_categories(m)
+ conf_subject_categories(m)
+ conf_meta_rules(m)
+ conf_policies(m)
+ conf_subjects(m)
+ conf_objects(m)
+ conf_actions(m)
+ conf_object_data(m)
+ conf_subject_data(m)
+ conf_action_data(m)
+ conf_action_assignments(m)
+ conf_object_assignments(m)
+ conf_subject_assignments(m)
+ conf_rule_assignments(m)
yield m
+
+
diff --git a/python_moonclient/tests/unit_python/mock_config.py b/python_moonclient/tests/unit_python/mock_config.py
index 6d6c8249..b6c42d76 100644
--- a/python_moonclient/tests/unit_python/mock_config.py
+++ b/python_moonclient/tests/unit_python/mock_config.py
@@ -33,3 +33,32 @@ def register_consul(m):
'GET', 'http://consul:8500/v1/kv/{}'.format(component),
json=[{'Key': component, 'Value': utilities.get_b64_conf(component)}]
)
+
+ m.register_uri(
+ 'GET', 'http://manager:30001',
+ json={}
+ )
+ m.register_uri(
+ 'GET', 'http://keystone:5000/v3',
+ json={}
+ )
+ m.register_uri(
+ 'POST', 'http://keystone:5000/v3/auth/tokens',
+ headers={'X-Subject-Token': "111111111"}
+ )
+ m.register_uri(
+ 'DELETE', 'http://keystone:5000/v3/auth/tokens',
+ headers={'X-Subject-Token': "111111111"}
+ )
+ m.register_uri(
+ 'POST', 'http://keystone:5000/v3/users?name=testuser&domain_id=default',
+ json={"users": {}}
+ )
+ m.register_uri(
+ 'GET', 'http://keystone:5000/v3/users?name=testuser&domain_id=default',
+ json={"users": {}}
+ )
+ m.register_uri(
+ 'POST', 'http://keystone:5000/v3/users/',
+ json={"users": [{"id": "1111111111111"}]}
+ )
diff --git a/python_moonclient/tests/unit_python/test_config.py b/python_moonclient/tests/unit_python/test_config.py
index ebdfacf0..e4effec6 100644
--- a/python_moonclient/tests/unit_python/test_config.py
+++ b/python_moonclient/tests/unit_python/test_config.py
@@ -1,8 +1,8 @@
-import pytest
-from . import utilities
+from python_moonclient.core.cli_exceptions import MoonCliException
def test_authz_request():
- from python_moonclient import config
+ from python_moonclient.core import config
conf_data = config.get_config_data("consul", 8500)
- assert isinstance(conf_data, dict)
+ if not isinstance(conf_data, dict):
+ raise MoonCliException("Unexpected error : the conf data is not a dictionnary")
diff --git a/python_moonclient/tests/unit_python/test_models.py b/python_moonclient/tests/unit_python/test_models.py
index f708c6e4..fed889e3 100644
--- a/python_moonclient/tests/unit_python/test_models.py
+++ b/python_moonclient/tests/unit_python/test_models.py
@@ -1,7 +1,8 @@
-from python_moonclient.models import *
+from python_moonclient.core.models import *
def test_models():
+ init("consul", 8500)
check_model()
model_id = add_model()
check_model(model_id)
diff --git a/python_moonclient/tests/unit_python/test_pdp.py b/python_moonclient/tests/unit_python/test_pdp.py
index 8d9a3ac3..e979aeae 100644
--- a/python_moonclient/tests/unit_python/test_pdp.py
+++ b/python_moonclient/tests/unit_python/test_pdp.py
@@ -1,13 +1,14 @@
-from python_moonclient.pdp import *
-
+from python_moonclient.core.pdp import *
def test_pdp():
+ init("consul", 8500)
projects = get_keystone_projects()
admin_project_id = None
for _project in projects['projects']:
if _project['name'] == "admin":
admin_project_id = _project['id']
- assert admin_project_id
+ if admin_project_id is None:
+ raise MoonCliException("Unexpected results, could not find the admin project")
check_pdp()
pdp_id = add_pdp()
check_pdp(pdp_id)
diff --git a/python_moonclient/tests/unit_python/test_policies.py b/python_moonclient/tests/unit_python/test_policies.py
index 386c37af..9ab9003e 100644
--- a/python_moonclient/tests/unit_python/test_policies.py
+++ b/python_moonclient/tests/unit_python/test_policies.py
@@ -1,8 +1,12 @@
-from python_moonclient.policies import *
-from python_moonclient.models import *
+from python_moonclient.core.policies import *
+from python_moonclient.core.models import *
+from python_moonclient.core import policies
+from python_moonclient.core import models
def test_policies():
+ policies.init("consul", 8500)
+ models.init("consul", 8500)
check_policy()
policy_id = add_policy()
check_policy(policy_id)
@@ -71,7 +75,7 @@ def test_object_data():
object_data_id = add_object_data(policy_id=policy_id, category_id=object_cat_id)
check_object_data(policy_id=policy_id, data_id=object_data_id, category_id=object_cat_id)
delete_object_data(policy_id=policy_id, data_id=object_data_id, category_id=object_cat_id)
-
+ print('ok')
def test_action_data():
policy_id = add_policy()
diff --git a/python_moondb/Changelog b/python_moondb/Changelog
index a7d10b17..f4feef62 100644
--- a/python_moondb/Changelog
+++ b/python_moondb/Changelog
@@ -57,3 +57,52 @@ CHANGES
-----
- Code cleaning
+1.2.6
+-----
+- Remove some code duplication in moon_db
+- handle the extra field for the perimeter
+
+1.2.7
+-----
+- Fix some bugs
+
+1.2.8
+-----
+- Add unique constraints on db tables
+
+1.2.9
+-----
+- Add some verifications when deleting some elements in database
+
+1.2.10
+-----
+- Update the migration script because of a bug introduced in 1.2.8 in rule table
+- Fix bugs due to the previous version
+
+1.2.11
+------
+- adding test cases for perimeter
+- adding subject_object_action to model_test
+- update import of exception
+- add unit_test to test_model
+- add validation for not accepting blank perimeter name or category name
+
+1.2.12
+------
+- Fix the SubjectExisting exception problem
+
+1.2.13
+------
+- Add validations and refactor test cases
+
+1.2.14
+------
+- Fix some bugs for the manager and clean the code
+
+1.2.15
+------
+- Fix test cases after removing syntax error in exceptions
+
+1.2.16
+------
+- Fix the "key length error" in meta_rule table
diff --git a/python_moondb/MANIFEST.in b/python_moondb/MANIFEST.in
index 82b40140..02655837 100644
--- a/python_moondb/MANIFEST.in
+++ b/python_moondb/MANIFEST.in
@@ -3,7 +3,7 @@
# license which can be found in the file 'LICENSE' in this package distribution
# or at 'http://www.apache.org/licenses/LICENSE-2.0'.
-include README.rst
+include README.md
include LICENSE
include setup.py
include requirements.txt
diff --git a/python_moondb/python_moondb/__init__.py b/python_moondb/python_moondb/__init__.py
index de7c772e..e2e16287 100644
--- a/python_moondb/python_moondb/__init__.py
+++ b/python_moondb/python_moondb/__init__.py
@@ -3,5 +3,4 @@
# license which can be found in the file 'LICENSE' in this package distribution
# or at 'http://www.apache.org/licenses/LICENSE-2.0'.
-__version__ = "1.2.5"
-
+__version__ = "1.2.16"
diff --git a/python_moondb/python_moondb/api/model.py b/python_moondb/python_moondb/api/model.py
index bd475365..c1603b83 100644
--- a/python_moondb/python_moondb/api/model.py
+++ b/python_moondb/python_moondb/api/model.py
@@ -9,7 +9,6 @@ from python_moonutilities import exceptions
from python_moonutilities.security_functions import filter_input, enforce
from python_moondb.api.managers import Managers
-
logger = logging.getLogger("moon.db.api.model")
@@ -23,6 +22,10 @@ class ModelManager(Managers):
def update_model(self, user_id, model_id, value):
if model_id not in self.driver.get_models(model_id=model_id):
raise exceptions.ModelUnknown
+ if value and 'meta_rules' in value:
+ for meta_rule_id in value['meta_rules']:
+ if not self.driver.get_meta_rules(meta_rule_id=meta_rule_id):
+ raise exceptions.MetaRuleUnknown
return self.driver.update_model(model_id=model_id, value=value)
@enforce(("read", "write"), "models")
@@ -30,6 +33,10 @@ class ModelManager(Managers):
if model_id not in self.driver.get_models(model_id=model_id):
raise exceptions.ModelUnknown
# TODO (asteroide): check that no policy is connected to this model
+ policies = Managers.PolicyManager.get_policies(user_id=user_id)
+ for policy in policies:
+ if policies[policy]['model_id'] == model_id:
+ raise exceptions.DeleteModelWithPolicy
return self.driver.delete_model(model_id=model_id)
@enforce(("read", "write"), "models")
@@ -38,6 +45,10 @@ class ModelManager(Managers):
raise exceptions.ModelExisting
if not model_id:
model_id = uuid4().hex
+ if value and 'meta_rules' in value:
+ for meta_rule_id in value['meta_rules']:
+ if not self.driver.get_meta_rules(meta_rule_id=meta_rule_id):
+ raise exceptions.MetaRuleUnknown
return self.driver.add_model(model_id=model_id, value=value)
@enforce("read", "models")
@@ -48,6 +59,19 @@ class ModelManager(Managers):
def set_meta_rule(self, user_id, meta_rule_id, value):
if meta_rule_id not in self.driver.get_meta_rules(meta_rule_id=meta_rule_id):
raise exceptions.MetaRuleUnknown
+ if value:
+ if 'subject_categories' in value:
+ for subject_category_id in value['subject_categories']:
+ if not self.driver.get_subject_categories(category_id=subject_category_id):
+ raise exceptions.SubjectCategoryUnknown
+ if 'object_categories' in value:
+ for object_category_id in value['object_categories']:
+ if not self.driver.get_object_categories(category_id=object_category_id):
+ raise exceptions.ObjectCategoryUnknown
+ if 'action_categories' in value:
+ for action_category_id in value['action_categories']:
+ if not self.driver.get_action_categories(category_id=action_category_id):
+ raise exceptions.ActionCategoryUnknown
return self.driver.set_meta_rule(meta_rule_id=meta_rule_id, value=value)
@enforce("read", "meta_rules")
@@ -58,9 +82,19 @@ class ModelManager(Managers):
def add_meta_rule(self, user_id, meta_rule_id=None, value=None):
if meta_rule_id in self.driver.get_meta_rules(meta_rule_id=meta_rule_id):
raise exceptions.MetaRuleExisting
- if not meta_rule_id:
- meta_rule_id = uuid4().hex
- logger.info("add_meta_rule {}".format(value))
+ if value:
+ if 'subject_categories' in value:
+ for subject_category_id in value['subject_categories']:
+ if not self.driver.get_subject_categories(category_id=subject_category_id):
+ raise exceptions.SubjectCategoryUnknown
+ if 'object_categories' in value:
+ for object_category_id in value['object_categories']:
+ if not self.driver.get_object_categories(category_id=object_category_id):
+ raise exceptions.ObjectCategoryUnknown
+ if 'action_categories' in value:
+ for action_category_id in value['action_categories']:
+ if not self.driver.get_action_categories(category_id=action_category_id):
+ raise exceptions.ActionCategoryUnknown
return self.driver.set_meta_rule(meta_rule_id=meta_rule_id, value=value)
@enforce(("read", "write"), "meta_rules")
@@ -68,6 +102,10 @@ class ModelManager(Managers):
if meta_rule_id not in self.driver.get_meta_rules(meta_rule_id=meta_rule_id):
raise exceptions.MetaRuleUnknown
# TODO (asteroide): check and/or delete data and assignments and rules linked to that meta_rule
+ models = self.get_models(user_id=user_id)
+ for model_id in models:
+ if models[model_id]['meta_rules'] == meta_rule_id:
+ raise exceptions.DeleteMetaRuleWithModel
return self.driver.delete_meta_rule(meta_rule_id=meta_rule_id)
@enforce("read", "meta_data")
@@ -78,8 +116,6 @@ class ModelManager(Managers):
def add_subject_category(self, user_id, category_id=None, value=None):
if category_id in self.driver.get_subject_categories(category_id=category_id):
raise exceptions.SubjectCategoryExisting
- # if not category_id:
- # category_id = uuid4().hex
return self.driver.add_subject_category(name=value["name"], description=value["description"], uuid=category_id)
@enforce(("read", "write"), "meta_data")
@@ -88,6 +124,16 @@ class ModelManager(Managers):
# TODO (asteroide): delete all meta_rules linked to that category
if category_id not in self.driver.get_subject_categories(category_id=category_id):
raise exceptions.SubjectCategoryUnknown
+ meta_rules = self.get_meta_rules(user_id=user_id)
+ for meta_rule_id in meta_rules:
+ for subject_category_id in meta_rules[meta_rule_id]['subject_categories']:
+ logger.info("delete_subject_category {} {}".format(subject_category_id, meta_rule_id))
+ logger.info("delete_subject_category {}".format(meta_rules[meta_rule_id]))
+ if subject_category_id == category_id:
+ self.delete_meta_rule(user_id, meta_rule_id)
+ # raise exceptions.DeleteCategoryWithMetaRule
+ if self.driver.is_subject_data_exist(category_id=category_id):
+ raise exceptions.DeleteCategoryWithData
return self.driver.delete_subject_category(category_id=category_id)
@enforce("read", "meta_data")
@@ -98,8 +144,6 @@ class ModelManager(Managers):
def add_object_category(self, user_id, category_id=None, value=None):
if category_id in self.driver.get_object_categories(category_id=category_id):
raise exceptions.ObjectCategoryExisting
- # if not category_id:
- # category_id = uuid4().hex
return self.driver.add_object_category(name=value["name"], description=value["description"], uuid=category_id)
@enforce(("read", "write"), "meta_data")
@@ -108,6 +152,13 @@ class ModelManager(Managers):
# TODO (asteroide): delete all meta_rules linked to that category
if category_id not in self.driver.get_object_categories(category_id=category_id):
raise exceptions.ObjectCategoryUnknown
+ meta_rules = self.get_meta_rules(user_id=user_id)
+ for meta_rule_id in meta_rules:
+ for object_category_id in meta_rules[meta_rule_id]['object_categories']:
+ if object_category_id == category_id:
+ self.delete_meta_rule(user_id, meta_rule_id)
+ if self.driver.is_object_data_exist(category_id=category_id):
+ raise exceptions.DeleteCategoryWithData
return self.driver.delete_object_category(category_id=category_id)
@enforce("read", "meta_data")
@@ -118,8 +169,6 @@ class ModelManager(Managers):
def add_action_category(self, user_id, category_id=None, value=None):
if category_id in self.driver.get_action_categories(category_id=category_id):
raise exceptions.ActionCategoryExisting
- # if not category_id:
- # category_id = uuid4().hex
return self.driver.add_action_category(name=value["name"], description=value["description"], uuid=category_id)
@enforce(("read", "write"), "meta_data")
@@ -127,6 +176,12 @@ class ModelManager(Managers):
# TODO (asteroide): delete all data linked to that category
# TODO (asteroide): delete all meta_rules linked to that category
if category_id not in self.driver.get_action_categories(category_id=category_id):
- raise exceptions.ActionCategoryExisting
+ raise exceptions.ActionCategoryUnknown
+ meta_rules = self.get_meta_rules(user_id=user_id)
+ for meta_rule_id in meta_rules:
+ for action_category_id in meta_rules[meta_rule_id]['action_categories']:
+ if action_category_id == category_id:
+ self.delete_meta_rule(user_id, meta_rule_id)
+ if self.driver.is_action_data_exist(category_id=category_id):
+ raise exceptions.DeleteCategoryWithData
return self.driver.delete_action_category(category_id=category_id)
-
diff --git a/python_moondb/python_moondb/api/pdp.py b/python_moondb/python_moondb/api/pdp.py
index 7e852ca8..d0a071c9 100644
--- a/python_moondb/python_moondb/api/pdp.py
+++ b/python_moondb/python_moondb/api/pdp.py
@@ -22,6 +22,10 @@ class PDPManager(Managers):
def update_pdp(self, user_id, pdp_id, value):
if pdp_id not in self.driver.get_pdp(pdp_id=pdp_id):
raise exceptions.PdpUnknown
+ if value and 'security_pipeline' in value:
+ for policy_id in value['security_pipeline']:
+ if not Managers.PolicyManager.get_policies(user_id=user_id, policy_id=policy_id):
+ raise exceptions.PolicyUnknown
return self.driver.update_pdp(pdp_id=pdp_id, value=value)
@enforce(("read", "write"), "pdp")
@@ -36,6 +40,10 @@ class PDPManager(Managers):
raise exceptions.PdpExisting
if not pdp_id:
pdp_id = uuid4().hex
+ if value and 'security_pipeline' in value:
+ for policy_id in value['security_pipeline']:
+ if not Managers.PolicyManager.get_policies(user_id=user_id, policy_id=policy_id):
+ raise exceptions.PolicyUnknown
return self.driver.add_pdp(pdp_id=pdp_id, value=value)
@enforce("read", "pdp")
diff --git a/python_moondb/python_moondb/api/policy.py b/python_moondb/python_moondb/api/policy.py
index ca313f9a..05c2b7d5 100644
--- a/python_moondb/python_moondb/api/policy.py
+++ b/python_moondb/python_moondb/api/policy.py
@@ -8,6 +8,7 @@ import logging
from python_moonutilities.security_functions import enforce
from python_moondb.api.managers import Managers
from python_moonutilities import exceptions
+# from python_moondb.core import PDPManager
logger = logging.getLogger("moon.db.api.policy")
@@ -39,6 +40,9 @@ class PolicyManager(Managers):
def update_policy(self, user_id, policy_id, value):
if policy_id not in self.driver.get_policies(policy_id=policy_id):
raise exceptions.PolicyUnknown
+ if value and 'model_id' in value and value['model_id'] != "":
+ if not Managers.ModelManager.get_models(user_id, model_id=value['model_id']):
+ raise exceptions.ModelUnknown
return self.driver.update_policy(policy_id=policy_id, value=value)
@enforce(("read", "write"), "policies")
@@ -46,6 +50,11 @@ class PolicyManager(Managers):
# TODO (asteroide): unmap PDP linked to that policy
if policy_id not in self.driver.get_policies(policy_id=policy_id):
raise exceptions.PolicyUnknown
+ pdps = self.PDPManager.get_pdp(user_id=user_id)
+ for pdp in pdps:
+ for policy_id in pdps[pdp]['security_pipeline']:
+ if policy_id == policy_id:
+ raise exceptions.DeletePolicyWithPdp
return self.driver.delete_policy(policy_id=policy_id)
@enforce(("read", "write"), "policies")
@@ -54,6 +63,9 @@ class PolicyManager(Managers):
raise exceptions.PolicyExisting
if not policy_id:
policy_id = uuid4().hex
+ if value and 'model_id' in value and value['model_id'] != "":
+ if not Managers.ModelManager.get_models(user_id, model_id=value['model_id']):
+ raise exceptions.ModelUnknown
return self.driver.add_policy(policy_id=policy_id, value=value)
@enforce("read", "policies")
@@ -62,10 +74,19 @@ class PolicyManager(Managers):
@enforce("read", "perimeter")
def get_subjects(self, user_id, policy_id, perimeter_id=None):
+ if not policy_id:
+ pass
+ elif not (policy_id and self.get_policies(user_id=user_id, policy_id=policy_id)):
+ raise exceptions.PolicyUnknown
return self.driver.get_subjects(policy_id=policy_id, perimeter_id=perimeter_id)
@enforce(("read", "write"), "perimeter")
def add_subject(self, user_id, policy_id, perimeter_id=None, value=None):
+ if not value or "name" not in value or not value["name"].strip():
+ raise exceptions.PerimeterNameInvalid
+ if value["name"] in map(lambda x: x['name'],
+ self.get_subjects(user_id, policy_id, perimeter_id).values()):
+ raise exceptions.SubjectExisting
k_user = Managers.KeystoneManager.get_user_by_name(value.get('name'))
if not k_user['users']:
k_user = Managers.KeystoneManager.create_user(value)
@@ -88,10 +109,16 @@ class PolicyManager(Managers):
@enforce(("read", "write"), "perimeter")
def delete_subject(self, user_id, policy_id, perimeter_id):
+ if policy_id and not self.get_policies(user_id=user_id, policy_id=policy_id):
+ raise exceptions.PolicyUnknown
return self.driver.delete_subject(policy_id=policy_id, perimeter_id=perimeter_id)
@enforce("read", "perimeter")
def get_objects(self, user_id, policy_id, perimeter_id=None):
+ if not policy_id:
+ pass
+ elif not (policy_id and self.get_policies(user_id=user_id, policy_id=policy_id)):
+ raise exceptions.PolicyUnknown
return self.driver.get_objects(policy_id=policy_id, perimeter_id=perimeter_id)
@enforce(("read", "write"), "perimeter")
@@ -104,22 +131,30 @@ class PolicyManager(Managers):
@enforce(("read", "write"), "perimeter")
def delete_object(self, user_id, policy_id, perimeter_id):
+ if policy_id and not self.get_policies(user_id=user_id, policy_id=policy_id):
+ raise exceptions.PolicyUnknown
return self.driver.delete_object(policy_id=policy_id, perimeter_id=perimeter_id)
@enforce("read", "perimeter")
def get_actions(self, user_id, policy_id, perimeter_id=None):
+ if not policy_id:
+ pass
+ elif not (policy_id and self.get_policies(user_id=user_id, policy_id=policy_id)):
+ raise exceptions.PolicyUnknown
return self.driver.get_actions(policy_id=policy_id, perimeter_id=perimeter_id)
@enforce(("read", "write"), "perimeter")
def add_action(self, user_id, policy_id, perimeter_id=None, value=None):
+ logger.debug("add_action {}".format(policy_id))
if not self.get_policies(user_id=user_id, policy_id=policy_id):
raise exceptions.PolicyUnknown
- if not perimeter_id:
- perimeter_id = uuid4().hex
return self.driver.set_action(policy_id=policy_id, perimeter_id=perimeter_id, value=value)
@enforce(("read", "write"), "perimeter")
def delete_action(self, user_id, policy_id, perimeter_id):
+ logger.debug("delete_action {} {} {}".format(policy_id, perimeter_id, self.get_policies(user_id=user_id, policy_id=policy_id)))
+ if policy_id and not self.get_policies(user_id=user_id, policy_id=policy_id):
+ raise exceptions.PolicyUnknown
return self.driver.delete_action(policy_id=policy_id, perimeter_id=perimeter_id)
@enforce("read", "data")
@@ -139,6 +174,8 @@ class PolicyManager(Managers):
def set_subject_data(self, user_id, policy_id, data_id=None, category_id=None, value=None):
if not category_id:
raise Exception('Invalid category id')
+ if not Managers.ModelManager.get_subject_categories(user_id=user_id, category_id=category_id):
+ raise exceptions.MetaDataUnknown
if not self.get_policies(user_id=user_id, policy_id=policy_id):
raise exceptions.PolicyUnknown
if not data_id:
@@ -148,6 +185,9 @@ class PolicyManager(Managers):
@enforce(("read", "write"), "data")
def delete_subject_data(self, user_id, policy_id, data_id):
# TODO (asteroide): check and/or delete assignments linked to that data
+ subject_assignments = self.get_subject_assignments(user_id=user_id, policy_id=policy_id, subject_id=data_id)
+ if subject_assignments:
+ raise exceptions.DeleteData
return self.driver.delete_subject_data(policy_id=policy_id, data_id=data_id)
@enforce("read", "data")
@@ -167,6 +207,8 @@ class PolicyManager(Managers):
def add_object_data(self, user_id, policy_id, data_id=None, category_id=None, value=None):
if not category_id:
raise Exception('Invalid category id')
+ if not Managers.ModelManager.get_object_categories(user_id=user_id, category_id=category_id):
+ raise exceptions.MetaDataUnknown
if not self.get_policies(user_id=user_id, policy_id=policy_id):
raise exceptions.PolicyUnknown
if not data_id:
@@ -176,6 +218,9 @@ class PolicyManager(Managers):
@enforce(("read", "write"), "data")
def delete_object_data(self, user_id, policy_id, data_id):
# TODO (asteroide): check and/or delete assignments linked to that data
+ object_assignments = self.get_object_assignments(user_id=user_id, policy_id=policy_id, object_id=data_id)
+ if object_assignments:
+ raise exceptions.DeleteData
return self.driver.delete_object_data(policy_id=policy_id, data_id=data_id)
@enforce("read", "data")
@@ -195,6 +240,8 @@ class PolicyManager(Managers):
def add_action_data(self, user_id, policy_id, data_id=None, category_id=None, value=None):
if not category_id:
raise Exception('Invalid category id')
+ if not Managers.ModelManager.get_action_categories(user_id=user_id, category_id=category_id):
+ raise exceptions.MetaDataUnknown
if not self.get_policies(user_id=user_id, policy_id=policy_id):
raise exceptions.PolicyUnknown
if not data_id:
@@ -204,6 +251,9 @@ class PolicyManager(Managers):
@enforce(("read", "write"), "data")
def delete_action_data(self, user_id, policy_id, data_id):
# TODO (asteroide): check and/or delete assignments linked to that data
+ action_assignments = self.get_action_assignments(user_id=user_id, policy_id=policy_id, action_id=data_id)
+ if action_assignments:
+ raise exceptions.DeleteData
return self.driver.delete_action_data(policy_id=policy_id, data_id=data_id)
@enforce("read", "assignments")
@@ -214,6 +264,12 @@ class PolicyManager(Managers):
def add_subject_assignment(self, user_id, policy_id, subject_id, category_id, data_id):
if not self.get_policies(user_id=user_id, policy_id=policy_id):
raise exceptions.PolicyUnknown
+ if not self.get_subjects(user_id=user_id, policy_id=policy_id, perimeter_id=subject_id):
+ raise exceptions.SubjectUnknown
+ if not Managers.ModelManager.get_subject_categories(user_id=user_id, category_id=category_id):
+ raise exceptions.MetaDataUnknown
+ if not self.get_subject_data(user_id=user_id, policy_id=policy_id, data_id=data_id):
+ raise exceptions.DataUnknown
return self.driver.add_subject_assignment(policy_id=policy_id, subject_id=subject_id,
category_id=category_id, data_id=data_id)
@@ -230,6 +286,12 @@ class PolicyManager(Managers):
def add_object_assignment(self, user_id, policy_id, object_id, category_id, data_id):
if not self.get_policies(user_id=user_id, policy_id=policy_id):
raise exceptions.PolicyUnknown
+ if not self.get_objects(user_id=user_id, policy_id=policy_id, perimeter_id=object_id):
+ raise exceptions.ObjectUnknown
+ if not Managers.ModelManager.get_object_categories(user_id=user_id, category_id=category_id):
+ raise exceptions.MetaDataUnknown
+ if not self.get_object_data(user_id=user_id, policy_id=policy_id, data_id=data_id):
+ raise exceptions.DataUnknown
return self.driver.add_object_assignment(policy_id=policy_id, object_id=object_id,
category_id=category_id, data_id=data_id)
@@ -246,6 +308,12 @@ class PolicyManager(Managers):
def add_action_assignment(self, user_id, policy_id, action_id, category_id, data_id):
if not self.get_policies(user_id=user_id, policy_id=policy_id):
raise exceptions.PolicyUnknown
+ if not self.get_actions(user_id=user_id, policy_id=policy_id, perimeter_id=action_id):
+ raise exceptions.ActionUnknown
+ if not Managers.ModelManager.get_action_categories(user_id=user_id, category_id=category_id):
+ raise exceptions.MetaDataUnknown
+ if not self.get_action_data(user_id=user_id, policy_id=policy_id, data_id=data_id):
+ raise exceptions.DataUnknown
return self.driver.add_action_assignment(policy_id=policy_id, action_id=action_id,
category_id=category_id, data_id=data_id)
@@ -257,11 +325,14 @@ class PolicyManager(Managers):
@enforce("read", "rules")
def get_rules(self, user_id, policy_id, meta_rule_id=None, rule_id=None):
return self.driver.get_rules(policy_id=policy_id, meta_rule_id=meta_rule_id, rule_id=rule_id)
+ logger.info("delete_subject_data: {} {}".format(policy_id, data_id))
@enforce(("read", "write"), "rules")
def add_rule(self, user_id, policy_id, meta_rule_id, value):
if not self.get_policies(user_id=user_id, policy_id=policy_id):
raise exceptions.PolicyUnknown
+ if not self.ModelManager.get_meta_rules(user_id=user_id, meta_rule_id=meta_rule_id):
+ raise exceptions.MetaRuleUnknown
return self.driver.add_rule(policy_id=policy_id, meta_rule_id=meta_rule_id, value=value)
@enforce(("read", "write"), "rules")
diff --git a/python_moondb/python_moondb/backends/sql.py b/python_moondb/python_moondb/backends/sql.py
index 1ce8d016..7310e7f3 100644
--- a/python_moondb/python_moondb/backends/sql.py
+++ b/python_moondb/python_moondb/backends/sql.py
@@ -9,13 +9,14 @@ from uuid import uuid4
import sqlalchemy as sql
import logging
from sqlalchemy.orm import sessionmaker
-from sqlalchemy.ext.declarative import declarative_base
+from sqlalchemy.ext.declarative import declarative_base, declared_attr
from sqlalchemy import create_engine
from contextlib import contextmanager
from sqlalchemy import types as sql_types
from python_moonutilities import configuration
-from python_moonutilities.exceptions import *
+from python_moonutilities import exceptions
from python_moondb.core import PDPDriver, PolicyDriver, ModelDriver
+import sqlalchemy
logger = logging.getLogger("moon.db.driver.sql")
Base = declarative_base()
@@ -61,13 +62,14 @@ class JsonBlob(sql_types.TypeDecorator):
class Model(Base, DictBase):
__tablename__ = 'models'
- attributes = ['id', 'value']
+ attributes = ['id', 'name', 'value']
id = sql.Column(sql.String(64), primary_key=True)
+ name = sql.Column(sql.String(256), nullable=False)
value = sql.Column(JsonBlob(), nullable=True)
def to_dict(self):
return {
- "name": self.value.get("name"),
+ "name": self.name,
"description": self.value.get("description", ""),
"meta_rules": self.value.get("meta_rules", list()),
}
@@ -75,240 +77,198 @@ class Model(Base, DictBase):
class Policy(Base, DictBase):
__tablename__ = 'policies'
- attributes = ['id', 'value']
+ attributes = ['id', 'name', 'model_id', 'value']
id = sql.Column(sql.String(64), primary_key=True)
+ name = sql.Column(sql.String(256), nullable=False)
+ model_id = sql.Column(sql.String(64), nullable=True, default="")
value = sql.Column(JsonBlob(), nullable=True)
def to_dict(self):
return {
- "name": self.value.get("name"),
"description": self.value.get("description", ""),
- "model_id": self.value.get("model_id", ""),
"genre": self.value.get("genre", ""),
+ "model_id": self.model_id,
+ "name": self.name
}
class PDP(Base, DictBase):
__tablename__ = 'pdp'
- attributes = ['id', 'value']
+ attributes = ['id', 'name', 'keystone_project_id', 'value']
id = sql.Column(sql.String(64), primary_key=True)
+ name = sql.Column(sql.String(256), nullable=False)
+ keystone_project_id = sql.Column(sql.String(64), nullable=True, default="")
value = sql.Column(JsonBlob(), nullable=True)
def to_dict(self):
return {
- "name": self.value.get("name"),
+ "name": self.name,
"description": self.value.get("description", ""),
- "keystone_project_id": self.value.get("keystone_project_id", ""),
+ "keystone_project_id": self.keystone_project_id,
"security_pipeline": self.value.get("security_pipeline", []),
}
-class SubjectCategory(Base, DictBase):
- __tablename__ = 'subject_categories'
+class PerimeterCategoryBase(DictBase):
attributes = ['id', 'name', 'description']
id = sql.Column(sql.String(64), primary_key=True)
name = sql.Column(sql.String(256), nullable=False)
description = sql.Column(sql.String(256), nullable=True)
-class ObjectCategory(Base, DictBase):
+class SubjectCategory(Base, PerimeterCategoryBase):
+ __tablename__ = 'subject_categories'
+
+
+class ObjectCategory(Base, PerimeterCategoryBase):
__tablename__ = 'object_categories'
- attributes = ['id', 'name', 'description']
- id = sql.Column(sql.String(64), primary_key=True)
- name = sql.Column(sql.String(256), nullable=False)
- description = sql.Column(sql.String(256), nullable=True)
-class ActionCategory(Base, DictBase):
+class ActionCategory(Base, PerimeterCategoryBase):
__tablename__ = 'action_categories'
- attributes = ['id', 'name', 'description']
- id = sql.Column(sql.String(64), primary_key=True)
- name = sql.Column(sql.String(256), nullable=False)
- description = sql.Column(sql.String(256), nullable=True)
-class Subject(Base, DictBase):
- __tablename__ = 'subjects'
- attributes = ['id', 'value']
+class PerimeterBase(DictBase):
+ attributes = ['id', 'name', 'value']
id = sql.Column(sql.String(64), primary_key=True)
+ name = sql.Column(sql.String(256), nullable=False)
value = sql.Column(JsonBlob(), nullable=True)
+ __mapper_args__ = {'concrete': True}
def __repr__(self):
- return "{}: {}".format(self.id, json.dumps(self.value))
+ return "{} with name {} : {}".format(self.id, self.name, json.dumps(self.value))
def to_return(self):
return {
'id': self.id,
- 'name': self.value.get("name", ""),
+ 'name': self.name,
'description': self.value.get("description", ""),
'email': self.value.get("email", ""),
- 'partner_id': self.value.get("partner_id", ""),
+ 'extra': self.value.get("extra", dict()),
'policy_list': self.value.get("policy_list", [])
}
def to_dict(self):
+ dict_value = copy.deepcopy(self.value)
+ dict_value["name"] = self.name
return {
'id': self.id,
- 'value': self.value
+ 'value': dict_value
}
-class Object(Base, DictBase):
- __tablename__ = 'objects'
- attributes = ['id', 'value']
- id = sql.Column(sql.String(64), primary_key=True)
- value = sql.Column(JsonBlob(), nullable=True)
-
- def __repr__(self):
- return "{}: {}".format(self.id, json.dumps(self.value))
+class Subject(Base, PerimeterBase):
+ __tablename__ = 'subjects'
- def to_dict(self):
- return {
- 'id': self.id,
- 'value': self.value
- }
- def to_return(self):
- return {
- 'id': self.id,
- 'name': self.value.get("name", ""),
- 'description': self.value.get("description", ""),
- 'partner_id': self.value.get("partner_id", ""),
- 'policy_list': self.value.get("policy_list", [])
- }
+class Object(Base, PerimeterBase):
+ __tablename__ = 'objects'
-class Action(Base, DictBase):
+class Action(Base, PerimeterBase):
__tablename__ = 'actions'
- attributes = ['id', 'value']
- id = sql.Column(sql.String(64), primary_key=True)
- value = sql.Column(JsonBlob(), nullable=True)
- def __repr__(self):
- return "{}: {}".format(self.id, json.dumps(self.value))
- def to_dict(self):
- return {
- 'id': self.id,
- 'value': self.value
- }
-
- def to_return(self):
- return {
- 'id': self.id,
- 'name': self.value.get("name", ""),
- 'description': self.value.get("description", ""),
- 'partner_id': self.value.get("partner_id", ""),
- 'policy_list': self.value.get("policy_list", [])
- }
-
-
-class SubjectData(Base, DictBase):
- __tablename__ = 'subject_data'
- attributes = ['id', 'value', 'category_id', 'policy_id']
+class PerimeterDataBase(DictBase):
+ attributes = ['id', 'name', 'value', 'category_id', 'policy_id']
id = sql.Column(sql.String(64), primary_key=True)
+ name = sql.Column(sql.String(256), nullable=False)
value = sql.Column(JsonBlob(), nullable=True)
- category_id = sql.Column(sql.ForeignKey("subject_categories.id"), nullable=False)
- policy_id = sql.Column(sql.ForeignKey("policies.id"), nullable=False)
+ @declared_attr
+ def policy_id(cls):
+ return sql.Column(sql.ForeignKey("policies.id"), nullable=False)
def to_dict(self):
return {
'id': self.id,
- 'name': self.value.get("name", ""),
+ 'name': self.name,
'description': self.value.get("description", ""),
'category_id': self.category_id,
'policy_id': self.policy_id
}
-class ObjectData(Base, DictBase):
+class SubjectData(Base, PerimeterDataBase):
+ __tablename__ = 'subject_data'
+ category_id = sql.Column(sql.ForeignKey("subject_categories.id"), nullable=False)
+
+
+class ObjectData(Base, PerimeterDataBase):
__tablename__ = 'object_data'
- attributes = ['id', 'value', 'category_id', 'policy_id']
- id = sql.Column(sql.String(64), primary_key=True)
- value = sql.Column(JsonBlob(), nullable=True)
category_id = sql.Column(sql.ForeignKey("object_categories.id"), nullable=False)
- policy_id = sql.Column(sql.ForeignKey("policies.id"), nullable=False)
-class ActionData(Base, DictBase):
+class ActionData(Base, PerimeterDataBase):
__tablename__ = 'action_data'
- attributes = ['id', 'value', 'category_id', 'policy_id']
- id = sql.Column(sql.String(64), primary_key=True)
- value = sql.Column(JsonBlob(), nullable=True)
category_id = sql.Column(sql.ForeignKey("action_categories.id"), nullable=False)
- policy_id = sql.Column(sql.ForeignKey("policies.id"), nullable=False)
-class SubjectAssignment(Base, DictBase):
- __tablename__ = 'subject_assignments'
+class PerimeterAssignmentBase(DictBase):
attributes = ['id', 'assignments', 'policy_id', 'subject_id', 'category_id']
id = sql.Column(sql.String(64), primary_key=True)
assignments = sql.Column(JsonBlob(), nullable=True)
- policy_id = sql.Column(sql.ForeignKey("policies.id"), nullable=False)
- subject_id = sql.Column(sql.ForeignKey("subjects.id"), nullable=False)
- category_id = sql.Column(sql.ForeignKey("subject_categories.id"), nullable=False)
+ category_id = None
- def to_dict(self):
+ @declared_attr
+ def policy_id(cls):
+ return sql.Column(sql.ForeignKey("policies.id"), nullable=False)
+
+ def _to_dict(self, element_key, element_value):
return {
"id": self.id,
"policy_id": self.policy_id,
- "subject_id": self.subject_id,
+ element_key: element_value,
"category_id": self.category_id,
"assignments": self.assignments,
}
-class ObjectAssignment(Base, DictBase):
+class SubjectAssignment(Base, PerimeterAssignmentBase):
+ __tablename__ = 'subject_assignments'
+ subject_id = sql.Column(sql.ForeignKey("subjects.id"), nullable=False)
+ category_id = sql.Column(sql.ForeignKey("subject_categories.id"), nullable=False)
+
+ def to_dict(self):
+ return self._to_dict("subject_id", self.subject_id)
+
+
+class ObjectAssignment(Base, PerimeterAssignmentBase):
__tablename__ = 'object_assignments'
attributes = ['id', 'assignments', 'policy_id', 'object_id', 'category_id']
- id = sql.Column(sql.String(64), primary_key=True)
- assignments = sql.Column(JsonBlob(), nullable=True)
- policy_id = sql.Column(sql.ForeignKey("policies.id"), nullable=False)
object_id = sql.Column(sql.ForeignKey("objects.id"), nullable=False)
category_id = sql.Column(sql.ForeignKey("object_categories.id"), nullable=False)
def to_dict(self):
- return {
- "id": self.id,
- "policy_id": self.policy_id,
- "object_id": self.object_id,
- "category_id": self.category_id,
- "assignments": self.assignments,
- }
+ return self._to_dict("object_id", self.object_id)
-class ActionAssignment(Base, DictBase):
+class ActionAssignment(Base, PerimeterAssignmentBase):
__tablename__ = 'action_assignments'
attributes = ['id', 'assignments', 'policy_id', 'action_id', 'category_id']
- id = sql.Column(sql.String(64), primary_key=True)
- assignments = sql.Column(JsonBlob(), nullable=True)
- policy_id = sql.Column(sql.ForeignKey("policies.id"), nullable=False)
action_id = sql.Column(sql.ForeignKey("actions.id"), nullable=False)
category_id = sql.Column(sql.ForeignKey("action_categories.id"), nullable=False)
def to_dict(self):
- return {
- "id": self.id,
- "policy_id": self.policy_id,
- "action_id": self.action_id,
- "category_id": self.category_id,
- "assignments": self.assignments,
- }
+ return self._to_dict("action_id", self.action_id)
class MetaRule(Base, DictBase):
__tablename__ = 'meta_rules'
- attributes = ['id', 'value']
+ attributes = ['id', 'name', 'subject_categories', 'object_categories', 'action_categories', 'value']
id = sql.Column(sql.String(64), primary_key=True)
+ name = sql.Column(sql.String(256), nullable=False)
+ subject_categories = sql.Column(JsonBlob(), nullable=True)
+ object_categories = sql.Column(JsonBlob(), nullable=True)
+ action_categories = sql.Column(JsonBlob(), nullable=True)
value = sql.Column(JsonBlob(), nullable=True)
def to_dict(self):
return {
- "name": self.value["name"],
+ "name": self.name,
"description": self.value.get("description", ""),
- "subject_categories": self.value.get("subject_categories", list()),
- "object_categories": self.value.get("object_categories", list()),
- "action_categories": self.value.get("action_categories", list()),
+ "subject_categories": self.subject_categories,
+ "object_categories": self.object_categories,
+ "action_categories": self.action_categories,
}
@@ -378,15 +338,23 @@ class BaseConnector(object):
class PDPConnector(BaseConnector, PDPDriver):
def update_pdp(self, pdp_id, value):
- with self.get_session_for_write() as session:
- query = session.query(PDP)
- query = query.filter_by(id=pdp_id)
- ref = query.first()
- if ref:
- d = dict(ref.value)
- d.update(value)
- setattr(ref, "value", d)
- return {ref.id: ref.to_dict()}
+ try:
+ with self.get_session_for_write() as session:
+ query = session.query(PDP)
+ query = query.filter_by(id=pdp_id)
+ ref = query.first()
+ if ref:
+ value_wo_name = copy.deepcopy(value)
+ value_wo_name.pop("name", None)
+ value_wo_name.pop("keystone_project_id", None)
+ ref.name = value["name"]
+ ref.keystone_project_id = value["keystone_project_id"]
+ d = dict(ref.value)
+ d.update(value_wo_name)
+ setattr(ref, "value", d)
+ return {ref.id: ref.to_dict()}
+ except sqlalchemy.exc.IntegrityError:
+ raise exceptions.PdpExisting
def delete_pdp(self, pdp_id):
with self.get_session_for_write() as session:
@@ -394,13 +362,21 @@ class PDPConnector(BaseConnector, PDPDriver):
session.delete(ref)
def add_pdp(self, pdp_id=None, value=None):
- with self.get_session_for_write() as session:
- new = PDP.from_dict({
- "id": pdp_id if pdp_id else uuid4().hex,
- "value": value
- })
- session.add(new)
- return {new.id: new.to_dict()}
+ try:
+ with self.get_session_for_write() as session:
+ value_wo_name = copy.deepcopy(value)
+ value_wo_name.pop("name", None)
+ value_wo_name.pop("keystone_project_id", None)
+ new = PDP.from_dict({
+ "id": pdp_id if pdp_id else uuid4().hex,
+ "name": value["name"],
+ "keystone_project_id": value["keystone_project_id"],
+ "value": value_wo_name
+ })
+ session.add(new)
+ return {new.id: new.to_dict()}
+ except sqlalchemy.exc.IntegrityError:
+ raise exceptions.PdpExisting
def get_pdp(self, pdp_id=None):
with self.get_session_for_read() as session:
@@ -419,8 +395,13 @@ class PolicyConnector(BaseConnector, PolicyDriver):
query = query.filter_by(id=policy_id)
ref = query.first()
if ref:
+ value_wo_other_info = copy.deepcopy(value)
+ value_wo_other_info.pop("name", None)
+ value_wo_other_info.pop("model_id", None)
+ ref.name = value["name"]
+ ref.model_id= value["model_id"]
d = dict(ref.value)
- d.update(value)
+ d.update(value_wo_other_info)
setattr(ref, "value", d)
return {ref.id: ref.to_dict()}
@@ -431,9 +412,14 @@ class PolicyConnector(BaseConnector, PolicyDriver):
def add_policy(self, policy_id=None, value=None):
with self.get_session_for_write() as session:
+ value_wo_other_info = copy.deepcopy(value)
+ value_wo_other_info.pop("name", None)
+ value_wo_other_info.pop("model_id", None)
new = Policy.from_dict({
"id": policy_id if policy_id else uuid4().hex,
- "value": value
+ "name": value["name"],
+ "model_id": value.get("model_id", ""),
+ "value": value_wo_other_info
})
session.add(new)
return {new.id: new.to_dict()}
@@ -446,9 +432,9 @@ class PolicyConnector(BaseConnector, PolicyDriver):
ref_list = query.all()
return {_ref.id: _ref.to_dict() for _ref in ref_list}
- def get_subjects(self, policy_id, perimeter_id=None):
+ def __get_perimeters(self, ClassType, policy_id, perimeter_id=None):
with self.get_session_for_read() as session:
- query = session.query(Subject)
+ query = session.query(ClassType)
ref_list = copy.deepcopy(query.all())
if perimeter_id:
for _ref in ref_list:
@@ -467,212 +453,148 @@ class PolicyConnector(BaseConnector, PolicyDriver):
return {_ref.id: _ref.to_return() for _ref in results}
return {_ref.id: _ref.to_return() for _ref in ref_list}
- def set_subject(self, policy_id, perimeter_id=None, value=None):
- _subject = None
+ def __set_perimeter(self, ClassType, ClassTypeException, policy_id, perimeter_id=None, value=None):
+ if not value or "name" not in value or not value["name"].strip():
+ raise exceptions.PerimeterNameInvalid
with self.get_session_for_write() as session:
+ _perimeter = None
if perimeter_id:
- query = session.query(Subject)
+ query = session.query(ClassType)
query = query.filter_by(id=perimeter_id)
- _subject = query.first()
- if not _subject:
+ _perimeter = query.first()
+ if not perimeter_id and not _perimeter:
+ query = session.query(ClassType)
+ query = query.filter_by(name=value['name'])
+ _perimeter = query.first()
+ if _perimeter:
+ raise ClassTypeException
+ if not _perimeter:
if "policy_list" not in value or type(value["policy_list"]) is not list:
value["policy_list"] = []
if policy_id and policy_id not in value["policy_list"]:
value["policy_list"] = [policy_id, ]
- new = Subject.from_dict({
+
+ value_wo_name = copy.deepcopy(value)
+ value_wo_name.pop("name", None)
+ new = ClassType.from_dict({
"id": perimeter_id if perimeter_id else uuid4().hex,
- "value": value
+ "name": value["name"],
+ "value": value_wo_name
})
session.add(new)
return {new.id: new.to_return()}
else:
- _value = copy.deepcopy(_subject.to_dict())
+ _value = copy.deepcopy(_perimeter.to_dict())
if "policy_list" not in _value["value"] or type(_value["value"]["policy_list"]) is not list:
_value["value"]["policy_list"] = []
if policy_id and policy_id not in _value["value"]["policy_list"]:
_value["value"]["policy_list"].append(policy_id)
- new_subject = Subject.from_dict(_value)
- # setattr(_subject, "value", _value["value"])
- setattr(_subject, "value", getattr(new_subject, "value"))
- return {_subject.id: _subject.to_return()}
+ _value["value"].update(value)
+
+ name = _value["value"]["name"]
+ _value["value"].pop("name")
+ new_perimeter = ClassType.from_dict({
+ "id": _value["id"],
+ "name": name,
+ "value": _value["value"]
+ })
+ _perimeter.value = new_perimeter.value
+ _perimeter.name = new_perimeter.name
+ return {_perimeter.id: _perimeter.to_return()}
- def delete_subject(self, policy_id, perimeter_id):
+ def __delete_perimeter(self, ClassType, ClassUnknownException, policy_id, perimeter_id):
with self.get_session_for_write() as session:
- query = session.query(Subject)
+ query = session.query(ClassType)
query = query.filter_by(id=perimeter_id)
- _subject = query.first()
- if not _subject:
- raise SubjectUnknown
- old_subject = copy.deepcopy(_subject.to_dict())
- # value = _subject.to_dict()
+ _perimeter = query.first()
+ if not _perimeter:
+ raise ClassUnknownException
+ old_perimeter = copy.deepcopy(_perimeter.to_dict())
try:
- old_subject["value"]["policy_list"].remove(policy_id)
- new_user = Subject.from_dict(old_subject)
- setattr(_subject, "value", getattr(new_user, "value"))
+ old_perimeter["value"]["policy_list"].remove(policy_id)
+ new_perimeter = ClassType.from_dict(old_perimeter)
+ setattr(_perimeter, "value", getattr(new_perimeter, "value"))
except ValueError:
- if not _subject.value["policy_list"]:
- session.delete(_subject)
+ if not _perimeter.value["policy_list"]:
+ session.delete(_perimeter)
+
+ def get_subjects(self, policy_id, perimeter_id=None):
+ return self.__get_perimeters(Subject, policy_id, perimeter_id)
+
+ def set_subject(self, policy_id, perimeter_id=None, value=None):
+ try:
+ return self.__set_perimeter(Subject, exceptions.SubjectExisting, policy_id, perimeter_id=perimeter_id, value=value)
+ except sqlalchemy.exc.IntegrityError:
+ raise exceptions.SubjectExisting
+
+ def delete_subject(self, policy_id, perimeter_id):
+ self.__delete_perimeter(Subject, exceptions.SubjectUnknown, policy_id, perimeter_id)
def get_objects(self, policy_id, perimeter_id=None):
- with self.get_session_for_read() as session:
- query = session.query(Object)
- ref_list = copy.deepcopy(query.all())
- if perimeter_id:
- for _ref in ref_list:
- _ref_value = _ref.to_return()
- if perimeter_id == _ref.id:
- if policy_id and policy_id in _ref_value["policy_list"]:
- return {_ref.id: _ref_value}
- else:
- return {}
- elif policy_id:
- results = []
- for _ref in ref_list:
- _ref_value = _ref.to_return()
- if policy_id in _ref_value["policy_list"]:
- results.append(_ref)
- return {_ref.id: _ref.to_return() for _ref in results}
- return {_ref.id: _ref.to_return() for _ref in ref_list}
+ return self.__get_perimeters(Object, policy_id, perimeter_id)
def set_object(self, policy_id, perimeter_id=None, value=None):
- _object = None
- with self.get_session_for_write() as session:
- if perimeter_id:
- query = session.query(Object)
- query = query.filter_by(id=perimeter_id)
- _object = query.first()
- if not _object:
- if "policy_list" not in value or type(value["policy_list"]) is not list:
- value["policy_list"] = []
- if policy_id and policy_id not in value["policy_list"]:
- value["policy_list"] = [policy_id, ]
- new = Object.from_dict({
- "id": perimeter_id if perimeter_id else uuid4().hex,
- "value": value
- })
- session.add(new)
- return {new.id: new.to_return()}
- else:
- _value = copy.deepcopy(_object.to_dict())
- if "policy_list" not in _value["value"] or type(_value["value"]["policy_list"]) is not list:
- _value["value"]["policy_list"] = []
- if policy_id and policy_id not in _value["value"]["policy_list"]:
- _value["value"]["policy_list"].append(policy_id)
- new_object = Object.from_dict(_value)
- # setattr(_object, "value", _value["value"])
- setattr(_object, "value", getattr(new_object, "value"))
- return {_object.id: _object.to_return()}
+ try:
+ return self.__set_perimeter(Object, exceptions.ObjectExisting, policy_id, perimeter_id=perimeter_id, value=value)
+ except sqlalchemy.exc.IntegrityError as e:
+ logger.exception("IntegrityError {}".format(e))
+ raise exceptions.ObjectExisting
def delete_object(self, policy_id, perimeter_id):
- with self.get_session_for_write() as session:
- query = session.query(Object)
- query = query.filter_by(id=perimeter_id)
- _object = query.first()
- if not _object:
- raise ObjectUnknown
- old_object = copy.deepcopy(_object.to_dict())
- # value = _object.to_dict()
- try:
- old_object["value"]["policy_list"].remove(policy_id)
- new_user = Object.from_dict(old_object)
- setattr(_object, "value", getattr(new_user, "value"))
- except ValueError:
- if not _object.value["policy_list"]:
- session.delete(_object)
+ self.__delete_perimeter(Object, exceptions.ObjectUnknown, policy_id, perimeter_id)
def get_actions(self, policy_id, perimeter_id=None):
- with self.get_session_for_read() as session:
- query = session.query(Action)
- ref_list = copy.deepcopy(query.all())
- if perimeter_id:
- for _ref in ref_list:
- _ref_value = _ref.to_return()
- if perimeter_id == _ref.id:
- if policy_id and policy_id in _ref_value["policy_list"]:
- return {_ref.id: _ref_value}
- else:
- return {}
- elif policy_id:
- results = []
- for _ref in ref_list:
- _ref_value = _ref.to_return()
- if policy_id in _ref_value["policy_list"]:
- results.append(_ref)
- return {_ref.id: _ref.to_return() for _ref in results}
- return {_ref.id: _ref.to_return() for _ref in ref_list}
+ return self.__get_perimeters(Action, policy_id, perimeter_id)
def set_action(self, policy_id, perimeter_id=None, value=None):
- _action = None
- with self.get_session_for_write() as session:
- if perimeter_id:
- query = session.query(Action)
- query = query.filter_by(id=perimeter_id)
- _action = query.first()
- if not _action:
- if "policy_list" not in value or type(value["policy_list"]) is not list:
- value["policy_list"] = []
- if policy_id and policy_id not in value["policy_list"]:
- value["policy_list"] = [policy_id, ]
- new = Action.from_dict({
- "id": perimeter_id if perimeter_id else uuid4().hex,
- "value": value
- })
- session.add(new)
- return {new.id: new.to_return()}
- else:
- _value = copy.deepcopy(_action.to_dict())
- if "policy_list" not in _value["value"] or type(_value["value"]["policy_list"]) is not list:
- _value["value"]["policy_list"] = []
- if policy_id and policy_id not in _value["value"]["policy_list"]:
- _value["value"]["policy_list"].append(policy_id)
- new_action = Action.from_dict(_value)
- # setattr(_action, "value", _value["value"])
- setattr(_action, "value", getattr(new_action, "value"))
- return {_action.id: _action.to_return()}
+ try:
+ return self.__set_perimeter(Action, exceptions.ActionExisting, policy_id, perimeter_id=perimeter_id, value=value)
+ except sqlalchemy.exc.IntegrityError:
+ raise exceptions.ActionExisting
def delete_action(self, policy_id, perimeter_id):
- with self.get_session_for_write() as session:
- query = session.query(Action)
- query = query.filter_by(id=perimeter_id)
- _action = query.first()
- if not _action:
- raise ActionUnknown
- old_action = copy.deepcopy(_action.to_dict())
- # value = _action.to_dict()
- try:
- old_action["value"]["policy_list"].remove(policy_id)
- new_user = Action.from_dict(old_action)
- setattr(_action, "value", getattr(new_user, "value"))
- except ValueError:
- if not _action.value["policy_list"]:
- session.delete(_action)
+ self.__delete_perimeter(Action, exceptions.ActionUnknown, policy_id, perimeter_id)
- def get_subject_data(self, policy_id, data_id=None, category_id=None):
- logger.info("driver {} {} {}".format(policy_id, data_id, category_id))
+ def __is_data_exist(self, ClassType, data_id=None, category_id=None):
+ if not data_id:
+ return False
with self.get_session_for_read() as session:
- query = session.query(SubjectData)
- if data_id:
+ query = session.query(ClassType)
+ query = query.filter_by(category_id=category_id)
+ ref_list = query.all()
+ if ref_list:
+ return True
+ return False
+
+ def __get_data(self, ClassType, policy_id, data_id=None, category_id=None):
+ with self.get_session_for_read() as session:
+ query = session.query(ClassType)
+ if policy_id and data_id and category_id:
query = query.filter_by(policy_id=policy_id, id=data_id, category_id=category_id)
- else:
+ elif policy_id and category_id:
query = query.filter_by(policy_id=policy_id, category_id=category_id)
+ else:
+ query = query.filter_by(category_id=category_id)
ref_list = query.all()
- logger.info("ref_list={}".format(ref_list))
return {
"policy_id": policy_id,
"category_id": category_id,
"data": {_ref.id: _ref.to_dict() for _ref in ref_list}
}
- def set_subject_data(self, policy_id, data_id=None, category_id=None, value=None):
+ def __set_data(self, ClassType, ClassTypeData, policy_id, data_id=None, category_id=None, value=None):
with self.get_session_for_write() as session:
- query = session.query(SubjectData)
+ query = session.query(ClassTypeData)
query = query.filter_by(policy_id=policy_id, id=data_id, category_id=category_id)
ref = query.first()
if not ref:
- new_ref = SubjectData.from_dict(
+ value_wo_name = copy.deepcopy(value)
+ value_wo_name.pop("name", None)
+ new_ref = ClassTypeData.from_dict(
{
"id": data_id if data_id else uuid4().hex,
- 'value': value,
+ 'name': value["name"],
+ 'value': value_wo_name,
'category_id': category_id,
'policy_id': policy_id,
}
@@ -680,7 +602,7 @@ class PolicyConnector(BaseConnector, PolicyDriver):
session.add(new_ref)
ref = new_ref
else:
- for attr in Subject.attributes:
+ for attr in ClassType.attributes:
if attr != 'id':
setattr(ref, attr, getattr(ref, attr))
# session.flush()
@@ -690,116 +612,64 @@ class PolicyConnector(BaseConnector, PolicyDriver):
"data": {ref.id: ref.to_dict()}
}
- def delete_subject_data(self, policy_id, data_id):
+ def __delete_data(self, ClassType, policy_id, data_id):
with self.get_session_for_write() as session:
- query = session.query(SubjectData)
+ query = session.query(ClassType)
query = query.filter_by(policy_id=policy_id, id=data_id)
ref = query.first()
if ref:
session.delete(ref)
+ def is_subject_data_exist(self, data_id=None, category_id=None):
+ return self.__is_data_exist(SubjectData, data_id=data_id, category_id=category_id)
+
+ def get_subject_data(self, policy_id, data_id=None, category_id=None):
+ return self.__get_data(SubjectData, policy_id, data_id=data_id, category_id=category_id)
+
+ def set_subject_data(self, policy_id, data_id=None, category_id=None, value=None):
+ try:
+ return self.__set_data(Subject, SubjectData, policy_id, data_id=data_id, category_id=category_id, value=value)
+ except sqlalchemy.exc.IntegrityError:
+ raise exceptions.SubjectScopeExisting
+
+ def delete_subject_data(self, policy_id, data_id):
+ return self.__delete_data(SubjectData, policy_id, data_id)
+
+ def is_object_data_exist(self, data_id=None, category_id=None):
+ return self.__is_data_exist(ObjectData, data_id=data_id, category_id=category_id)
+
def get_object_data(self, policy_id, data_id=None, category_id=None):
- with self.get_session_for_read() as session:
- query = session.query(ObjectData)
- if data_id:
- query = query.filter_by(policy_id=policy_id, id=data_id, category_id=category_id)
- else:
- query = query.filter_by(policy_id=policy_id, category_id=category_id)
- ref_list = query.all()
- return {
- "policy_id": policy_id,
- "category_id": category_id,
- "data": {_ref.id: _ref.to_dict() for _ref in ref_list}
- }
+ return self.__get_data(ObjectData, policy_id, data_id=data_id, category_id=category_id)
def set_object_data(self, policy_id, data_id=None, category_id=None, value=None):
- with self.get_session_for_write() as session:
- query = session.query(ObjectData)
- query = query.filter_by(policy_id=policy_id, id=data_id, category_id=category_id)
- ref = query.first()
- if not ref:
- new_ref = ObjectData.from_dict(
- {
- "id": data_id if data_id else uuid4().hex,
- 'value': value,
- 'category_id': category_id,
- 'policy_id': policy_id,
- }
- )
- session.add(new_ref)
- ref = new_ref
- else:
- for attr in Object.attributes:
- if attr != 'id':
- setattr(ref, attr, getattr(ref, attr))
- # session.flush()
- return {
- "policy_id": policy_id,
- "category_id": category_id,
- "data": {ref.id: ref.to_dict()}
- }
+ try:
+ return self.__set_data(Object, ObjectData, policy_id, data_id=data_id, category_id=category_id, value=value)
+ except sqlalchemy.exc.IntegrityError:
+ raise exceptions.ObjectScopeExisting
def delete_object_data(self, policy_id, data_id):
- with self.get_session_for_write() as session:
- query = session.query(ObjectData)
- query = query.filter_by(policy_id=policy_id, id=data_id)
- ref = query.first()
- if ref:
- session.delete(ref)
+ return self.__delete_data(ObjectData, policy_id, data_id)
+
+ def is_action_data_exist(self, data_id=None,category_id=None):
+ return self.__is_data_exist(ActionData, data_id=data_id, category_id=category_id)
def get_action_data(self, policy_id, data_id=None, category_id=None):
- with self.get_session_for_read() as session:
- query = session.query(ActionData)
- if data_id:
- query = query.filter_by(policy_id=policy_id, id=data_id, category_id=category_id)
- else:
- query = query.filter_by(policy_id=policy_id, category_id=category_id)
- ref_list = query.all()
- return {
- "policy_id": policy_id,
- "category_id": category_id,
- "data": {_ref.id: _ref.to_dict() for _ref in ref_list}
- }
+ return self.__get_data(ActionData, policy_id, data_id=data_id, category_id=category_id)
def set_action_data(self, policy_id, data_id=None, category_id=None, value=None):
- with self.get_session_for_write() as session:
- query = session.query(ActionData)
- query = query.filter_by(policy_id=policy_id, id=data_id, category_id=category_id)
- ref = query.first()
- if not ref:
- new_ref = ActionData.from_dict(
- {
- "id": data_id if data_id else uuid4().hex,
- 'value': value,
- 'category_id': category_id,
- 'policy_id': policy_id,
- }
- )
- session.add(new_ref)
- ref = new_ref
- else:
- for attr in Action.attributes:
- if attr != 'id':
- setattr(ref, attr, getattr(ref, attr))
- # session.flush()
- return {
- "policy_id": policy_id,
- "category_id": category_id,
- "data": {ref.id: ref.to_dict()}
- }
+ try:
+ return self.__set_data(Action, ActionData, policy_id, data_id=data_id, category_id=category_id, value=value)
+ except sqlalchemy.exc.IntegrityError:
+ raise exceptions.ActionScopeExisting
def delete_action_data(self, policy_id, data_id):
- with self.get_session_for_write() as session:
- query = session.query(ActionData)
- query = query.filter_by(policy_id=policy_id, id=data_id)
- ref = query.first()
- if ref:
- session.delete(ref)
+ return self.__delete_data(ActionData, policy_id, data_id)
def get_subject_assignments(self, policy_id, subject_id=None, category_id=None):
with self.get_session_for_write() as session:
query = session.query(SubjectAssignment)
if subject_id and category_id:
+ #TODO change the subject_id to perimeter_id to allow code refactoring
query = query.filter_by(policy_id=policy_id, subject_id=subject_id, category_id=category_id)
elif subject_id:
query = query.filter_by(policy_id=policy_id, subject_id=subject_id)
@@ -819,6 +689,8 @@ class PolicyConnector(BaseConnector, PolicyDriver):
if data_id not in assignments:
assignments.append(data_id)
setattr(ref, "assignments", assignments)
+ else:
+ raise exceptions.SubjectAssignmentExisting
else:
ref = SubjectAssignment.from_dict(
{
@@ -852,6 +724,7 @@ class PolicyConnector(BaseConnector, PolicyDriver):
with self.get_session_for_write() as session:
query = session.query(ObjectAssignment)
if object_id and category_id:
+ #TODO change the object_id to perimeter_id to allow code refactoring
query = query.filter_by(policy_id=policy_id, object_id=object_id, category_id=category_id)
elif object_id:
query = query.filter_by(policy_id=policy_id, object_id=object_id)
@@ -871,6 +744,8 @@ class PolicyConnector(BaseConnector, PolicyDriver):
if data_id not in assignments:
assignments.append(data_id)
setattr(ref, "assignments", assignments)
+ else:
+ raise exceptions.ObjectAssignmentExisting
else:
ref = ObjectAssignment.from_dict(
{
@@ -904,6 +779,7 @@ class PolicyConnector(BaseConnector, PolicyDriver):
with self.get_session_for_write() as session:
query = session.query(ActionAssignment)
if action_id and category_id:
+ # TODO change the action_id to perimeter_id to allow code refactoring
query = query.filter_by(policy_id=policy_id, action_id=action_id, category_id=category_id)
elif action_id:
query = query.filter_by(policy_id=policy_id, action_id=action_id)
@@ -923,6 +799,8 @@ class PolicyConnector(BaseConnector, PolicyDriver):
if data_id not in assignments:
assignments.append(data_id)
setattr(ref, "assignments", assignments)
+ else:
+ raise exceptions.ActionAssignmentExisting
else:
ref = ActionAssignment.from_dict(
{
@@ -976,13 +854,12 @@ class PolicyConnector(BaseConnector, PolicyDriver):
}
def add_rule(self, policy_id, meta_rule_id, value):
- with self.get_session_for_write() as session:
- query = session.query(Rule)
- query = query.filter_by(policy_id=policy_id, meta_rule_id=meta_rule_id)
- ref_list = query.all()
- rules = list(map(lambda x: x.rule, ref_list))
- if not rules or value not in rules:
- logger.info("add_rule IN IF")
+ try:
+ rules = self.get_rules(policy_id, meta_rule_id=meta_rule_id)
+ for _rule in map(lambda x: x["rule"], rules["rules"]):
+ if list(value.get('rule')) == list(_rule):
+ raise exceptions.RuleExisting
+ with self.get_session_for_write() as session:
ref = Rule.from_dict(
{
"id": uuid4().hex,
@@ -993,7 +870,8 @@ class PolicyConnector(BaseConnector, PolicyDriver):
)
session.add(ref)
return {ref.id: ref.to_dict()}
- return {}
+ except sqlalchemy.exc.IntegrityError:
+ raise exceptions.RuleExisting
def delete_rule(self, policy_id, rule_id):
with self.get_session_for_write() as session:
@@ -1013,8 +891,11 @@ class ModelConnector(BaseConnector, ModelDriver):
query = query.filter_by(id=model_id)
ref = query.first()
if ref:
+ value_wo_name = copy.deepcopy(value)
+ value_wo_name.pop("name", None)
+ setattr(ref, "name", value["name"])
d = dict(ref.value)
- d.update(value)
+ d.update(value_wo_name)
setattr(ref, "value", d)
return {ref.id: ref.to_dict()}
@@ -1024,13 +905,19 @@ class ModelConnector(BaseConnector, ModelDriver):
session.delete(ref)
def add_model(self, model_id=None, value=None):
- with self.get_session_for_write() as session:
- new = Model.from_dict({
- "id": model_id if model_id else uuid4().hex,
- "value": value
- })
- session.add(new)
- return {new.id: new.to_dict()}
+ try:
+ with self.get_session_for_write() as session:
+ value_wo_name = copy.deepcopy(value)
+ value_wo_name.pop("name", None)
+ new = Model.from_dict({
+ "id": model_id if model_id else uuid4().hex,
+ "name": value["name"],
+ "value": value_wo_name
+ })
+ session.add(new)
+ return {new.id: new.to_dict()}
+ except sqlalchemy.exc.IntegrityError as e:
+ raise exceptions.ModelExisting
def get_models(self, model_id=None):
with self.get_session_for_read() as session:
@@ -1039,23 +926,41 @@ class ModelConnector(BaseConnector, ModelDriver):
ref_list = query.filter(Model.id == model_id)
else:
ref_list = query.all()
- return {_ref.id: _ref.to_dict() for _ref in ref_list}
+
+ r = {_ref.id: _ref.to_dict() for _ref in ref_list}
+ return r
def set_meta_rule(self, meta_rule_id, value):
with self.get_session_for_write() as session:
- query = session.query(MetaRule)
- query = query.filter_by(id=meta_rule_id)
- ref = query.first()
- if not ref:
- ref = MetaRule.from_dict(
- {
- "id": meta_rule_id if meta_rule_id else uuid4().hex,
- "value": value
- }
- )
- session.add(ref)
+ value_wo_other_data = copy.deepcopy(value)
+ value_wo_other_data.pop("name", None)
+ value_wo_other_data.pop("subject_categories", None)
+ value_wo_other_data.pop("object_categories", None)
+ value_wo_other_data.pop("action_categories", None)
+ if meta_rule_id is None:
+ try:
+ ref = MetaRule.from_dict(
+ {
+ "id": uuid4().hex,
+ "name": value["name"],
+ "subject_categories": value["subject_categories"],
+ "object_categories": value["object_categories"],
+ "action_categories": value["action_categories"],
+ "value": value_wo_other_data
+ }
+ )
+ session.add(ref)
+ except sqlalchemy.exc.IntegrityError as e:
+ raise exceptions.MetaRuleExisting
else:
- setattr(ref, "value", value)
+ query = session.query(MetaRule)
+ query = query.filter_by(id=meta_rule_id)
+ ref = query.first()
+ setattr(ref, "name", value["name"])
+ setattr(ref, "subject_categories", value["subject_categories"])
+ setattr(ref, "object_categories", value["object_categories"])
+ setattr(ref, "action_categories", value["action_categories"])
+ setattr(ref, "value", value_wo_other_data)
return {ref.id: ref.to_dict()}
def get_meta_rules(self, meta_rule_id=None):
@@ -1074,101 +979,73 @@ class ModelConnector(BaseConnector, ModelDriver):
if ref:
session.delete(ref)
- def get_subject_categories(self, category_id=None):
+ def __get_perimeter_categories(self, ClassType, category_id=None):
with self.get_session_for_read() as session:
- query = session.query(SubjectCategory)
+ query = session.query(ClassType)
if category_id:
query = query.filter_by(id=category_id)
ref_list = query.all()
return {_ref.id: _ref.to_dict() for _ref in ref_list}
- def add_subject_category(self, name, description, uuid=None):
+ def __add_perimeter_category(self, ClassType, name, description, uuid=None):
+ if not name.strip():
+ raise exceptions.CategoryNameInvalid
with self.get_session_for_write() as session:
- query = session.query(SubjectCategory)
- query = query.filter_by(name=name)
- ref = query.first()
- if not ref:
- ref = SubjectCategory.from_dict(
- {
- "id": uuid if uuid else uuid4().hex,
- "name": name,
- "description": description
- }
- )
- session.add(ref)
+ ref = ClassType.from_dict(
+ {
+ "id": uuid if uuid else uuid4().hex,
+ "name": name,
+ "description": description
+ }
+ )
+ session.add(ref)
return {ref.id: ref.to_dict()}
- def delete_subject_category(self, category_id):
+ def __delete_perimeter_category(self, ClassType, category_id):
with self.get_session_for_write() as session:
- query = session.query(SubjectCategory)
+ query = session.query(ClassType)
query = query.filter_by(id=category_id)
ref = query.first()
if ref:
session.delete(ref)
+ def get_subject_categories(self, category_id=None):
+ return self.__get_perimeter_categories(SubjectCategory, category_id=category_id)
+
+ def add_subject_category(self, name, description, uuid=None):
+ try:
+ return self.__add_perimeter_category(SubjectCategory, name, description, uuid=uuid)
+ except sql.exc.IntegrityError as e:
+ raise exceptions.SubjectCategoryExisting()
+
+ def delete_subject_category(self, category_id):
+ self.__delete_perimeter_category(SubjectCategory, category_id)
+
def get_object_categories(self, category_id=None):
- with self.get_session_for_read() as session:
- query = session.query(ObjectCategory)
- if category_id:
- query = query.filter_by(id=category_id)
- ref_list = query.all()
- return {_ref.id: _ref.to_dict() for _ref in ref_list}
+ return self.__get_perimeter_categories(ObjectCategory, category_id=category_id)
def add_object_category(self, name, description, uuid=None):
- with self.get_session_for_write() as session:
- query = session.query(ObjectCategory)
- query = query.filter_by(name=name)
- ref = query.first()
- if not ref:
- ref = ObjectCategory.from_dict(
- {
- "id": uuid if uuid else uuid4().hex,
- "name": name,
- "description": description
- }
- )
- session.add(ref)
- return {ref.id: ref.to_dict()}
+ try:
+ return self.__add_perimeter_category(ObjectCategory, name, description, uuid=uuid)
+ except sql.exc.IntegrityError as e:
+ raise exceptions.ObjectCategoryExisting()
def delete_object_category(self, category_id):
- with self.get_session_for_write() as session:
- query = session.query(ObjectCategory)
- query = query.filter_by(id=category_id)
- ref = query.first()
- if ref:
- session.delete(ref)
+ self.__delete_perimeter_category(ObjectCategory, category_id)
def get_action_categories(self, category_id=None):
- with self.get_session_for_read() as session:
- query = session.query(ActionCategory)
- if category_id:
- query = query.filter_by(id=category_id)
- ref_list = query.all()
- return {_ref.id: _ref.to_dict() for _ref in ref_list}
+
+ return self.__get_perimeter_categories(ActionCategory, category_id=category_id)
def add_action_category(self, name, description, uuid=None):
- with self.get_session_for_write() as session:
- query = session.query(ActionCategory)
- query = query.filter_by(name=name)
- ref = query.first()
- if not ref:
- ref = ActionCategory.from_dict(
- {
- "id": uuid if uuid else uuid4().hex,
- "name": name,
- "description": description
- }
- )
- session.add(ref)
- return {ref.id: ref.to_dict()}
+ try:
+ return self.__add_perimeter_category(ActionCategory, name, description, uuid=uuid)
+ except sql.exc.IntegrityError as e:
+ raise exceptions.ActionCategoryExisting()
def delete_action_category(self, category_id):
- with self.get_session_for_write() as session:
- query = session.query(ActionCategory)
- query = query.filter_by(id=category_id)
- ref = query.first()
- if ref:
- session.delete(ref)
+ self.__delete_perimeter_category(ActionCategory, category_id)
+
# Getter and Setter for subject_category
# def get_subject_categories_dict(self, intra_extension_id):
diff --git a/python_moondb/python_moondb/migrate_repo/versions/001_moon.py b/python_moondb/python_moondb/migrate_repo/versions/001_moon.py
index 2cc36140..1bfb2ffa 100644
--- a/python_moondb/python_moondb/migrate_repo/versions/001_moon.py
+++ b/python_moondb/python_moondb/migrate_repo/versions/001_moon.py
@@ -3,7 +3,19 @@
# license which can be found in the file 'LICENSE' in this package distribution
# or at 'http://www.apache.org/licenses/LICENSE-2.0'.
+import json
import sqlalchemy as sql
+from sqlalchemy import types as sql_types
+
+class JsonBlob(sql_types.TypeDecorator):
+
+ impl = sql.Text
+
+ def process_bind_param(self, value, dialect):
+ return json.dumps(value)
+
+ def process_result_value(self, value, dialect):
+ return json.loads(value)
def upgrade(migrate_engine):
@@ -14,7 +26,10 @@ def upgrade(migrate_engine):
'pdp',
meta,
sql.Column('id', sql.String(64), primary_key=True),
- sql.Column('value', sql.Text(), nullable=True),
+ sql.Column('name', sql.String(256), nullable=False),
+ sql.Column('keystone_project_id', sql.String(64), nullable=True, default=""),
+ sql.Column('value', JsonBlob(), nullable=True),
+ sql.UniqueConstraint('name', 'keystone_project_id', name='unique_constraint_models'),
mysql_engine='InnoDB',
mysql_charset='utf8')
table.create(migrate_engine, checkfirst=True)
@@ -23,7 +38,10 @@ def upgrade(migrate_engine):
'policies',
meta,
sql.Column('id', sql.String(64), primary_key=True),
- sql.Column('value', sql.Text(), nullable=True),
+ sql.Column('name', sql.String(256), nullable=False),
+ sql.Column('model_id', sql.String(64), nullable=True, default=""),
+ sql.Column('value', JsonBlob(), nullable=True),
+ sql.UniqueConstraint('name', 'model_id', name='unique_constraint_models'),
mysql_engine='InnoDB',
mysql_charset='utf8')
table.create(migrate_engine, checkfirst=True)
@@ -32,7 +50,9 @@ def upgrade(migrate_engine):
'models',
meta,
sql.Column('id', sql.String(64), primary_key=True),
- sql.Column('value', sql.Text(), nullable=True),
+ sql.Column('name', sql.String(256), nullable=False),
+ sql.Column('value', JsonBlob(), nullable=True),
+ sql.UniqueConstraint('name', name='unique_constraint_models'),
mysql_engine='InnoDB',
mysql_charset='utf8')
table.create(migrate_engine, checkfirst=True)
@@ -43,6 +63,8 @@ def upgrade(migrate_engine):
sql.Column('id', sql.String(64), primary_key=True),
sql.Column('name', sql.String(256), nullable=False),
sql.Column('description', sql.String(256), nullable=True),
+
+ sql.UniqueConstraint('name', name='unique_constraint_subject_categories'),
mysql_engine='InnoDB',
mysql_charset='utf8')
subject_categories_table.create(migrate_engine, checkfirst=True)
@@ -53,6 +75,8 @@ def upgrade(migrate_engine):
sql.Column('id', sql.String(64), primary_key=True),
sql.Column('name', sql.String(256), nullable=False),
sql.Column('description', sql.String(256), nullable=True),
+
+ sql.UniqueConstraint('name', name='unique_constraint_object_categories'),
mysql_engine='InnoDB',
mysql_charset='utf8')
object_categories_table.create(migrate_engine, checkfirst=True)
@@ -63,6 +87,8 @@ def upgrade(migrate_engine):
sql.Column('id', sql.String(64), primary_key=True),
sql.Column('name', sql.String(256), nullable=False),
sql.Column('description', sql.String(256), nullable=True),
+
+ sql.UniqueConstraint('name', name='unique_constraint_action_categories'),
mysql_engine='InnoDB',
mysql_charset='utf8')
action_categories_table.create(migrate_engine, checkfirst=True)
@@ -71,7 +97,9 @@ def upgrade(migrate_engine):
'subjects',
meta,
sql.Column('id', sql.String(64), primary_key=True),
- sql.Column('value', sql.Text(), nullable=True),
+ sql.Column('name', sql.String(256), nullable=False),
+ sql.Column('value', JsonBlob(), nullable=True),
+ sql.UniqueConstraint('name', name='unique_constraint_subjects'),
mysql_engine='InnoDB',
mysql_charset='utf8')
subjects_table.create(migrate_engine, checkfirst=True)
@@ -80,7 +108,9 @@ def upgrade(migrate_engine):
'objects',
meta,
sql.Column('id', sql.String(64), primary_key=True),
- sql.Column('value', sql.Text(), nullable=True),
+ sql.Column('name', sql.String(256), nullable=False),
+ sql.Column('value', JsonBlob(), nullable=True),
+ sql.UniqueConstraint('name', name='unique_constraint_objects'),
mysql_engine='InnoDB',
mysql_charset='utf8')
objects_table.create(migrate_engine, checkfirst=True)
@@ -89,7 +119,9 @@ def upgrade(migrate_engine):
'actions',
meta,
sql.Column('id', sql.String(64), primary_key=True),
- sql.Column('value', sql.Text(), nullable=True),
+ sql.Column('name', sql.String(256), nullable=False),
+ sql.Column('value', JsonBlob(), nullable=True),
+ sql.UniqueConstraint('name', name='unique_constraint_actions'),
mysql_engine='InnoDB',
mysql_charset='utf8')
actions_table.create(migrate_engine, checkfirst=True)
@@ -98,9 +130,11 @@ def upgrade(migrate_engine):
'subject_data',
meta,
sql.Column('id', sql.String(64), primary_key=True),
- sql.Column('value', sql.Text(), nullable=True),
+ sql.Column('name', sql.String(256), nullable=False),
+ sql.Column('value', JsonBlob(), nullable=True),
sql.Column('category_id', sql.ForeignKey("subject_categories.id"), nullable=False),
sql.Column('policy_id', sql.ForeignKey("policies.id"), nullable=False),
+ sql.UniqueConstraint('name', 'category_id', 'policy_id', name='unique_constraint_subject_data'),
mysql_engine='InnoDB',
mysql_charset='utf8')
subject_data_table.create(migrate_engine, checkfirst=True)
@@ -109,9 +143,11 @@ def upgrade(migrate_engine):
'object_data',
meta,
sql.Column('id', sql.String(64), primary_key=True),
- sql.Column('value', sql.Text(), nullable=True),
+ sql.Column('name', sql.String(256), nullable=False),
+ sql.Column('value', JsonBlob(), nullable=True),
sql.Column('category_id', sql.ForeignKey("object_categories.id"), nullable=False),
sql.Column('policy_id', sql.ForeignKey("policies.id"), nullable=False),
+ sql.UniqueConstraint('name', 'category_id', 'policy_id', name='unique_constraint_object_data'),
mysql_engine='InnoDB',
mysql_charset='utf8')
object_data_table.create(migrate_engine, checkfirst=True)
@@ -120,9 +156,11 @@ def upgrade(migrate_engine):
'action_data',
meta,
sql.Column('id', sql.String(64), primary_key=True),
- sql.Column('value', sql.Text(), nullable=True),
+ sql.Column('name', sql.String(256), nullable=False),
+ sql.Column('value', JsonBlob(), nullable=True),
sql.Column('category_id', sql.ForeignKey("action_categories.id"), nullable=False),
sql.Column('policy_id', sql.ForeignKey("policies.id"), nullable=False),
+ sql.UniqueConstraint('name', 'category_id', 'policy_id', name='unique_constraint_action_data'),
mysql_engine='InnoDB',
mysql_charset='utf8')
action_data_table.create(migrate_engine, checkfirst=True)
@@ -131,10 +169,11 @@ def upgrade(migrate_engine):
'subject_assignments',
meta,
sql.Column('id', sql.String(64), primary_key=True),
- sql.Column('assignments', sql.Text(), nullable=True),
+ sql.Column('assignments', sql.String(256), nullable=True),
sql.Column('policy_id', sql.ForeignKey("policies.id"), nullable=False),
sql.Column('subject_id', sql.ForeignKey("subjects.id"), nullable=False),
sql.Column('category_id', sql.ForeignKey("subject_categories.id"), nullable=False),
+ sql.UniqueConstraint('policy_id', 'subject_id', 'category_id', name='unique_constraint_subject_assignment'),
mysql_engine='InnoDB',
mysql_charset='utf8')
subject_assignments_table.create(migrate_engine, checkfirst=True)
@@ -143,10 +182,11 @@ def upgrade(migrate_engine):
'object_assignments',
meta,
sql.Column('id', sql.String(64), primary_key=True),
- sql.Column('assignments', sql.Text(), nullable=True),
+ sql.Column('assignments', sql.String(256), nullable=True),
sql.Column('policy_id', sql.ForeignKey("policies.id"), nullable=False),
sql.Column('object_id', sql.ForeignKey("objects.id"), nullable=False),
sql.Column('category_id', sql.ForeignKey("object_categories.id"), nullable=False),
+ sql.UniqueConstraint('policy_id', 'object_id', 'category_id', name='unique_constraint_object_assignment'),
mysql_engine='InnoDB',
mysql_charset='utf8')
object_assignments_table.create(migrate_engine, checkfirst=True)
@@ -155,10 +195,11 @@ def upgrade(migrate_engine):
'action_assignments',
meta,
sql.Column('id', sql.String(64), primary_key=True),
- sql.Column('assignments', sql.Text(), nullable=True),
+ sql.Column('assignments', sql.String(256), nullable=True),
sql.Column('policy_id', sql.ForeignKey("policies.id"), nullable=False),
sql.Column('action_id', sql.ForeignKey("actions.id"), nullable=False),
sql.Column('category_id', sql.ForeignKey("action_categories.id"), nullable=False),
+ sql.UniqueConstraint('policy_id', 'action_id', 'category_id', name='unique_constraint_action_assignment'),
mysql_engine='InnoDB',
mysql_charset='utf8')
action_assignments_table.create(migrate_engine, checkfirst=True)
@@ -167,7 +208,13 @@ def upgrade(migrate_engine):
'meta_rules',
meta,
sql.Column('id', sql.String(64), primary_key=True),
- sql.Column('value', sql.Text(), nullable=True),
+ sql.Column('name', sql.String(256), nullable=False),
+ sql.Column('subject_categories', JsonBlob(), nullable=False),
+ sql.Column('object_categories', JsonBlob(), nullable=False),
+ sql.Column('action_categories', JsonBlob(), nullable=False),
+ sql.Column('value', JsonBlob(), nullable=True),
+ sql.UniqueConstraint('name', name='unique_constraint_meta_rule_name'),
+ # sql.UniqueConstraint('subject_categories', 'object_categories', 'action_categories', name='unique_constraint_meta_rule_def'),
mysql_engine='InnoDB',
mysql_charset='utf8')
meta_rules_table.create(migrate_engine, checkfirst=True)
@@ -176,7 +223,7 @@ def upgrade(migrate_engine):
'rules',
meta,
sql.Column('id', sql.String(64), primary_key=True),
- sql.Column('rule', sql.Text(), nullable=True),
+ sql.Column('rule', JsonBlob(), nullable=True),
sql.Column('policy_id', sql.ForeignKey("policies.id"), nullable=False),
sql.Column('meta_rule_id', sql.ForeignKey("meta_rules.id"), nullable=False),
mysql_engine='InnoDB',
diff --git a/python_moondb/tests/unit_python/helpers/__init__.py b/python_moondb/tests/unit_python/helpers/__init__.py
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/python_moondb/tests/unit_python/helpers/__init__.py
diff --git a/python_moondb/tests/unit_python/helpers/assignment_helper.py b/python_moondb/tests/unit_python/helpers/assignment_helper.py
new file mode 100644
index 00000000..22a56e38
--- /dev/null
+++ b/python_moondb/tests/unit_python/helpers/assignment_helper.py
@@ -0,0 +1,49 @@
+# 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'.
+
+def get_action_assignments(policy_id, action_id=None, category_id=None):
+ from python_moondb.core import PolicyManager
+ return PolicyManager.get_action_assignments("", policy_id, action_id, category_id)
+
+
+def add_action_assignment(policy_id, action_id, category_id, data_id):
+ from python_moondb.core import PolicyManager
+ return PolicyManager.add_action_assignment("", policy_id, action_id, category_id, data_id)
+
+
+def delete_action_assignment(policy_id, action_id, category_id, data_id):
+ from python_moondb.core import PolicyManager
+ PolicyManager.delete_action_assignment("", policy_id, action_id, category_id, data_id)
+
+
+def get_object_assignments(policy_id, object_id=None, category_id=None):
+ from python_moondb.core import PolicyManager
+ return PolicyManager.get_object_assignments("", policy_id, object_id, category_id)
+
+
+def add_object_assignment(policy_id, object_id, category_id, data_id):
+ from python_moondb.core import PolicyManager
+ return PolicyManager.add_object_assignment("", policy_id, object_id, category_id, data_id)
+
+
+def delete_object_assignment(policy_id, object_id, category_id, data_id):
+ from python_moondb.core import PolicyManager
+ PolicyManager.delete_object_assignment("", policy_id, object_id, category_id, data_id)
+
+
+def get_subject_assignments(policy_id, subject_id=None, category_id=None):
+ from python_moondb.core import PolicyManager
+ return PolicyManager.get_subject_assignments("", policy_id, subject_id, category_id)
+
+
+def add_subject_assignment(policy_id, subject_id, category_id, data_id):
+ from python_moondb.core import PolicyManager
+ return PolicyManager.add_subject_assignment("", policy_id, subject_id, category_id, data_id)
+
+
+def delete_subject_assignment(policy_id, subject_id, category_id, data_id):
+ from python_moondb.core import PolicyManager
+ PolicyManager.delete_subject_assignment("", policy_id, subject_id, category_id, data_id)
+
diff --git a/python_moondb/tests/unit_python/helpers/category_helper.py b/python_moondb/tests/unit_python/helpers/category_helper.py
new file mode 100644
index 00000000..55e95d91
--- /dev/null
+++ b/python_moondb/tests/unit_python/helpers/category_helper.py
@@ -0,0 +1,54 @@
+# 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'.
+
+def add_subject_category(cat_id=None, value=None):
+ from python_moondb.core import ModelManager
+ category = ModelManager.add_subject_category(user_id=None, category_id=cat_id, value=value)
+ return category
+
+
+def get_subject_category(cat_id=None):
+ from python_moondb.core import ModelManager
+ category = ModelManager.get_subject_categories(user_id=None, category_id=cat_id)
+ return category
+
+
+def add_object_category(cat_id=None, value=None):
+ from python_moondb.core import ModelManager
+ category = ModelManager.add_object_category(user_id=None, category_id=cat_id, value=value)
+ return category
+
+
+def get_object_category(cat_id=None):
+ from python_moondb.core import ModelManager
+ category = ModelManager.get_object_categories(user_id=None, category_id=cat_id)
+ return category
+
+
+def add_action_category(cat_id=None, value=None):
+ from python_moondb.core import ModelManager
+ category = ModelManager.add_action_category(user_id=None, category_id=cat_id, value=value)
+ return category
+
+
+def get_action_category(cat_id=None):
+ from python_moondb.core import ModelManager
+ category = ModelManager.get_action_categories(user_id=None, category_id=cat_id)
+ return category
+
+
+def delete_subject_category(category_id=None):
+ from python_moondb.core import ModelManager
+ return ModelManager.delete_subject_category("", category_id=category_id)
+
+
+def delete_object_category(category_id=None):
+ from python_moondb.core import ModelManager
+ return ModelManager.delete_object_category("", category_id=category_id)
+
+
+def delete_action_category(category_id=None):
+ from python_moondb.core import ModelManager
+ return ModelManager.delete_action_category("", category_id=category_id)
diff --git a/python_moondb/tests/unit_python/helpers/data_helper.py b/python_moondb/tests/unit_python/helpers/data_helper.py
new file mode 100644
index 00000000..20d9ae9a
--- /dev/null
+++ b/python_moondb/tests/unit_python/helpers/data_helper.py
@@ -0,0 +1,98 @@
+# 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'.
+
+def get_action_data(policy_id, data_id=None, category_id=None):
+ from python_moondb.core import PolicyManager
+ return PolicyManager.get_action_data("", policy_id, data_id, category_id)
+
+
+def add_action_data(policy_id, data_id=None, category_id=None, value=None):
+ from python_moondb.core import PolicyManager
+ return PolicyManager.add_action_data("", policy_id, data_id, category_id, value)
+
+
+def delete_action_data(policy_id, data_id):
+ from python_moondb.core import PolicyManager
+ PolicyManager.delete_action_data("", policy_id, data_id)
+
+
+def get_object_data(policy_id, data_id=None, category_id=None):
+ from python_moondb.core import PolicyManager
+ return PolicyManager.get_object_data("", policy_id, data_id, category_id)
+
+
+def add_object_data(policy_id, data_id=None, category_id=None, value=None):
+ from python_moondb.core import PolicyManager
+ return PolicyManager.add_object_data("", policy_id, data_id, category_id, value)
+
+
+def delete_object_data(policy_id, data_id):
+ from python_moondb.core import PolicyManager
+ PolicyManager.delete_object_data("", policy_id, data_id)
+
+
+def get_subject_data(policy_id, data_id=None, category_id=None):
+ from python_moondb.core import PolicyManager
+ return PolicyManager.get_subject_data("", policy_id, data_id, category_id)
+
+
+def add_subject_data(policy_id, data_id=None, category_id=None, value=None):
+ from python_moondb.core import PolicyManager
+ return PolicyManager.set_subject_data("", policy_id, data_id, category_id, value)
+
+
+def delete_subject_data(policy_id, data_id):
+ from python_moondb.core import PolicyManager
+ PolicyManager.delete_subject_data("", policy_id, data_id)
+
+
+def get_actions(policy_id, perimeter_id=None):
+ from python_moondb.core import PolicyManager
+ return PolicyManager.get_actions("", policy_id, perimeter_id)
+
+
+def add_action(policy_id, perimeter_id=None, value=None):
+ from python_moondb.core import PolicyManager
+ return PolicyManager.add_action("", policy_id, perimeter_id, value)
+
+
+def delete_action(policy_id, perimeter_id):
+ from python_moondb.core import PolicyManager
+ PolicyManager.delete_action("", policy_id, perimeter_id)
+
+
+def get_objects(policy_id, perimeter_id=None):
+ from python_moondb.core import PolicyManager
+ return PolicyManager.get_objects("", policy_id, perimeter_id)
+
+
+def add_object(policy_id, perimeter_id=None, value=None):
+ from python_moondb.core import PolicyManager
+ return PolicyManager.add_object("", policy_id, perimeter_id, value)
+
+
+def delete_object(policy_id, perimeter_id):
+ from python_moondb.core import PolicyManager
+ PolicyManager.delete_object("", policy_id, perimeter_id)
+
+
+def get_subjects(policy_id, perimeter_id=None):
+ from python_moondb.core import PolicyManager
+ return PolicyManager.get_subjects("", policy_id, perimeter_id)
+
+
+def add_subject(policy_id, perimeter_id=None, value=None):
+ from python_moondb.core import PolicyManager
+ return PolicyManager.add_subject("", policy_id, perimeter_id, value)
+
+
+def delete_subject(policy_id, perimeter_id):
+ from python_moondb.core import PolicyManager
+ PolicyManager.delete_subject("", policy_id, perimeter_id)
+
+
+def get_available_metadata(policy_id):
+ from python_moondb.core import PolicyManager
+ return PolicyManager.get_available_metadata("", policy_id)
diff --git a/python_moondb/tests/unit_python/helpers/meta_rule_helper.py b/python_moondb/tests/unit_python/helpers/meta_rule_helper.py
new file mode 100644
index 00000000..80d138c6
--- /dev/null
+++ b/python_moondb/tests/unit_python/helpers/meta_rule_helper.py
@@ -0,0 +1,48 @@
+# 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'.
+
+from helpers import mock_data
+
+
+def set_meta_rule(meta_rule_id, value=None):
+ from python_moondb.core import ModelManager
+ if not value:
+ action_category_id = mock_data.create_action_category("action_category_id1")
+ subject_category_id = mock_data.create_subject_category("subject_category_id1")
+ object_category_id = mock_data.create_object_category("object_category_id1")
+ value = {
+ "name": "MLS_meta_rule",
+ "description": "test",
+ "subject_categories": [subject_category_id],
+ "object_categories": [object_category_id],
+ "action_categories": [action_category_id]
+ }
+ return ModelManager.set_meta_rule(user_id=None, meta_rule_id=meta_rule_id, value=value)
+
+
+def add_meta_rule(meta_rule_id=None, value=None):
+ from python_moondb.core import ModelManager
+ if not value:
+ action_category_id = mock_data.create_action_category("action_category_id1")
+ subject_category_id = mock_data.create_subject_category("subject_category_id1")
+ object_category_id = mock_data.create_object_category("object_category_id1")
+ value = {
+ "name": "MLS_meta_rule",
+ "description": "test",
+ "subject_categories": [subject_category_id],
+ "object_categories": [object_category_id],
+ "action_categories": [action_category_id]
+ }
+ return ModelManager.add_meta_rule(user_id=None, meta_rule_id=meta_rule_id, value=value)
+
+
+def get_meta_rules(meta_rule_id=None):
+ from python_moondb.core import ModelManager
+ return ModelManager.get_meta_rules(user_id=None, meta_rule_id=meta_rule_id)
+
+
+def delete_meta_rules(meta_rule_id=None):
+ from python_moondb.core import ModelManager
+ ModelManager.delete_meta_rule(user_id=None, meta_rule_id=meta_rule_id)
diff --git a/python_moondb/tests/unit_python/helpers/mock_data.py b/python_moondb/tests/unit_python/helpers/mock_data.py
new file mode 100644
index 00000000..82eebe88
--- /dev/null
+++ b/python_moondb/tests/unit_python/helpers/mock_data.py
@@ -0,0 +1,144 @@
+# 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'.
+
+from .category_helper import *
+from .policy_helper import *
+from .data_helper import *
+from .model_helper import *
+from .meta_rule_helper import *
+
+
+def create_subject_category(name):
+ subject_category = add_subject_category(
+ value={"name": name, "description": "description 1"})
+ return list(subject_category.keys())[0]
+
+
+def create_object_category(name):
+ object_category = add_object_category(
+ value={"name": name, "description": "description 1"})
+ return list(object_category.keys())[0]
+
+
+def create_action_category(name):
+ action_category = add_action_category(
+ value={"name": name, "description": "description 1"})
+ return list(action_category.keys())[0]
+
+
+def create_model(meta_rule_id, model_name="test_model"):
+ value = {
+ "name": model_name,
+ "description": "test",
+ "meta_rules": [meta_rule_id]
+
+ }
+ return value
+
+
+def create_policy(model_id, policy_name="policy_1"):
+ value = {
+ "name": policy_name,
+ "model_id": model_id,
+ "genre": "authz",
+ "description": "test",
+ }
+ return value
+
+
+def create_pdp(policies_ids):
+ value = {
+ "name": "test_pdp",
+ "security_pipeline": policies_ids,
+ "keystone_project_id": "keystone_project_id1",
+ "description": "...",
+ }
+ return value
+
+
+def create_new_policy(subject_category_name=None, object_category_name=None, action_category_name=None,
+ model_name="test_model", policy_name="policy_1", meta_rule_name="meta_rule1"):
+ subject_category_id, object_category_id, action_category_id, meta_rule_id = create_new_meta_rule(
+ subject_category_name=subject_category_name,
+ object_category_name=object_category_name,
+ action_category_name=action_category_name, meta_rule_name=meta_rule_name)
+ model = add_model(value=create_model(meta_rule_id, model_name))
+ model_id = list(model.keys())[0]
+ value = create_policy(model_id, policy_name)
+ policy = add_policies(value=value)
+ assert policy
+ policy_id = list(policy.keys())[0]
+ return subject_category_id, object_category_id, action_category_id, meta_rule_id, policy_id
+
+
+def create_new_meta_rule(subject_category_name=None, object_category_name=None, action_category_name=None,
+ meta_rule_name="meta_rule1"):
+ subject_category_id = create_subject_category(subject_category_name)
+ object_category_id = create_object_category(object_category_name)
+ action_category_id = create_action_category(action_category_name)
+ value = {"name": meta_rule_name,
+ "algorithm": "name of the meta rule algorithm",
+ "subject_categories": [subject_category_id],
+ "object_categories": [object_category_id],
+ "action_categories": [action_category_id]
+ }
+ meta_rule = add_meta_rule(value=value)
+ return subject_category_id, object_category_id, action_category_id, list(meta_rule.keys())[0]
+
+
+def create_subject(policy_id):
+ value = {
+ "name": "testuser",
+ "description": "test",
+ }
+ subject = add_subject(policy_id=policy_id, value=value)
+ return list(subject.keys())[0]
+
+
+def create_object(policy_id):
+ value = {
+ "name": "testobject",
+ "description": "test",
+ }
+ object = add_object(policy_id=policy_id, value=value)
+ return list(object.keys())[0]
+
+
+def create_action(policy_id):
+ value = {
+ "name": "testaction",
+ "description": "test",
+ }
+ action = add_action(policy_id=policy_id, value=value)
+ return list(action.keys())[0]
+
+
+def create_subject_data(policy_id, category_id):
+ value = {
+ "name": "subject-security-level",
+ "description": {"low": "", "medium": "", "high": ""},
+ }
+ subject_data = add_subject_data(policy_id=policy_id, category_id=category_id, value=value).get('data')
+ assert subject_data
+ return list(subject_data.keys())[0]
+
+
+def create_object_data(policy_id, category_id):
+ value = {
+ "name": "object-security-level",
+ "description": {"low": "", "medium": "", "high": ""},
+ }
+ object_data = add_object_data(policy_id=policy_id, category_id=category_id, value=value).get('data')
+ return list(object_data.keys())[0]
+
+
+def create_action_data(policy_id, category_id):
+ value = {
+ "name": "action-type",
+ "description": {"vm-action": "", "storage-action": "", },
+ }
+ action_data = add_action_data(policy_id=policy_id, category_id=category_id, value=value).get('data')
+ return list(action_data.keys())[0]
+
diff --git a/python_moondb/tests/unit_python/helpers/model_helper.py b/python_moondb/tests/unit_python/helpers/model_helper.py
new file mode 100644
index 00000000..58946a99
--- /dev/null
+++ b/python_moondb/tests/unit_python/helpers/model_helper.py
@@ -0,0 +1,50 @@
+# 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'.
+
+from helpers import mock_data
+
+
+def get_models(model_id=None):
+ from python_moondb.core import ModelManager
+ return ModelManager.get_models(user_id=None, model_id=model_id)
+
+
+def add_model(model_id=None, value=None):
+ from python_moondb.core import ModelManager
+ if not value:
+ subject_category_id, object_category_id, action_category_id, meta_rule_id = mock_data.create_new_meta_rule(
+ subject_category_name="subject_category1",
+ object_category_name="object_category1",
+ action_category_name="action_category1")
+ name = "MLS" if model_id is None else "MLS " + model_id
+ value = {
+ "name": name,
+ "description": "test",
+ "meta_rules": [meta_rule_id]
+ }
+ return ModelManager.add_model(user_id=None, model_id=model_id, value=value)
+
+
+def delete_models(uuid=None, name=None):
+ from python_moondb.core import ModelManager
+ if not uuid:
+ for model_id, model_value in get_models():
+ if name == model_value['name']:
+ uuid = model_id
+ break
+ ModelManager.delete_model(user_id=None, model_id=uuid)
+
+
+def delete_all_models():
+ from python_moondb.core import ModelManager
+ models_values = get_models()
+ print(models_values)
+ for model_id, model_value in models_values.items():
+ ModelManager.delete_model(user_id=None, model_id=model_id)
+
+
+def update_model(model_id=None, value=None):
+ from python_moondb.core import ModelManager
+ return ModelManager.update_model(user_id=None, model_id=model_id, value=value)
diff --git a/python_moondb/tests/unit_python/helpers/pdp_helper.py b/python_moondb/tests/unit_python/helpers/pdp_helper.py
new file mode 100644
index 00000000..3d169b06
--- /dev/null
+++ b/python_moondb/tests/unit_python/helpers/pdp_helper.py
@@ -0,0 +1,23 @@
+# 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'.
+
+def update_pdp(pdp_id, value):
+ from python_moondb.core import PDPManager
+ return PDPManager.update_pdp("", pdp_id, value)
+
+
+def delete_pdp(pdp_id):
+ from python_moondb.core import PDPManager
+ PDPManager.delete_pdp("", pdp_id)
+
+
+def add_pdp(pdp_id=None, value=None):
+ from python_moondb.core import PDPManager
+ return PDPManager.add_pdp("", pdp_id, value)
+
+
+def get_pdp(pdp_id=None):
+ from python_moondb.core import PDPManager
+ return PDPManager.get_pdp("", pdp_id)
diff --git a/python_moondb/tests/unit_python/helpers/policy_helper.py b/python_moondb/tests/unit_python/helpers/policy_helper.py
new file mode 100644
index 00000000..c932ee3a
--- /dev/null
+++ b/python_moondb/tests/unit_python/helpers/policy_helper.py
@@ -0,0 +1,61 @@
+# 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'.
+
+def get_policies():
+ from python_moondb.core import PolicyManager
+ return PolicyManager.get_policies("admin")
+
+
+def add_policies(policy_id=None, value=None):
+ from python_moondb.core import PolicyManager
+ if not value:
+ value = {
+ "name": "test_policy",
+ "model_id": "",
+ "genre": "authz",
+ "description": "test",
+ }
+ return PolicyManager.add_policy("admin", policy_id=policy_id, value=value)
+
+
+def delete_policies(uuid=None, name=None):
+ from python_moondb.core import PolicyManager
+ if not uuid:
+ for policy_id, policy_value in get_policies():
+ if name == policy_value['name']:
+ uuid = policy_id
+ break
+ PolicyManager.delete_policy("admin", uuid)
+
+
+def update_policy(policy_id, value):
+ from python_moondb.core import PolicyManager
+ return PolicyManager.update_policy("admin", policy_id, value)
+
+
+def get_policy_from_meta_rules(meta_rule_id):
+ from python_moondb.core import PolicyManager
+ return PolicyManager.get_policy_from_meta_rules("admin", meta_rule_id)
+
+
+def get_rules(policy_id=None, meta_rule_id=None, rule_id=None):
+ from python_moondb.core import PolicyManager
+ return PolicyManager.get_rules("", policy_id, meta_rule_id, rule_id)
+
+
+def add_rule(policy_id=None, meta_rule_id=None, value=None):
+ from python_moondb.core import PolicyManager
+ if not value:
+ value = {
+ "rule": ("high", "medium", "vm-action"),
+ "instructions": ({"decision": "grant"}),
+ "enabled": "",
+ }
+ return PolicyManager.add_rule("", policy_id, meta_rule_id, value)
+
+
+def delete_rule(policy_id=None, rule_id=None):
+ from python_moondb.core import PolicyManager
+ PolicyManager.delete_rule("", policy_id, rule_id)
diff --git a/python_moondb/tests/unit_python/models/test_categories.py b/python_moondb/tests/unit_python/models/test_categories.py
new file mode 100644
index 00000000..f87d0e12
--- /dev/null
+++ b/python_moondb/tests/unit_python/models/test_categories.py
@@ -0,0 +1,79 @@
+# 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 pytest
+import logging
+from python_moonutilities.exceptions import *
+from helpers import category_helper
+
+logger = logging.getLogger("moon.db.tests.models.test_categories")
+
+def test_add_subject_category_twice():
+ category = category_helper.add_subject_category(value={"name": "category name", "description": "description 1"})
+ category_id = list(category.keys())[0]
+ assert category is not None
+ with pytest.raises(SubjectCategoryExisting):
+ category_helper.add_subject_category(category_id,
+ value={"name": "category name", "description": "description 2"})
+
+
+def test_get_subject_categories():
+ added_category = category_helper.add_subject_category(
+ value={"name": "category name", "description": "description 1"})
+ category_id = list(added_category.keys())[0]
+ subject_category = category_helper.get_subject_category(category_id)
+ assert subject_category == added_category
+
+
+def test_get_subject_categories_with_invalid_id():
+ category_id = "invalid_id"
+ subject_category = category_helper.get_subject_category(category_id)
+ assert len(subject_category) == 0
+
+
+def test_add_object_category_twice():
+ category = category_helper.add_object_category(value={"name": "category name", "description": "description 1"})
+ category_id = list(category.keys())[0]
+ assert category is not None
+ with pytest.raises(ObjectCategoryExisting):
+ category_helper.add_object_category(category_id,
+ value={"name": "category name", "description": "description 2"})
+
+
+def test_get_object_categories():
+ added_category = category_helper.add_object_category(
+ value={"name": "category name", "description": "description 1"})
+ category_id = list(added_category.keys())[0]
+ object_category = category_helper.get_object_category(category_id)
+ assert object_category == added_category
+
+
+def test_get_object_categories_with_invalid_id():
+ category_id = "invalid_id"
+ object_category = category_helper.get_object_category(category_id)
+ assert len(object_category) == 0
+
+
+def test_add_action_category_twice():
+ category = category_helper.add_action_category(value={"name": "category name", "description": "description 1"})
+ category_id = list(category.keys())[0]
+ assert category is not None
+ with pytest.raises(ActionCategoryExisting):
+ category_helper.add_action_category(category_id,
+ value={"name": "category name", "description": "description 2"})
+
+
+def test_get_action_categories():
+ added_category = category_helper.add_action_category(
+ value={"name": "category name", "description": "description 1"})
+ category_id = list(added_category.keys())[0]
+ action_category = category_helper.get_action_category(category_id)
+ assert action_category == added_category
+
+
+def test_get_action_categories_with_invalid_id():
+ category_id = "invalid_id"
+ action_category = category_helper.get_action_category(category_id)
+ assert len(action_category) == 0
diff --git a/python_moondb/tests/unit_python/models/test_meta_rules.py b/python_moondb/tests/unit_python/models/test_meta_rules.py
index d8b61365..102cd724 100644
--- a/python_moondb/tests/unit_python/models/test_meta_rules.py
+++ b/python_moondb/tests/unit_python/models/test_meta_rules.py
@@ -1,122 +1,115 @@
-import pytest
-
-
-def set_meta_rule(meta_rule_id, value=None):
- from python_moondb.core import ModelManager
- if not value:
- value = {
- "name": "MLS_meta_rule",
- "description": "test",
- "subject_categories": ["user_security_level_id_1"],
- "object_categories": ["vm_security_level_id_1"],
- "action_categories": ["action_type_id_1"]
- }
- return ModelManager.set_meta_rule(user_id=None, meta_rule_id=meta_rule_id, value=value)
-
-
-def add_meta_rule(meta_rule_id=None, value=None):
- from python_moondb.core import ModelManager
- if not value:
- value = {
- "name": "MLS_meta_rule",
- "description": "test",
- "subject_categories": ["user_security_level_id_1"],
- "object_categories": ["vm_security_level_id_1"],
- "action_categories": ["action_type_id_1"]
- }
- return ModelManager.add_meta_rule(user_id=None, meta_rule_id=meta_rule_id, value=value)
-
-
-def get_meta_rules(meta_rule_id=None):
- from python_moondb.core import ModelManager
- return ModelManager.get_meta_rules(user_id=None, meta_rule_id=meta_rule_id)
+# 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 pytest
+from helpers import meta_rule_helper
+import helpers.mock_data as mock_data
-def delete_meta_rules(meta_rule_id=None):
- from python_moondb.core import ModelManager
- ModelManager.delete_meta_rule(user_id=None, meta_rule_id=meta_rule_id)
def test_set_not_exist_meta_rule_error(db):
# set not existing meta rule and expect to raise and error
with pytest.raises(Exception) as exception_info:
- set_meta_rule(meta_rule_id=None)
- assert str(exception_info.value) == '400: Sub Meta Rule Unknown'
+ meta_rule_helper.set_meta_rule(meta_rule_id=None)
+ assert str(exception_info.value) == '400: Meta Rule Unknown'
def test_add_new_meta_rule_success(db):
+ action_category_id = mock_data.create_action_category("action_category_id1")
+ subject_category_id = mock_data.create_subject_category("subject_category_id1")
+ object_category_id = mock_data.create_object_category("object_category_id1")
value = {
"name": "MLS_meta_rule",
"description": "test",
- "subject_categories": ["user_security_level_id_1"],
- "object_categories": ["vm_security_level_id_1"],
- "action_categories": ["action_type_id_1"]
+ "subject_categories": [subject_category_id],
+ "object_categories": [object_category_id],
+ "action_categories": [action_category_id]
}
- metaRules = add_meta_rule();
- assert isinstance(metaRules, dict)
- assert metaRules
- assert len(metaRules) is 1
- meta_rule_id = list(metaRules.keys())[0]
+ meta_rules = meta_rule_helper.add_meta_rule(value=value)
+ assert isinstance(meta_rules, dict)
+ assert meta_rules
+ assert len(meta_rules) is 1
+ meta_rule_id = list(meta_rules.keys())[0]
for key in ("name", "description", "subject_categories", "object_categories", "action_categories"):
- assert key in metaRules[meta_rule_id]
- assert metaRules[meta_rule_id][key] == value[key]
+ assert key in meta_rules[meta_rule_id]
+ assert meta_rules[meta_rule_id][key] == value[key]
-def test_set_meta_rule_succes(db):
+def test_set_meta_rule_success(db):
# arrange
- meta_rules = add_meta_rule()
+ meta_rules = meta_rule_helper.add_meta_rule()
meta_rule_id = list(meta_rules.keys())[0]
+ action_category_id = mock_data.create_action_category("action_category_id2")
+ subject_category_id = mock_data.create_subject_category("subject_category_id2")
+ object_category_id = mock_data.create_object_category("object_category_id2")
updated_value = {
"name": "MLS_meta_rule",
"description": "test",
- "subject_categories": ["user_role_id_1"],
- "object_categories": ["vm_security_level_id_1"],
- "action_categories": ["action_type_id_1"]
+ "subject_categories": [subject_category_id],
+ "object_categories": [object_category_id],
+ "action_categories": [action_category_id]
}
# action
- updated_meta_rule = set_meta_rule(meta_rule_id, updated_value)
+ updated_meta_rule = meta_rule_helper.set_meta_rule(meta_rule_id, updated_value)
# assert
updated_meta_rule_id = list(updated_meta_rule.keys())[0]
assert updated_meta_rule_id == meta_rule_id
- assert updated_meta_rule[updated_meta_rule_id]["subject_categories"] == \
- updated_value["subject_categories"]
+ assert updated_meta_rule[updated_meta_rule_id]["subject_categories"] == updated_value["subject_categories"]
def test_add_existing_meta_rule_error(db):
- meta_rules = add_meta_rule()
+ action_category_id = mock_data.create_action_category("action_category_id3")
+ subject_category_id = mock_data.create_subject_category("subject_category_id3")
+ object_category_id = mock_data.create_object_category("object_category_id3")
+ value = {
+ "name": "MLS_meta_rule",
+ "description": "test",
+ "subject_categories": [subject_category_id],
+ "object_categories": [object_category_id],
+ "action_categories": [action_category_id]
+ }
+ meta_rules = meta_rule_helper.add_meta_rule(value=value)
meta_rule_id = list(meta_rules.keys())[0]
with pytest.raises(Exception) as exception_info:
- add_meta_rule(meta_rule_id=meta_rule_id)
+ meta_rule_helper.add_meta_rule(meta_rule_id=meta_rule_id)
assert str(exception_info.value) == '400: Sub Meta Rule Existing'
def test_get_meta_rule_success(db):
# arrange
+ action_category_id = mock_data.create_action_category("action_type")
+ subject_category_id = mock_data.create_subject_category("user_security_level")
+ object_category_id = mock_data.create_object_category("vm_security_level")
values = {}
value1 = {
"name": "MLS_meta_rule",
"description": "test",
- "subject_categories": ["user_security_level_id_1"],
- "object_categories": ["vm_security_level_id_1"],
- "action_categories": ["action_type_id_1"]
+ "subject_categories": [subject_category_id],
+ "object_categories": [object_category_id],
+ "action_categories": [action_category_id]
}
- meta_rules1 = add_meta_rule(value=value1)
+ meta_rules1 = meta_rule_helper.add_meta_rule(value=value1)
meta_rule_id1 = list(meta_rules1.keys())[0]
values[meta_rule_id1] = value1
+ action_category_id = mock_data.create_action_category("action_type2")
+ subject_category_id = mock_data.create_subject_category("user_security_level2")
+ object_category_id = mock_data.create_object_category("vm_security_level2")
value2 = {
"name": "rbac_meta_rule",
"description": "test",
- "subject_categories": ["user_role_id_1"],
- "object_categories": ["vm_id_1"],
- "action_categories": ["action_type_id_1"]
+ "subject_categories": [subject_category_id],
+ "object_categories": [object_category_id],
+ "action_categories": [action_category_id]
}
- meta_rules2 = add_meta_rule(value=value2)
+ meta_rules2 = meta_rule_helper.add_meta_rule(value=value2)
meta_rule_id2 = list(meta_rules2.keys())[0]
values[meta_rule_id2] = value2
# action
- meta_rules = get_meta_rules()
+ meta_rules = meta_rule_helper.get_meta_rules()
# assert
- assert isinstance(meta_rules , dict)
+ assert isinstance(meta_rules, dict)
assert meta_rules
assert len(meta_rules) is 2
for meta_rule_id in meta_rules:
@@ -127,11 +120,10 @@ def test_get_meta_rule_success(db):
def test_get_specific_meta_rule_success(db):
# arrange
- add_meta_rule()
- added_meta_rules = add_meta_rule()
+ added_meta_rules = meta_rule_helper.add_meta_rule()
added_meta_rule_id = list(added_meta_rules.keys())[0]
# action
- meta_rules = get_meta_rules(meta_rule_id=added_meta_rule_id)
+ meta_rules = meta_rule_helper.get_meta_rules(meta_rule_id=added_meta_rule_id)
meta_rule_id = list(meta_rules.keys())[0]
# assert
assert meta_rule_id == added_meta_rule_id
@@ -141,35 +133,28 @@ def test_get_specific_meta_rule_success(db):
def test_delete_meta_rules_success(db):
+ action_category_id = mock_data.create_action_category("action_type")
+ subject_category_id = mock_data.create_subject_category("user_security_level")
+ object_category_id = mock_data.create_object_category("vm_security_level")
# arrange
value1 = {
"name": "MLS_meta_rule",
"description": "test",
- "subject_categories": ["user_security_level_id_1"],
- "object_categories": ["vm_security_level_id_1"],
- "action_categories": ["action_type_id_1"]
+ "subject_categories": [subject_category_id],
+ "object_categories": [object_category_id],
+ "action_categories": [action_category_id]
}
- meta_rules1 = add_meta_rule(value=value1)
+ meta_rules1 = meta_rule_helper.add_meta_rule(value=value1)
meta_rule_id1 = list(meta_rules1.keys())[0]
- value2 = {
- "name": "rbac_meta_rule",
- "description": "test",
- "subject_categories": ["user_role_id_1"],
- "object_categories": ["vm_id_1"],
- "action_categories": ["action_type_id_1"]
- }
- meta_rules2 = add_meta_rule(value=value2)
- meta_rule_id2 = list(meta_rules2.keys())[0]
-
# action
- delete_meta_rules(meta_rule_id1)
+ meta_rule_helper.delete_meta_rules(meta_rule_id1)
# assert
- meta_rules = get_meta_rules()
+ meta_rules = meta_rule_helper.get_meta_rules()
assert meta_rule_id1 not in meta_rules
def test_delete_invalid_meta_rules_error(db):
with pytest.raises(Exception) as exception_info:
- delete_meta_rules("INVALID_META_RULE_ID")
- assert str(exception_info.value) == '400: Sub Meta Rule Unknown'
+ meta_rule_helper.delete_meta_rules("INVALID_META_RULE_ID")
+ assert str(exception_info.value) == '400: Meta Rule Unknown'
diff --git a/python_moondb/tests/unit_python/models/test_models.py b/python_moondb/tests/unit_python/models/test_models.py
index e56fea6b..0026345c 100644
--- a/python_moondb/tests/unit_python/models/test_models.py
+++ b/python_moondb/tests/unit_python/models/test_models.py
@@ -1,40 +1,22 @@
-import pytest
-
-
-def get_models(model_id=None):
- from python_moondb.core import ModelManager
- return ModelManager.get_models(user_id= None , model_id= model_id)
-
-
-def add_model(model_id=None, value=None):
- from python_moondb.core import ModelManager
- if not value:
- value = {
- "name": "MLS",
- "description": "test",
- "meta_rules": "meta_rule_mls_1"
- }
- return ModelManager.add_model(user_id=None, model_id=model_id, value=value)
-
-
-def delete_models(uuid=None, name=None):
- from python_moondb.core import ModelManager
- if not uuid:
- for model_id, model_value in get_models():
- if name == model_value['name']:
- uuid = model_id
- break
- ModelManager.delete_model(user_id=None, model_id=uuid)
+# 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 pytest
+from python_moonutilities.exceptions import *
+import logging
+import helpers.mock_data as mock_data
+import helpers.model_helper as model_helper
+import helpers.category_helper as category_helper
+import helpers.policy_helper as policy_helper
-def update_model(model_id=None, value=None):
- from python_moondb.core import ModelManager
- return ModelManager.update_model(user_id=None, model_id=model_id, value=value)
+logger = logging.getLogger("moon.db.tests.test_model")
def test_get_models_empty(db):
# act
- models = get_models()
+ models = model_helper.get_models()
# assert
assert isinstance(models, dict)
assert not models
@@ -42,70 +24,107 @@ def test_get_models_empty(db):
def test_get_model(db):
# prepare
- add_model(model_id="mls_model_id")
+ model_helper.add_model(model_id="mls_model_id")
# act
- models = get_models()
+ models = model_helper.get_models()
# assert
assert isinstance(models, dict)
assert models # assert model is not empty
assert len(models) is 1
+ model_helper.delete_all_models()
def test_get_specific_model(db):
# prepare
- add_model(model_id="mls_model_id")
- add_model(model_id="rbac_model_id")
+ model_helper.add_model(model_id="mls_model_id")
# act
- models = get_models(model_id="mls_model_id")
+ models = model_helper.get_models(model_id="mls_model_id")
# assert
assert isinstance(models, dict)
assert models # assert model is not empty
assert len(models) is 1
+ model_helper.delete_all_models()
def test_add_model(db):
# act
- model = add_model()
+ model = model_helper.add_model()
# assert
assert isinstance(model, dict)
assert model # assert model is not empty
assert len(model) is 1
+ model_helper.delete_all_models()
def test_add_same_model_twice(db):
+ subject_category_id, object_category_id, action_category_id, meta_rule_id = mock_data.create_new_meta_rule(
+ subject_category_name="subject_category1",
+ object_category_name="object_category1",
+ action_category_name="action_category1",
+ meta_rule_name="meta_rule_1")
+ value = {
+ "name": "model1",
+ "description": "test",
+ "meta_rules": [meta_rule_id]
+ }
# prepare
- add_model(model_id="model_1") # add model twice
+ model_helper.add_model(model_id="model_1", value=value) # add model twice
# act
- with pytest.raises(Exception) as exception_info:
- add_model(model_id="model_1")
- assert str(exception_info.value) == '409: Model Error'
+ subject_category_id, object_category_id, action_category_id, meta_rule_id = mock_data.create_new_meta_rule(
+ subject_category_name="subject_category2",
+ object_category_name="object_category2",
+ action_category_name="action_category2",
+ meta_rule_name="meta_rule_2")
+ value = {
+ "name": "model2",
+ "description": "test",
+ "meta_rules": [meta_rule_id]
+ }
+ with pytest.raises(ModelExisting) as exception_info:
+ model_helper.add_model(model_id="model_1", value=value)
+ model_helper.delete_all_models()
+ # assert str(exception_info.value) == '409: Model Error'
def test_add_model_generate_new_uuid(db):
+ subject_category_id, object_category_id, action_category_id, meta_rule_id1 = mock_data.create_new_meta_rule(
+ subject_category_name="subject_category3",
+ object_category_name="object_category3",
+ action_category_name="action_category3",
+ meta_rule_name="meta_rule_3")
model_value1 = {
"name": "MLS",
"description": "test",
- "meta_rules": "meta_rule_mls_1"
+ "meta_rules": [meta_rule_id1]
}
- model1 = add_model(value=model_value1)
-
+ model1 = model_helper.add_model(value=model_value1)
+ subject_category_id, object_category_id, action_category_id, meta_rule_id2 = mock_data.create_new_meta_rule(
+ subject_category_name="subject_category4",
+ object_category_name="object_category4",
+ action_category_name="action_category4",
+ meta_rule_name="meta_rule_4")
model_value2 = {
"name": "rbac",
"description": "test",
- "meta_rules": "meta_rule_mls_2"
+ "meta_rules": [meta_rule_id2]
}
- model2 = add_model(value=model_value2)
+ model2 = model_helper.add_model(value=model_value2)
assert list(model1)[0] != list(model2)[0]
+ model_helper.delete_all_models()
def test_add_models(db):
+ subject_category_id, object_category_id, action_category_id, meta_rule_id = mock_data.create_new_meta_rule(
+ subject_category_name="subject_category5",
+ object_category_name="object_category5",
+ action_category_name="action_category5")
model_value1 = {
"name": "MLS",
"description": "test",
- "meta_rules": "meta_rule_mls_1"
+ "meta_rules": [meta_rule_id]
}
- models = add_model(value=model_value1)
+ models = model_helper.add_model(value=model_value1)
assert isinstance(models, dict)
assert models
assert len(models.keys()) == 1
@@ -113,49 +132,306 @@ def test_add_models(db):
for key in ("name", "meta_rules", "description"):
assert key in models[model_id]
assert models[model_id][key] == model_value1[key]
+ model_helper.delete_all_models()
-def test_delete_models(db):
+def test_add_models_with_same_name_twice(db):
+ subject_category_id, object_category_id, action_category_id, meta_rule_id = mock_data.create_new_meta_rule(
+ subject_category_name="subject_category5",
+ object_category_name="object_category5",
+ action_category_name="action_category5")
model_value1 = {
"name": "MLS",
"description": "test",
- "meta_rules": "meta_rule_mls_1"
+ "meta_rules": [meta_rule_id]
}
- model1 = add_model(value=model_value1)
+ models = model_helper.add_model(value=model_value1)
+ assert isinstance(models, dict)
+ assert models
+ with pytest.raises(Exception) as exc_info:
+ model_helper.add_model(value=model_value1)
+ model_helper.delete_all_models()
+
+def test_delete_models(db):
+ subject_category_id, object_category_id, action_category_id, meta_rule_id1 = mock_data.create_new_meta_rule(
+ subject_category_name="subject_category6",
+ object_category_name="object_category6",
+ action_category_name="action_category6",
+ meta_rule_name="meta_rule_6")
+ model_value1 = {
+ "name": "MLS",
+ "description": "test",
+ "meta_rules": [meta_rule_id1]
+ }
+ model1 = model_helper.add_model(value=model_value1)
+ subject_category_id, object_category_id, action_category_id, meta_rule_id2 = mock_data.create_new_meta_rule(
+ subject_category_name="subject_category7",
+ object_category_name="object_category7",
+ action_category_name="action_category7",
+ meta_rule_name="meta_rule_7")
model_value2 = {
"name": "rbac",
"description": "test",
- "meta_rules": "meta_rule_mls_2"
+ "meta_rules": [meta_rule_id2]
}
- model2 = add_model(value=model_value2)
+ model_helper.add_model(value=model_value2)
id = list(model1)[0]
- delete_models(id)
+ model_helper.delete_models(id)
# assert
- models = get_models()
+ models = model_helper.get_models()
assert id not in models
+ model_helper.delete_all_models()
def test_update_model(db):
+ subject_category_id, object_category_id, action_category_id, meta_rule_id1 = mock_data.create_new_meta_rule(
+ subject_category_name="subject_category8",
+ object_category_name="object_category8",
+ action_category_name="action_category8",
+ meta_rule_name="meta_rule_8")
# prepare
model_value = {
"name": "MLS",
"description": "test",
- "meta_rules": "meta_rule_mls_1"
+ "meta_rules": [meta_rule_id1]
}
- model = add_model(value=model_value)
+ model = model_helper.add_model(value=model_value)
model_id = list(model)[0]
+ subject_category_id, object_category_id, action_category_id, meta_rule_id2 = mock_data.create_new_meta_rule(
+ subject_category_name="subject_category9",
+ object_category_name="object_category9",
+ action_category_name="action_category9",
+ meta_rule_name="meta_rule_9")
new_model_value = {
- "name": "MLS",
+ "name": "MLS2",
"description": "test",
- "meta_rules": "meta_rule_mls_2"
+ "meta_rules": [meta_rule_id2]
}
# act
- update_model(model_id=model_id, value=new_model_value)
+ model_helper.update_model(model_id=model_id, value=new_model_value)
# assert
- model = get_models(model_id)
+ model = model_helper.get_models(model_id)
for key in ("name", "meta_rules", "description"):
assert key in model[model_id]
- assert model[model_id][key] == new_model_value[key] \ No newline at end of file
+ assert model[model_id][key] == new_model_value[key]
+ model_helper.delete_all_models()
+
+
+def test_delete_model_assigned_to_policy(db):
+ model_value1 = {
+ "name": "MLS",
+ "description": "test",
+ "meta_rules": []
+ }
+ models = model_helper.add_model(value=model_value1)
+ assert isinstance(models, dict)
+ assert models
+ assert len(models.keys()) == 1
+ model_id = list(models.keys())[0]
+ value = {
+ "name": "test_policy",
+ "model_id": model_id,
+ "genre": "authz",
+ "description": "test",
+ }
+ policy_helper.add_policies(value=value)
+ with pytest.raises(DeleteModelWithPolicy) as exception_info:
+ model_helper.delete_models(uuid=model_id)
+
+
+def test_add_subject_category(db):
+ category_id = "category_id1"
+ value = {
+ "name": "subject_category",
+ "description": "description subject_category"
+ }
+ subject_category = category_helper.add_subject_category(category_id, value)
+ assert subject_category
+ assert len(subject_category) == 1
+
+
+def test_add_subject_category_with_empty_name(db):
+ category_id = "category_id1"
+ value = {
+ "name": "",
+ "description": "description subject_category"
+ }
+ with pytest.raises(Exception) as exception_info:
+ category_helper.add_subject_category(category_id, value)
+ assert str(exception_info.value) == '400: Category Name Invalid'
+
+
+def test_add_subject_category_with_same_category_id(db):
+ category_id = "category_id1"
+ value = {
+ "name": "subject_category",
+ "description": "description subject_category"
+ }
+ category_helper.add_subject_category(category_id, value)
+ with pytest.raises(Exception) as exception_info:
+ category_helper.add_subject_category(category_id, value)
+ assert str(exception_info.value) == '409: Subject Category Existing'
+
+
+def test_get_subject_category(db):
+ category_id = "category_id1"
+ value = {
+ "name": "subject_category",
+ "description": "description subject_category"
+ }
+ category_helper.add_subject_category(category_id, value)
+ subject_category = category_helper.get_subject_category(category_id)
+ assert subject_category
+ assert len(subject_category) == 1
+
+
+def test_delete_subject_category(db):
+ category_id = "category_id1"
+ value = {
+ "name": "subject_category",
+ "description": "description subject_category"
+ }
+ category_helper.add_subject_category(category_id, value)
+ subject_category = category_helper.delete_subject_category(category_id)
+ assert not subject_category
+
+
+def test_delete_subject_category_with_unkown_category_id(db):
+ category_id = "invalid_category_id"
+
+ with pytest.raises(Exception) as exception_info:
+ category_helper.delete_subject_category(category_id)
+ assert str(exception_info.value) == '400: Subject Category Unknown'
+
+
+def test_add_object_category(db):
+ category_id = "category_id1"
+ value = {
+ "name": "object_category",
+ "description": "description object_category"
+ }
+ object_category = category_helper.add_object_category(category_id, value)
+ assert object_category
+ assert len(object_category) == 1
+
+
+def test_add_object_category_with_same_category_id(db):
+ category_id = "category_id1"
+ value = {
+ "name": "object_category",
+ "description": "description object_category"
+ }
+ category_helper.add_object_category(category_id, value)
+ with pytest.raises(Exception) as exception_info:
+ category_helper.add_object_category(category_id, value)
+ assert str(exception_info.value) == '409: Object Category Existing'
+
+
+def test_add_object_category_with_empty_name(db):
+ category_id = "category_id1"
+ value = {
+ "name": "",
+ "description": "description object_category"
+ }
+ with pytest.raises(Exception) as exception_info:
+ category_helper.add_object_category(category_id, value)
+ assert str(exception_info.value) == '400: Category Name Invalid'
+
+
+def test_get_object_category(db):
+ category_id = "category_id1"
+ value = {
+ "name": "object_category",
+ "description": "description object_category"
+ }
+ category_helper.add_object_category(category_id, value)
+ object_category = category_helper.get_object_category(category_id)
+ assert object_category
+ assert len(object_category) == 1
+
+
+def test_delete_object_category(db):
+ category_id = "category_id1"
+ value = {
+ "name": "object_category",
+ "description": "description object_category"
+ }
+ category_helper.add_object_category(category_id, value)
+ object_category = category_helper.delete_object_category(category_id)
+ assert not object_category
+
+
+def test_delete_object_category_with_unkown_category_id(db):
+ category_id = "invalid_category_id"
+
+ with pytest.raises(Exception) as exception_info:
+ category_helper.delete_object_category(category_id)
+ assert str(exception_info.value) == '400: Object Category Unknown'
+
+
+def test_add_action_category(db):
+ category_id = "category_id1"
+ value = {
+ "name": "action_category",
+ "description": "description action_category"
+ }
+ action_category = category_helper.add_action_category(category_id, value)
+ assert action_category
+ assert len(action_category) == 1
+
+
+def test_add_action_category_with_same_category_id(db):
+ category_id = "category_id1"
+ value = {
+ "name": "action_category",
+ "description": "description action_category"
+ }
+ category_helper.add_action_category(category_id, value)
+ with pytest.raises(Exception) as exception_info:
+ category_helper.add_action_category(category_id, value)
+ assert str(exception_info.value) == '409: Action Category Existing'
+
+
+def test_add_action_category_with_empty_name(db):
+ category_id = "category_id1"
+ value = {
+ "name": "",
+ "description": "description action_category"
+ }
+ with pytest.raises(Exception) as exception_info:
+ category_helper.add_action_category(category_id, value)
+ assert str(exception_info.value) == '400: Category Name Invalid'
+
+
+def test_get_action_category(db):
+ category_id = "category_id1"
+ value = {
+ "name": "action_category",
+ "description": "description action_category"
+ }
+ category_helper.add_action_category(category_id, value)
+ action_category = category_helper.get_action_category(category_id)
+ assert action_category
+ assert len(action_category) == 1
+
+
+def test_delete_action_category(db):
+ category_id = "category_id1"
+ value = {
+ "name": "action_category",
+ "description": "description action_category"
+ }
+ category_helper.add_action_category(category_id, value)
+ action_category = category_helper.delete_action_category(category_id)
+ assert not action_category
+
+
+def test_delete_action_category_with_unkown_category_id(db):
+ category_id = "invalid_category_id"
+
+ with pytest.raises(Exception) as exception_info:
+ category_helper.delete_action_category(category_id)
+ assert str(exception_info.value) == '400: Action Category Unknown'
diff --git a/python_moondb/tests/unit_python/policies/mock_data.py b/python_moondb/tests/unit_python/policies/mock_data.py
index 23eeef64..47fc9f9e 100644
--- a/python_moondb/tests/unit_python/policies/mock_data.py
+++ b/python_moondb/tests/unit_python/policies/mock_data.py
@@ -1,18 +1,24 @@
-def create_meta_rule():
+import helpers.model_helper as model_helper
+import helpers.meta_rule_helper as meta_rule_helper
+import helpers.policy_helper as policy_helper
+import helpers.category_helper as category_helper
+
+
+def create_meta_rule(meta_rule_name="meta_rule1", category_prefix=""):
meta_rule_value = {
- "name": "meta_rule1",
+ "name": meta_rule_name,
"algorithm": "name of the meta rule algorithm",
- "subject_categories": ["subject_category_id1",
- "subject_category_id2"],
- "object_categories": ["object_category_id1"],
- "action_categories": ["action_category_id1"]
+ "subject_categories": [category_prefix + "subject_category_id1",
+ category_prefix + "subject_category_id2"],
+ "object_categories": [category_prefix + "object_category_id1"],
+ "action_categories": [category_prefix + "action_category_id1"]
}
return meta_rule_value
-def create_model(meta_rule_id):
+def create_model(meta_rule_id, model_name="test_model"):
value = {
- "name": "test_model",
+ "name": model_name,
"description": "test",
"meta_rules": [meta_rule_id]
@@ -20,9 +26,9 @@ def create_model(meta_rule_id):
return value
-def create_policy(model_id):
+def create_policy(model_id, policy_name="policy_1"):
value = {
- "name": "policy_1",
+ "name": policy_name,
"model_id": model_id,
"genre": "authz",
"description": "test",
@@ -40,16 +46,29 @@ def create_pdp(pdp_ids):
return value
-def get_policy_id():
- import policies.test_policies as test_policies
- import models.test_models as test_models
- import models.test_meta_rules as test_meta_rules
- meta_rule = test_meta_rules.add_meta_rule(value=create_meta_rule())
+def get_policy_id(model_name="test_model", policy_name="policy_1", meta_rule_name="meta_rule1", category_prefix=""):
+ category_helper.add_subject_category(
+ category_prefix + "subject_category_id1",
+ value={"name": category_prefix + "subject_category_id1",
+ "description": "description 1"})
+ category_helper.add_subject_category(
+ category_prefix + "subject_category_id2",
+ value={"name": category_prefix + "subject_category_id2",
+ "description": "description 1"})
+ category_helper.add_object_category(
+ category_prefix + "object_category_id1",
+ value={"name": category_prefix + "object_category_id1",
+ "description": "description 1"})
+ category_helper.add_action_category(
+ category_prefix + "action_category_id1",
+ value={"name": category_prefix + "action_category_id1",
+ "description": "description 1"})
+ meta_rule = meta_rule_helper.add_meta_rule(value=create_meta_rule(meta_rule_name, category_prefix))
meta_rule_id = list(meta_rule.keys())[0]
- model = test_models.add_model(value=create_model(meta_rule_id))
+ model = model_helper.add_model(value=create_model(meta_rule_id, model_name))
model_id = list(model.keys())[0]
- value = create_policy(model_id)
- policy = test_policies.add_policies(value=value)
+ value = create_policy(model_id, policy_name)
+ policy = policy_helper.add_policies(value=value)
assert policy
policy_id = list(policy.keys())[0]
return policy_id
diff --git a/python_moondb/tests/unit_python/policies/test_assignments.py b/python_moondb/tests/unit_python/policies/test_assignments.py
index 707632b0..675c2ff9 100755
--- a/python_moondb/tests/unit_python/policies/test_assignments.py
+++ b/python_moondb/tests/unit_python/policies/test_assignments.py
@@ -1,248 +1,220 @@
-import policies.mock_data as mock_data
+# 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'.
-
-def get_action_assignments(policy_id, action_id=None, category_id=None):
- from python_moondb.core import PolicyManager
- return PolicyManager.get_action_assignments("", policy_id, action_id, category_id)
-
-
-def add_action_assignment(policy_id, action_id, category_id, data_id):
- from python_moondb.core import PolicyManager
- return PolicyManager.add_action_assignment("", policy_id, action_id, category_id, data_id)
-
-
-def delete_action_assignment(policy_id, action_id, category_id, data_id):
- from python_moondb.core import PolicyManager
- PolicyManager.delete_action_assignment("", policy_id, action_id, category_id, data_id)
-
-
-def get_object_assignments(policy_id, object_id=None, category_id=None):
- from python_moondb.core import PolicyManager
- return PolicyManager.get_object_assignments("", policy_id, object_id, category_id)
-
-
-def add_object_assignment(policy_id, object_id, category_id, data_id):
- from python_moondb.core import PolicyManager
- return PolicyManager.add_object_assignment("", policy_id, object_id, category_id, data_id)
-
-
-def delete_object_assignment(policy_id, object_id, category_id, data_id):
- from python_moondb.core import PolicyManager
- PolicyManager.delete_object_assignment("", policy_id, object_id, category_id, data_id)
-
-
-def get_subject_assignments(policy_id, subject_id=None, category_id=None):
- from python_moondb.core import PolicyManager
- return PolicyManager.get_subject_assignments("", policy_id, subject_id, category_id)
-
-
-def add_subject_assignment(policy_id, subject_id, category_id, data_id):
- from python_moondb.core import PolicyManager
- return PolicyManager.add_subject_assignment("", policy_id, subject_id, category_id, data_id)
-
-
-def delete_subject_assignment(policy_id, subject_id, category_id, data_id):
- from python_moondb.core import PolicyManager
- PolicyManager.delete_subject_assignment("", policy_id, subject_id, category_id, data_id)
+import helpers.mock_data as mock_data
+import helpers.assignment_helper as assignment_helper
+from python_moonutilities.exceptions import *
+import pytest
def test_get_action_assignments(db):
- policy_id = mock_data.get_policy_id()
- action_id = "action_id_1"
- category_id = "category_id_1"
- data_id = "data_id_1"
- add_action_assignment(policy_id, action_id, category_id, data_id)
- act_assignments = get_action_assignments(policy_id, action_id, category_id)
+ subject_category_id, object_category_id, action_category_id, meta_rule_id, policy_id = mock_data.create_new_policy(
+ subject_category_name="subject_category1",
+ object_category_name="object_category1",
+ action_category_name="action_category1",
+ meta_rule_name="meta_rule_1")
+ action_id = mock_data.create_action(policy_id)
+ data_id = mock_data.create_action_data(policy_id=policy_id, category_id=action_category_id)
+
+ assignment_helper.add_action_assignment(policy_id, action_id, action_category_id, data_id)
+ act_assignments = assignment_helper.get_action_assignments(policy_id, action_id, action_category_id)
action_id_1 = list(act_assignments.keys())[0]
assert act_assignments[action_id_1]["policy_id"] == policy_id
assert act_assignments[action_id_1]["action_id"] == action_id
- assert act_assignments[action_id_1]["category_id"] == category_id
+ assert act_assignments[action_id_1]["category_id"] == action_category_id
assert len(act_assignments[action_id_1].get("assignments")) == 1
assert data_id in act_assignments[action_id_1].get("assignments")
-def test_get_action_assignments_by_policy_id(db):
- policy_id = mock_data.get_policy_id()
- action_id = "action_id_1"
- category_id = "category_id_1"
- data_id = "data_id_1"
- add_action_assignment(policy_id, action_id, category_id, data_id)
- data_id = "data_id_2"
- add_action_assignment(policy_id, action_id, category_id, data_id)
- data_id = "data_id_3"
- add_action_assignment(policy_id, action_id, category_id, data_id)
- act_assignments = get_action_assignments(policy_id)
- action_id_1 = list(act_assignments.keys())[0]
- assert act_assignments[action_id_1]["policy_id"] == policy_id
- assert act_assignments[action_id_1]["action_id"] == action_id
- assert act_assignments[action_id_1]["category_id"] == category_id
- assert len(act_assignments[action_id_1].get("assignments")) == 3
-
-
def test_add_action_assignments(db):
- policy_id = mock_data.get_policy_id()
- action_id = "action_id_1"
- category_id = "category_id_1"
- data_id = "data_id_1"
- action_assignments = add_action_assignment(policy_id, action_id, category_id, data_id)
+ subject_category_id, object_category_id, action_category_id, meta_rule_id, policy_id = mock_data.create_new_policy(
+ subject_category_name="subject_category1",
+ object_category_name="object_category1",
+ action_category_name="action_category1",
+ meta_rule_name="meta_rule_1")
+ action_id = mock_data.create_action(policy_id)
+ data_id = mock_data.create_action_data(policy_id=policy_id, category_id=action_category_id)
+ action_assignments = assignment_helper.add_action_assignment(policy_id, action_id, action_category_id, data_id)
assert action_assignments
action_id_1 = list(action_assignments.keys())[0]
assert action_assignments[action_id_1]["policy_id"] == policy_id
assert action_assignments[action_id_1]["action_id"] == action_id
- assert action_assignments[action_id_1]["category_id"] == category_id
+ assert action_assignments[action_id_1]["category_id"] == action_category_id
assert len(action_assignments[action_id_1].get("assignments")) == 1
assert data_id in action_assignments[action_id_1].get("assignments")
+ with pytest.raises(ActionAssignmentExisting) as exception_info:
+ assignment_helper.add_action_assignment(policy_id, action_id, action_category_id, data_id)
+
def test_delete_action_assignment(db):
- policy_id = mock_data.get_policy_id()
- add_action_assignment(policy_id, "", "", "")
- policy_id = mock_data.get_policy_id()
- action_id = "action_id_2"
- category_id = "category_id_2"
- data_id = "data_id_2"
- add_action_assignment(policy_id, action_id, category_id, data_id)
- delete_action_assignment(policy_id, "", "", "")
- assignments = get_action_assignments(policy_id, )
+ subject_category_id, object_category_id, action_category_id, meta_rule_id, policy_id = mock_data.create_new_policy(
+ subject_category_name="subject_category1",
+ object_category_name="object_category1",
+ action_category_name="action_category1",
+ meta_rule_name="meta_rule_1")
+ action_id = mock_data.create_action(policy_id)
+ data_id = mock_data.create_action_data(policy_id=policy_id, category_id=action_category_id)
+ assignment_helper.add_action_assignment(policy_id, action_id, action_category_id, data_id)
+ assignment_helper.delete_action_assignment(policy_id, "", "", "")
+ assignments = assignment_helper.get_action_assignments(policy_id, )
assert len(assignments) == 1
def test_delete_action_assignment_with_invalid_policy_id(db):
policy_id = "invalid_id"
- delete_action_assignment(policy_id, "", "", "")
- assignments = get_action_assignments(policy_id, )
+ assignment_helper.delete_action_assignment(policy_id, "", "", "")
+ assignments = assignment_helper.get_action_assignments(policy_id, )
assert len(assignments) == 0
def test_get_object_assignments(db):
- policy_id = mock_data.get_policy_id()
- object_id = "object_id_1"
- category_id = "category_id_1"
- data_id = "data_id_1"
- add_object_assignment(policy_id, object_id, category_id, data_id)
- obj_assignments = get_object_assignments(policy_id, object_id, category_id)
+ subject_category_id, object_category_id, action_category_id, meta_rule_id, policy_id = mock_data.create_new_policy(
+ subject_category_name="subject_category1",
+ object_category_name="object_category1",
+ action_category_name="action_category1",
+ meta_rule_name="meta_rule_1")
+ object_id = mock_data.create_object(policy_id)
+ data_id = mock_data.create_object_data(policy_id=policy_id, category_id=object_category_id)
+ assignment_helper.add_object_assignment(policy_id, object_id, object_category_id, data_id)
+ obj_assignments = assignment_helper.get_object_assignments(policy_id, object_id, object_category_id)
object_id_1 = list(obj_assignments.keys())[0]
assert obj_assignments[object_id_1]["policy_id"] == policy_id
assert obj_assignments[object_id_1]["object_id"] == object_id
- assert obj_assignments[object_id_1]["category_id"] == category_id
+ assert obj_assignments[object_id_1]["category_id"] == object_category_id
assert len(obj_assignments[object_id_1].get("assignments")) == 1
assert data_id in obj_assignments[object_id_1].get("assignments")
def test_get_object_assignments_by_policy_id(db):
- policy_id = mock_data.get_policy_id()
- object_id_1 = "object_id_1"
- category_id_1 = "category_id_1"
- data_id = "data_id_1"
- add_action_assignment(policy_id, object_id_1, category_id_1, data_id)
- object_id_2 = "object_id_2"
- category_id_2 = "category_id_2"
- data_id = "data_id_2"
- add_action_assignment(policy_id, object_id_2, category_id_2, data_id)
- object_id_3 = "object_id_3"
- category_id_3 = "category_id_3"
- data_id = "data_id_3"
- add_action_assignment(policy_id, object_id_3, category_id_3, data_id)
- act_assignments = get_action_assignments(policy_id)
- assert len(act_assignments) == 3
+ subject_category_id, object_category_id, action_category_id, meta_rule_id, policy_id = mock_data.create_new_policy(
+ subject_category_name="subject_category1",
+ object_category_name="object_category1",
+ action_category_name="action_category1",
+ meta_rule_name="meta_rule_1")
+ object_id = mock_data.create_object(policy_id)
+ data_id = mock_data.create_object_data(policy_id=policy_id, category_id=object_category_id)
+ assignment_helper.add_object_assignment(policy_id, object_id, object_category_id, data_id)
+ obj_assignments = assignment_helper.get_object_assignments(policy_id)
+ assert len(obj_assignments) == 1
def test_add_object_assignments(db):
- policy_id = mock_data.get_policy_id()
- object_id = "object_id_1"
- category_id = "category_id_1"
- data_id = "data_id_1"
- object_assignments = add_object_assignment(policy_id, object_id, category_id, data_id)
+ subject_category_id, object_category_id, action_category_id, meta_rule_id, policy_id = mock_data.create_new_policy(
+ subject_category_name="subject_category1",
+ object_category_name="object_category1",
+ action_category_name="action_category1",
+ meta_rule_name="meta_rule_1")
+ object_id = mock_data.create_object(policy_id)
+ data_id = mock_data.create_object_data(policy_id=policy_id, category_id=object_category_id)
+ object_assignments = assignment_helper.add_object_assignment(policy_id, object_id, object_category_id, data_id)
assert object_assignments
object_id_1 = list(object_assignments.keys())[0]
assert object_assignments[object_id_1]["policy_id"] == policy_id
assert object_assignments[object_id_1]["object_id"] == object_id
- assert object_assignments[object_id_1]["category_id"] == category_id
+ assert object_assignments[object_id_1]["category_id"] == object_category_id
assert len(object_assignments[object_id_1].get("assignments")) == 1
assert data_id in object_assignments[object_id_1].get("assignments")
+ with pytest.raises(ObjectAssignmentExisting):
+ assignment_helper.add_object_assignment(policy_id, object_id, object_category_id, data_id)
+
def test_delete_object_assignment(db):
- policy_id = mock_data.get_policy_id()
- add_object_assignment(policy_id, "", "", "")
- object_id = "action_id_2"
- category_id = "category_id_2"
- data_id = "data_id_2"
- add_object_assignment(policy_id, object_id, category_id, data_id)
- delete_object_assignment(policy_id, "", "", "")
- assignments = get_object_assignments(policy_id, )
- assert len(assignments) == 1
+ subject_category_id, object_category_id, action_category_id, meta_rule_id, policy_id = mock_data.create_new_policy(
+ subject_category_name="subject_category1",
+ object_category_name="object_category1",
+ action_category_name="action_category1",
+ meta_rule_name="meta_rule_1")
+ object_id = mock_data.create_object(policy_id)
+ data_id = mock_data.create_object_data(policy_id=policy_id, category_id=object_category_id)
+ assignment_helper.add_object_assignment(policy_id, object_id, object_category_id, data_id)
+
+ assignment_helper.delete_object_assignment(policy_id, object_id, object_category_id, data_id=data_id)
+ assignments = assignment_helper.get_object_assignments(policy_id)
+ assert len(assignments) == 0
def test_delete_object_assignment_with_invalid_policy_id(db):
policy_id = "invalid_id"
- delete_object_assignment(policy_id, "", "", "")
- assignments = get_object_assignments(policy_id, )
+ assignment_helper.delete_object_assignment(policy_id, "", "", "")
+ assignments = assignment_helper.get_object_assignments(policy_id, )
assert len(assignments) == 0
def test_get_subject_assignments(db):
- policy_id = mock_data.get_policy_id()
- subject_id = "object_id_1"
- category_id = "category_id_1"
- data_id = "data_id_1"
- add_subject_assignment(policy_id, subject_id, category_id, data_id)
- subj_assignments = get_subject_assignments(policy_id, subject_id, category_id)
+ subject_category_id, object_category_id, action_category_id, meta_rule_id, policy_id = mock_data.create_new_policy(
+ subject_category_name="subject_category1",
+ object_category_name="object_category1",
+ action_category_name="action_category1",
+ meta_rule_name="meta_rule_1")
+ subject_id = mock_data.create_subject(policy_id)
+ data_id = mock_data.create_subject_data(policy_id=policy_id, category_id=subject_category_id)
+
+ assignment_helper.add_subject_assignment(policy_id, subject_id, subject_category_id, data_id)
+ subj_assignments = assignment_helper.get_subject_assignments(policy_id, subject_id, subject_category_id)
subject_id_1 = list(subj_assignments.keys())[0]
assert subj_assignments[subject_id_1]["policy_id"] == policy_id
assert subj_assignments[subject_id_1]["subject_id"] == subject_id
- assert subj_assignments[subject_id_1]["category_id"] == category_id
+ assert subj_assignments[subject_id_1]["category_id"] == subject_category_id
assert len(subj_assignments[subject_id_1].get("assignments")) == 1
assert data_id in subj_assignments[subject_id_1].get("assignments")
def test_get_subject_assignments_by_policy_id(db):
- policy_id = mock_data.get_policy_id()
- subject_id_1 = "subject_id_1"
- category_id_1 = "category_id_1"
- data_id = "data_id_1"
- add_subject_assignment(policy_id, subject_id_1, category_id_1, data_id)
- subject_id_2 = "subject_id_2"
- category_id_2 = "category_id_2"
- data_id = "data_id_2"
- add_subject_assignment(policy_id, subject_id_2, category_id_2, data_id)
- subject_id_3 = "subject_id_3"
- category_id_3 = "category_id_3"
- data_id = "data_id_3"
- add_subject_assignment(policy_id, subject_id_3, category_id_3, data_id)
- subj_assignments = get_subject_assignments(policy_id)
- assert len(subj_assignments) == 3
+ subject_category_id, object_category_id, action_category_id, meta_rule_id, policy_id = mock_data.create_new_policy(
+ subject_category_name="subject_category1",
+ object_category_name="object_category1",
+ action_category_name="action_category1",
+ meta_rule_name="meta_rule_1")
+ subject_id = mock_data.create_subject(policy_id)
+ data_id = mock_data.create_subject_data(policy_id=policy_id, category_id=subject_category_id)
+
+ assignment_helper.add_subject_assignment(policy_id, subject_id, subject_category_id, data_id)
+ subj_assignments = assignment_helper.get_subject_assignments(policy_id)
+ assert len(subj_assignments) == 1
def test_add_subject_assignments(db):
- policy_id = mock_data.get_policy_id()
- subject_id = "subject_id_1"
- category_id = "category_id_1"
- data_id = "data_id_1"
- subject_assignments = add_subject_assignment(policy_id, subject_id, category_id, data_id)
+ subject_category_id, object_category_id, action_category_id, meta_rule_id, policy_id = mock_data.create_new_policy(
+ subject_category_name="subject_category1",
+ object_category_name="object_category1",
+ action_category_name="action_category1",
+ meta_rule_name="meta_rule_1")
+ subject_id = mock_data.create_subject(policy_id)
+ data_id = mock_data.create_subject_data(policy_id=policy_id, category_id=subject_category_id)
+
+ subject_assignments = assignment_helper.add_subject_assignment(policy_id, subject_id, subject_category_id, data_id)
assert subject_assignments
subject_id_1 = list(subject_assignments.keys())[0]
assert subject_assignments[subject_id_1]["policy_id"] == policy_id
assert subject_assignments[subject_id_1]["subject_id"] == subject_id
- assert subject_assignments[subject_id_1]["category_id"] == category_id
+ assert subject_assignments[subject_id_1]["category_id"] == subject_category_id
assert len(subject_assignments[subject_id_1].get("assignments")) == 1
assert data_id in subject_assignments[subject_id_1].get("assignments")
+ with pytest.raises(SubjectAssignmentExisting):
+ assignment_helper.add_subject_assignment(policy_id, subject_id, subject_category_id, data_id)
+
def test_delete_subject_assignment(db):
- policy_id = mock_data.get_policy_id()
- add_subject_assignment(policy_id, "", "", "")
- subject_id = "subject_id_2"
- category_id = "category_id_2"
- data_id = "data_id_2"
- add_subject_assignment(policy_id, subject_id, category_id, data_id)
- delete_subject_assignment(policy_id, "", "", "")
- assignments = get_subject_assignments(policy_id, )
- assert len(assignments) == 1
+ subject_category_id, object_category_id, action_category_id, meta_rule_id, policy_id = mock_data.create_new_policy(
+ subject_category_name="subject_category1",
+ object_category_name="object_category1",
+ action_category_name="action_category1",
+ meta_rule_name="meta_rule_1")
+ subject_id = mock_data.create_subject(policy_id)
+ data_id = mock_data.create_subject_data(policy_id=policy_id, category_id=subject_category_id)
+ assignment_helper.add_subject_assignment(policy_id, subject_id, subject_category_id, data_id)
+ assignment_helper.delete_subject_assignment(policy_id, subject_id, subject_category_id, data_id)
+ assignments = assignment_helper.get_subject_assignments(policy_id)
+ assert len(assignments) == 0
def test_delete_subject_assignment_with_invalid_policy_id(db):
policy_id = "invalid_id"
- delete_subject_assignment(policy_id, "", "", "")
- assignments = get_subject_assignments(policy_id, )
+ assignment_helper.delete_subject_assignment(policy_id, "", "", "")
+ assignments = assignment_helper.get_subject_assignments(policy_id, )
assert len(assignments) == 0
diff --git a/python_moondb/tests/unit_python/policies/test_data.py b/python_moondb/tests/unit_python/policies/test_data.py
index 67fa44fb..fa3f8c06 100755
--- a/python_moondb/tests/unit_python/policies/test_data.py
+++ b/python_moondb/tests/unit_python/policies/test_data.py
@@ -1,328 +1,269 @@
-import policies.mock_data as mock_data
+# 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 helpers.mock_data as mock_data
+import policies.mock_data
+import helpers.data_helper as data_helper
import pytest
+import logging
+from python_moonutilities.exceptions import *
-
-def get_action_data(policy_id, data_id=None, category_id=None):
- from python_moondb.core import PolicyManager
- return PolicyManager.get_action_data("", policy_id, data_id, category_id)
-
-
-def add_action_data(policy_id, data_id=None, category_id=None, value=None):
- from python_moondb.core import PolicyManager
- return PolicyManager.add_action_data("", policy_id, data_id, category_id, value)
-
-
-def delete_action_data(policy_id, data_id):
- from python_moondb.core import PolicyManager
- PolicyManager.delete_action_data("", policy_id, data_id)
-
-
-def get_object_data(policy_id, data_id=None, category_id=None):
- from python_moondb.core import PolicyManager
- return PolicyManager.get_object_data("", policy_id, data_id, category_id)
-
-
-def add_object_data(policy_id, data_id=None, category_id=None, value=None):
- from python_moondb.core import PolicyManager
- return PolicyManager.add_object_data("", policy_id, data_id, category_id, value)
-
-
-def delete_object_data(policy_id, data_id):
- from python_moondb.core import PolicyManager
- PolicyManager.delete_object_data("", policy_id, data_id)
-
-
-def get_subject_data(policy_id, data_id=None, category_id=None):
- from python_moondb.core import PolicyManager
- return PolicyManager.get_subject_data("", policy_id, data_id, category_id)
-
-
-def add_subject_data(policy_id, data_id=None, category_id=None, value=None):
- from python_moondb.core import PolicyManager
- return PolicyManager.set_subject_data("", policy_id, data_id, category_id, value)
-
-
-def delete_subject_data(policy_id, data_id):
- from python_moondb.core import PolicyManager
- PolicyManager.delete_subject_data("", policy_id, data_id)
-
-
-def get_actions(policy_id, perimeter_id=None):
- from python_moondb.core import PolicyManager
- return PolicyManager.get_actions("", policy_id, perimeter_id)
-
-
-def add_action(policy_id, perimeter_id=None, value=None):
- from python_moondb.core import PolicyManager
- return PolicyManager.add_action("", policy_id, perimeter_id, value)
-
-
-def delete_action(policy_id, perimeter_id):
- from python_moondb.core import PolicyManager
- PolicyManager.delete_action("", policy_id, perimeter_id)
-
-
-def get_objects(policy_id, perimeter_id=None):
- from python_moondb.core import PolicyManager
- return PolicyManager.get_objects("", policy_id, perimeter_id)
-
-
-def add_object(policy_id, perimeter_id=None, value=None):
- from python_moondb.core import PolicyManager
- return PolicyManager.add_object("", policy_id, perimeter_id, value)
-
-
-def delete_object(policy_id, perimeter_id):
- from python_moondb.core import PolicyManager
- PolicyManager.delete_object("", policy_id, perimeter_id)
-
-
-def get_subjects(policy_id, perimeter_id=None):
- from python_moondb.core import PolicyManager
- return PolicyManager.get_subjects("", policy_id, perimeter_id)
-
-
-def add_subject(policy_id, perimeter_id=None, value=None):
- from python_moondb.core import PolicyManager
- return PolicyManager.add_subject("", policy_id, perimeter_id, value)
-
-
-def delete_subject(policy_id, perimeter_id):
- from python_moondb.core import PolicyManager
- PolicyManager.delete_subject("", policy_id, perimeter_id)
-
-
-def get_available_metadata(policy_id):
- from python_moondb.core import PolicyManager
- return PolicyManager.get_available_metadata("", policy_id)
+logger = logging.getLogger("python_moondb.tests.api.test_data")
def test_get_action_data(db):
- policy_id = mock_data.get_policy_id()
- get_available_metadata(policy_id)
-
- policy_id = policy_id
- data_id = "data_id_1"
- category_id = "action_category_id1"
+ subject_category_id, object_category_id, action_category_id, meta_rule_id, policy_id = mock_data.create_new_policy(
+ subject_category_name="subject_category1",
+ object_category_name="object_category1",
+ action_category_name="action_category1",
+ meta_rule_name="meta_rule_1")
value = {
"name": "action-type",
"description": {"vm-action": "", "storage-action": "", },
}
- add_action_data(policy_id, data_id, category_id, value)
- action_data = get_action_data(policy_id, data_id, category_id)
- assert action_data
- assert len(action_data[0]['data']) == 1
+ action_data = data_helper.add_action_data(policy_id=policy_id, category_id=action_category_id, value=value)
+ data_id = list(action_data["data"])[0]
+ found_action_data = data_helper.get_action_data(policy_id=policy_id, data_id=data_id,
+ category_id=action_category_id)
+ assert found_action_data
+ assert len(found_action_data[0]["data"]) == 1
def test_get_action_data_with_invalid_category_id(db):
- policy_id = mock_data.get_policy_id()
- get_available_metadata(policy_id)
- data_id = "data_id_1"
- category_id = "action_category_id1"
- value = {
- "name": "action-type",
- "description": {"vm-action": "", "storage-action": "", },
- }
- add_action_data(policy_id, data_id, category_id, value)
- action_data = get_action_data(policy_id)
- assert action_data
- assert len(action_data[0]['data']) == 1
+ subject_category_id, object_category_id, action_category_id, meta_rule_id, policy_id = mock_data.create_new_policy(
+ subject_category_name="subject_category1",
+ object_category_name="object_category1",
+ action_category_name="action_category1",
+ meta_rule_name="meta_rule_1")
+ action_data = data_helper.get_action_data(policy_id=policy_id, category_id="invalid")
+ assert len(action_data) == 0
def test_add_action_data(db):
- policy_id = mock_data.get_policy_id()
- data_id = "data_id_1"
- category_id = "category_id_1"
+ subject_category_id, object_category_id, action_category_id, meta_rule_id, policy_id = mock_data.create_new_policy(
+ subject_category_name="subject_category1",
+ object_category_name="object_category1",
+ action_category_name="action_category1",
+ meta_rule_name="meta_rule_1")
value = {
"name": "action-type",
"description": {"vm-action": "", "storage-action": "", },
}
- action_data = add_action_data(policy_id, data_id, category_id, value).get('data')
+ action_data = data_helper.add_action_data(policy_id=policy_id, category_id=action_category_id, value=value)
assert action_data
- action_data_id = list(action_data.keys())[0]
- assert action_data[action_data_id].get('policy_id') == policy_id
+ assert len(action_data['data']) == 1
def test_add_action_data_with_invalid_category_id(db):
- policy_id = mock_data.get_policy_id()
- data_id = "data_id_1"
+ subject_category_id, object_category_id, action_category_id, meta_rule_id, policy_id = mock_data.create_new_policy(
+ subject_category_name="subject_category1",
+ object_category_name="object_category1",
+ action_category_name="action_category1",
+ meta_rule_name="meta_rule_1")
value = {
"name": "action-type",
"description": {"vm-action": "", "storage-action": "", },
}
with pytest.raises(Exception) as exception_info:
- add_action_data(policy_id=policy_id, data_id=data_id, value=value).get('data')
+ data_helper.add_action_data(policy_id=policy_id, value=value).get('data')
assert str(exception_info.value) == 'Invalid category id'
def test_delete_action_data(db):
- policy_id = mock_data.get_policy_id()
- get_available_metadata(policy_id)
- data_id = "data_id_1"
- category_id = "category_id_1"
+ subject_category_id, object_category_id, action_category_id, meta_rule_id, policy_id = mock_data.create_new_policy(
+ subject_category_name="subject_category1",
+ object_category_name="object_category1",
+ action_category_name="action_category1",
+ meta_rule_name="meta_rule_1")
+ data_helper.get_available_metadata(policy_id)
value = {
"name": "action-type",
"description": {"vm-action": "", "storage-action": "", },
}
- action_data = add_action_data(policy_id, data_id, category_id, value).get('data')
- action_data_id = list(action_data.keys())[0]
- delete_action_data(action_data[action_data_id].get('policy_id'), None)
- new_action_data = get_action_data(policy_id)
+ action_data = data_helper.add_action_data(policy_id=policy_id, category_id=action_category_id, value=value)
+ data_id = list(action_data["data"])[0]
+ data_helper.delete_action_data(policy_id, data_id)
+ new_action_data = data_helper.get_action_data(policy_id)
assert len(new_action_data[0]['data']) == 0
def test_get_object_data(db):
- policy_id = mock_data.get_policy_id()
- get_available_metadata(policy_id)
- data_id = "data_id_1"
- category_id = "object_category_id1"
+ subject_category_id, object_category_id, action_category_id, meta_rule_id, policy_id = mock_data.create_new_policy(
+ subject_category_name="subject_category1",
+ object_category_name="object_category1",
+ action_category_name="action_category1",
+ meta_rule_name="meta_rule_1")
value = {
"name": "object-security-level",
"description": {"low": "", "medium": "", "high": ""},
}
- add_object_data(policy_id, data_id, category_id, value)
- object_data = get_object_data(policy_id, data_id, category_id)
- assert object_data
- assert len(object_data[0]['data']) == 1
+ object_data = data_helper.add_object_data(policy_id=policy_id, category_id=object_category_id, value=value)
+ data_id = list(object_data["data"])[0]
+ found_object_data = data_helper.get_object_data(policy_id=policy_id, data_id=data_id,
+ category_id=object_category_id)
+ assert found_object_data
+ assert len(found_object_data[0]['data']) == 1
def test_get_object_data_with_invalid_category_id(db):
- policy_id = mock_data.get_policy_id()
- get_available_metadata(policy_id)
- data_id = "data_id_1"
- category_id = "object_category_id1"
- value = {
- "name": "object-security-level",
- "description": {"low": "", "medium": "", "high": ""},
- }
- add_object_data(policy_id, data_id, category_id, value)
- object_data = get_object_data(policy_id)
- assert object_data
- assert len(object_data[0]['data']) == 1
+ subject_category_id, object_category_id, action_category_id, meta_rule_id, policy_id = mock_data.create_new_policy(
+ subject_category_name="subject_category1",
+ object_category_name="object_category1",
+ action_category_name="action_category1",
+ meta_rule_name="meta_rule_1")
+ object_data = data_helper.get_object_data(policy_id=policy_id, category_id="invalid")
+ assert len(object_data) == 0
def test_add_object_data(db):
- policy_id = mock_data.get_policy_id()
- data_id = "data_id_1"
- category_id = "object_category_id1"
+ subject_category_id, object_category_id, action_category_id, meta_rule_id, policy_id = mock_data.create_new_policy(
+ subject_category_name="subject_category1",
+ object_category_name="object_category1",
+ action_category_name="action_category1",
+ meta_rule_name="meta_rule_1")
value = {
"name": "object-security-level",
"description": {"low": "", "medium": "", "high": ""},
}
- object_data = add_object_data(policy_id, data_id, category_id, value).get('data')
+ object_data = data_helper.add_object_data(policy_id=policy_id, category_id=object_category_id, value=value).get(
+ 'data')
assert object_data
object_data_id = list(object_data.keys())[0]
assert object_data[object_data_id].get('policy_id') == policy_id
def test_add_object_data_with_invalid_category_id(db):
- policy_id = mock_data.get_policy_id()
- data_id = "data_id_1"
+ subject_category_id, object_category_id, action_category_id, meta_rule_id, policy_id = mock_data.create_new_policy(
+ subject_category_name="subject_category1",
+ object_category_name="object_category1",
+ action_category_name="action_category1",
+ meta_rule_name="meta_rule_1")
value = {
"name": "object-security-level",
"description": {"low": "", "medium": "", "high": ""},
}
- with pytest.raises(Exception) as exception_info:
- add_object_data(policy_id=policy_id, data_id=data_id, value=value).get('data')
- assert str(exception_info.value) == 'Invalid category id'
+ with pytest.raises(MetaDataUnknown) as exception_info:
+ data_helper.add_object_data(policy_id=policy_id, category_id="invalid", value=value).get('data')
+ assert str(exception_info.value) == '400: Meta data Unknown'
def test_delete_object_data(db):
- policy_id = mock_data.get_policy_id()
- get_available_metadata(policy_id)
- data_id = "data_id_1"
- category_id = "object_category_id1"
+ subject_category_id, object_category_id, action_category_id, meta_rule_id, policy_id = mock_data.create_new_policy(
+ subject_category_name="subject_category1",
+ object_category_name="object_category1",
+ action_category_name="action_category1",
+ meta_rule_name="meta_rule_1")
value = {
"name": "object-security-level",
"description": {"low": "", "medium": "", "high": ""},
}
- object_data = add_object_data(policy_id, data_id, category_id, value).get('data')
+ object_data = data_helper.add_object_data(policy_id=policy_id, category_id=object_category_id, value=value).get(
+ 'data')
object_data_id = list(object_data.keys())[0]
- delete_object_data(object_data[object_data_id].get('policy_id'), data_id)
- new_object_data = get_object_data(policy_id)
+ data_helper.delete_object_data(policy_id=object_data[object_data_id].get('policy_id'), data_id=object_data_id)
+ new_object_data = data_helper.get_object_data(policy_id)
assert len(new_object_data[0]['data']) == 0
def test_get_subject_data(db):
- policy_id = mock_data.get_policy_id()
- get_available_metadata(policy_id)
- data_id = "data_id_1"
- category_id = "subject_category_id1"
+ subject_category_id, object_category_id, action_category_id, meta_rule_id, policy_id = mock_data.create_new_policy(
+ subject_category_name="subject_category1",
+ object_category_name="object_category1",
+ action_category_name="action_category1",
+ meta_rule_name="meta_rule_1")
value = {
"name": "subject-security-level",
"description": {"low": "", "medium": "", "high": ""},
}
- add_subject_data(policy_id, data_id, category_id, value)
- subject_data = get_subject_data(policy_id, data_id, category_id)
+ subject_data = data_helper.add_subject_data(policy_id=policy_id, category_id=subject_category_id, value=value).get(
+ 'data')
+ subject_data_id = list(subject_data.keys())[0]
+ subject_data = data_helper.get_subject_data(policy_id, subject_data_id, subject_category_id)
assert subject_data
assert len(subject_data[0]['data']) == 1
def test_get_subject_data_with_invalid_category_id(db):
- policy_id = mock_data.get_policy_id()
- get_available_metadata(policy_id)
- data_id = "data_id_1"
- category_id = "subject_category_id1"
+ subject_category_id, object_category_id, action_category_id, meta_rule_id, policy_id = mock_data.create_new_policy(
+ subject_category_name="subject_category1",
+ object_category_name="object_category1",
+ action_category_name="action_category1",
+ meta_rule_name="meta_rule_1")
value = {
"name": "subject-security-level",
"description": {"low": "", "medium": "", "high": ""},
}
- add_subject_data(policy_id, data_id, category_id, value)
- subject_data = get_subject_data(policy_id)
- assert subject_data
- assert len(subject_data[0]['data']) == 1
+ subject_data = data_helper.add_subject_data(policy_id=policy_id, category_id=subject_category_id, value=value).get(
+ 'data')
+ subject_data_id = list(subject_data.keys())[0]
+ found_subject_data = data_helper.get_subject_data(policy_id, subject_data_id, "invalid")
+ assert len(found_subject_data) == 0
def test_add_subject_data(db):
- policy_id = mock_data.get_policy_id()
- data_id = "data_id_1"
- category_id = "subject_category_id1"
+ subject_category_id, object_category_id, action_category_id, meta_rule_id, policy_id = mock_data.create_new_policy(
+ subject_category_name="subject_category1",
+ object_category_name="object_category1",
+ action_category_name="action_category1",
+ meta_rule_name="meta_rule_1")
value = {
"name": "subject-security-level",
"description": {"low": "", "medium": "", "high": ""},
}
- subject_data = add_subject_data(policy_id, data_id, category_id, value).get('data')
+ subject_data = data_helper.add_subject_data(policy_id=policy_id, category_id=subject_category_id, value=value).get(
+ 'data')
assert subject_data
subject_data_id = list(subject_data.keys())[0]
assert subject_data[subject_data_id].get('policy_id') == policy_id
def test_add_subject_data_with_no_category_id(db):
- policy_id = mock_data.get_policy_id()
- data_id = "data_id_1"
+ subject_category_id, object_category_id, action_category_id, meta_rule_id, policy_id = mock_data.create_new_policy(
+ subject_category_name="subject_category1",
+ object_category_name="object_category1",
+ action_category_name="action_category1",
+ meta_rule_name="meta_rule_1")
value = {
"name": "subject-security-level",
"description": {"low": "", "medium": "", "high": ""},
}
with pytest.raises(Exception) as exception_info:
- add_subject_data(policy_id=policy_id, data_id=data_id, value=value).get('data')
+ data_helper.add_subject_data(policy_id=policy_id, data_id=subject_category_id, value=value).get('data')
assert str(exception_info.value) == 'Invalid category id'
def test_delete_subject_data(db):
- policy_id = mock_data.get_policy_id()
- get_available_metadata(policy_id)
- data_id = "data_id_1"
- category_id = "subject_category_id1"
+ subject_category_id, object_category_id, action_category_id, meta_rule_id, policy_id = mock_data.create_new_policy(
+ subject_category_name="subject_category1",
+ object_category_name="object_category1",
+ action_category_name="action_category1",
+ meta_rule_name="meta_rule_1")
value = {
"name": "subject-security-level",
"description": {"low": "", "medium": "", "high": ""},
}
- subject_data = add_subject_data(policy_id, data_id, category_id, value).get('data')
+ subject_data = data_helper.add_subject_data(policy_id=policy_id, category_id=subject_category_id, value=value).get(
+ 'data')
subject_data_id = list(subject_data.keys())[0]
- delete_subject_data(subject_data[subject_data_id].get('policy_id'), data_id)
- new_subject_data = get_subject_data(policy_id)
+ data_helper.delete_subject_data(subject_data[subject_data_id].get('policy_id'), subject_data_id)
+ new_subject_data = data_helper.get_subject_data(policy_id)
assert len(new_subject_data[0]['data']) == 0
def test_get_actions(db):
- policy_id = mock_data.get_policy_id()
+ subject_category_id, object_category_id, action_category_id, meta_rule_id, policy_id = mock_data.create_new_policy(
+ subject_category_name="subject_category1",
+ object_category_name="object_category1",
+ action_category_name="action_category1",
+ meta_rule_name="meta_rule_1")
value = {
"name": "test_action",
"description": "test",
}
- add_action(policy_id=policy_id, value=value)
- actions = get_actions(policy_id, )
+ data_helper.add_action(policy_id=policy_id, value=value)
+ actions = data_helper.get_actions(policy_id, )
assert actions
assert len(actions) == 1
action_id = list(actions.keys())[0]
@@ -330,24 +271,71 @@ def test_get_actions(db):
def test_add_action(db):
- policy_id = mock_data.get_policy_id()
+ subject_category_id, object_category_id, action_category_id, meta_rule_id, policy_id = mock_data.create_new_policy(
+ subject_category_name="subject_category1",
+ object_category_name="object_category1",
+ action_category_name="action_category1",
+ meta_rule_name="meta_rule_1")
value = {
"name": "test_action",
"description": "test",
}
- action = add_action(policy_id=policy_id, value=value)
+ action = data_helper.add_action(policy_id=policy_id, value=value)
assert action
action_id = list(action.keys())[0]
assert len(action[action_id].get('policy_list')) == 1
+def test_add_action_twice(db):
+ subject_category_id, object_category_id, action_category_id, meta_rule_id, policy_id = mock_data.create_new_policy(
+ subject_category_name="subject_category1",
+ object_category_name="object_category1",
+ action_category_name="action_category1",
+ meta_rule_name="meta_rule_1")
+ value = {
+ "name": "test_action",
+ "description": "test",
+ }
+ data_helper.add_action(policy_id=policy_id, value=value)
+ with pytest.raises(ActionExisting):
+ data_helper.add_action(policy_id=policy_id, value=value)
+
+
+def test_add_action_blank_name(db):
+ policy_id = policies.mock_data.get_policy_id()
+ value = {
+ "name": "",
+ "description": "test",
+ }
+ with pytest.raises(Exception) as exception_info:
+ data_helper.add_action(policy_id=policy_id, value=value)
+ assert str(exception_info.value) == '400: Perimeter Name is Invalid'
+
+
+def test_add_action_with_name_space(db):
+ policy_id = policies.mock_data.get_policy_id()
+ value = {
+ "name": " ",
+ "description": "test",
+ }
+ with pytest.raises(Exception) as exception_info:
+ data_helper.add_action(policy_id=policy_id, value=value)
+ assert str(exception_info.value) == '400: Perimeter Name is Invalid'
+
+
def test_add_action_multiple_times(db):
- policy_id = mock_data.get_policy_id()
+ subject_category_id, object_category_id, action_category_id, meta_rule_id, policy_id1 = mock_data.create_new_policy(
+ subject_category_name="subject_category1",
+ object_category_name="object_category1",
+ action_category_name="action_category1",
+ meta_rule_name="meta_rule_1",
+ model_name="model1")
value = {
"name": "test_action",
"description": "test",
}
- action = add_action(policy_id=policy_id, value=value)
+ action = data_helper.add_action(policy_id=policy_id1, value=value)
+ logger.info("action : {}".format(action))
action_id = list(action.keys())[0]
perimeter_id = action[action_id].get('id')
assert action
@@ -356,22 +344,33 @@ def test_add_action_multiple_times(db):
"description": "test",
"policy_list": ['policy_id_3', 'policy_id_4']
}
- action = add_action(mock_data.get_policy_id(), perimeter_id, value)
+ subject_category_id, object_category_id, action_category_id, meta_rule_id, policy_id2 = mock_data.create_new_policy(
+ subject_category_name="subject_category2",
+ object_category_name="object_category2",
+ action_category_name="action_category2",
+ meta_rule_name="meta_rule_2",
+ model_name="model2")
+ action = data_helper.add_action(policy_id=policy_id2, perimeter_id=perimeter_id, value=value)
+ logger.info("action : {}".format(action))
assert action
action_id = list(action.keys())[0]
assert len(action[action_id].get('policy_list')) == 2
def test_delete_action(db):
- policy_id = mock_data.get_policy_id()
+ subject_category_id, object_category_id, action_category_id, meta_rule_id, policy_id = mock_data.create_new_policy(
+ subject_category_name="subject_category1",
+ object_category_name="object_category1",
+ action_category_name="action_category1",
+ meta_rule_name="meta_rule_1")
value = {
"name": "test_action",
"description": "test",
}
- action = add_action(policy_id=policy_id, value=value)
+ action = data_helper.add_action(policy_id=policy_id, value=value)
action_id = list(action.keys())[0]
- delete_action(policy_id, action_id)
- actions = get_actions(policy_id, )
+ data_helper.delete_action(policy_id, action_id)
+ actions = data_helper.get_actions(policy_id, )
assert not actions
@@ -379,18 +378,22 @@ def test_delete_action_with_invalid_perimeter_id(db):
policy_id = "invalid"
perimeter_id = "invalid"
with pytest.raises(Exception) as exception_info:
- delete_action(policy_id, perimeter_id)
- assert str(exception_info.value) == '400: Action Unknown'
+ data_helper.delete_action(policy_id, perimeter_id)
+ assert str(exception_info.value) == '400: Policy Unknown'
def test_get_objects(db):
- policy_id = mock_data.get_policy_id()
+ subject_category_id, object_category_id, action_category_id, meta_rule_id, policy_id = mock_data.create_new_policy(
+ subject_category_name="subject_category1",
+ object_category_name="object_category1",
+ action_category_name="action_category1",
+ meta_rule_name="meta_rule_1")
value = {
"name": "test_object",
"description": "test",
}
- add_object(policy_id=policy_id, value=value)
- objects = get_objects(policy_id, )
+ data_helper.add_object(policy_id=policy_id, value=value)
+ objects = data_helper.get_objects(policy_id, )
assert objects
assert len(objects) == 1
object_id = list(objects.keys())[0]
@@ -398,48 +401,69 @@ def test_get_objects(db):
def test_add_object(db):
- policy_id = mock_data.get_policy_id()
+ subject_category_id, object_category_id, action_category_id, meta_rule_id, policy_id = mock_data.create_new_policy(
+ subject_category_name="subject_category1",
+ object_category_name="object_category1",
+ action_category_name="action_category1",
+ meta_rule_name="meta_rule_1")
value = {
"name": "test_object",
"description": "test",
}
- added_object = add_object(policy_id=policy_id, value=value)
+ added_object = data_helper.add_object(policy_id=policy_id, value=value)
assert added_object
object_id = list(added_object.keys())[0]
assert len(added_object[object_id].get('policy_list')) == 1
+ with pytest.raises(ObjectExisting):
+ data_helper.add_object(policy_id=policy_id, value=value)
+
def test_add_objects_multiple_times(db):
- policy_id = mock_data.get_policy_id()
+ subject_category_id, object_category_id, action_category_id, meta_rule_id, policy_id = mock_data.create_new_policy(
+ subject_category_name="subject_category1",
+ object_category_name="object_category1",
+ action_category_name="action_category1",
+ meta_rule_name="meta_rule_1",
+ model_name="model1")
value = {
"name": "test_object",
"description": "test",
}
- added_object = add_object(policy_id=policy_id, value=value)
+ added_object = data_helper.add_object(policy_id=policy_id, value=value)
object_id = list(added_object.keys())[0]
perimeter_id = added_object[object_id].get('id')
assert added_object
value = {
"name": "test_object",
"description": "test",
- "policy_list": ['policy_id_3', 'policy_id_4']
}
- added_object = add_object(mock_data.get_policy_id(), perimeter_id, value)
+ subject_category_id, object_category_id, action_category_id, meta_rule_id, policy_id = mock_data.create_new_policy(
+ subject_category_name="subject_category2",
+ object_category_name="object_category2",
+ action_category_name="action_category2",
+ meta_rule_name="meta_rule_2",
+ model_name="model2")
+ added_object = data_helper.add_object(policy_id=policy_id, perimeter_id=perimeter_id, value=value)
assert added_object
object_id = list(added_object.keys())[0]
assert len(added_object[object_id].get('policy_list')) == 2
def test_delete_object(db):
- policy_id = mock_data.get_policy_id()
+ subject_category_id, object_category_id, action_category_id, meta_rule_id, policy_id = mock_data.create_new_policy(
+ subject_category_name="subject_category1",
+ object_category_name="object_category1",
+ action_category_name="action_category1",
+ meta_rule_name="meta_rule_1")
value = {
"name": "test_object",
"description": "test",
}
- added_object = add_object(policy_id=policy_id, value=value)
+ added_object = data_helper.add_object(policy_id=policy_id, value=value)
object_id = list(added_object.keys())[0]
- delete_object(policy_id, object_id)
- objects = get_objects(policy_id, )
+ data_helper.delete_object(policy_id, object_id)
+ objects = data_helper.get_objects(policy_id, )
assert not objects
@@ -447,67 +471,107 @@ def test_delete_object_with_invalid_perimeter_id(db):
policy_id = "invalid"
perimeter_id = "invalid"
with pytest.raises(Exception) as exception_info:
- delete_object(policy_id, perimeter_id)
- assert str(exception_info.value) == '400: Object Unknown'
+ data_helper.delete_object(policy_id, perimeter_id)
+ assert str(exception_info.value) == '400: Policy Unknown'
def test_get_subjects(db):
- policy_id = mock_data.get_policy_id()
+ subject_category_id, object_category_id, action_category_id, meta_rule_id, policy_id = mock_data.create_new_policy(
+ subject_category_name="subject_category1",
+ object_category_name="object_category1",
+ action_category_name="action_category1",
+ meta_rule_name="meta_rule_1")
value = {
"name": "testuser",
"description": "test",
}
- add_subject(policy_id=policy_id, value=value)
- subjects = get_subjects(policy_id, )
+ data_helper.add_subject(policy_id=policy_id, value=value)
+ subjects = data_helper.get_subjects(policy_id=policy_id)
assert subjects
assert len(subjects) == 1
subject_id = list(subjects.keys())[0]
assert subjects[subject_id].get('policy_list')[0] == policy_id
+def test_get_subjects_with_invalid_policy_id(db):
+ subject_category_id, object_category_id, action_category_id, meta_rule_id, policy_id = mock_data.create_new_policy(
+ subject_category_name="subject_category1",
+ object_category_name="object_category1",
+ action_category_name="action_category1",
+ meta_rule_name="meta_rule_1")
+ value = {
+ "name": "testuser",
+ "description": "test",
+ }
+ data_helper.add_subject(policy_id=policy_id, value=value)
+ with pytest.raises(PolicyUnknown):
+ data_helper.get_subjects(policy_id="invalid")
+
+
def test_add_subject(db):
- policy_id = mock_data.get_policy_id()
+ subject_category_id, object_category_id, action_category_id, meta_rule_id, policy_id = mock_data.create_new_policy(
+ subject_category_name="subject_category1",
+ object_category_name="object_category1",
+ action_category_name="action_category1",
+ meta_rule_name="meta_rule_1")
value = {
"name": "testuser",
"description": "test",
}
- subject = add_subject(policy_id=policy_id, value=value)
+ subject = data_helper.add_subject(policy_id=policy_id, value=value)
assert subject
subject_id = list(subject.keys())[0]
assert len(subject[subject_id].get('policy_list')) == 1
+ with pytest.raises(SubjectExisting) as exception_info:
+ data_helper.add_subject(policy_id=policy_id, value=value)
+ assert str(exception_info.value) == '409: Subject Existing'
def test_add_subjects_multiple_times(db):
- policy_id = mock_data.get_policy_id()
+ subject_category_id, object_category_id, action_category_id, meta_rule_id, policy_id = mock_data.create_new_policy(
+ subject_category_name="subject_category1",
+ object_category_name="object_category1",
+ action_category_name="action_category1",
+ meta_rule_name="meta_rule_1",
+ model_name="model1")
value = {
"name": "testuser",
"description": "test",
}
- subject = add_subject(policy_id=policy_id, value=value)
+ subject = data_helper.add_subject(policy_id=policy_id, value=value)
subject_id = list(subject.keys())[0]
perimeter_id = subject[subject_id].get('id')
assert subject
value = {
"name": "testuser",
"description": "test",
- "policy_list": ['policy_id_3', 'policy_id_4']
}
- subject = add_subject(mock_data.get_policy_id(), perimeter_id, value)
+ subject_category_id, object_category_id, action_category_id, meta_rule_id, policy_id = mock_data.create_new_policy(
+ subject_category_name="subject_category2",
+ object_category_name="object_category2",
+ action_category_name="action_category2",
+ meta_rule_name="meta_rule_2",
+ model_name="model2")
+ subject = data_helper.add_subject(policy_id=policy_id, perimeter_id=perimeter_id, value=value)
assert subject
subject_id = list(subject.keys())[0]
assert len(subject[subject_id].get('policy_list')) == 2
def test_delete_subject(db):
- policy_id = mock_data.get_policy_id()
+ subject_category_id, object_category_id, action_category_id, meta_rule_id, policy_id = mock_data.create_new_policy(
+ subject_category_name="subject_category1",
+ object_category_name="object_category1",
+ action_category_name="action_category1",
+ meta_rule_name="meta_rule_1")
value = {
"name": "testuser",
"description": "test",
}
- subject = add_subject(policy_id=policy_id, value=value)
+ subject = data_helper.add_subject(policy_id=policy_id, value=value)
subject_id = list(subject.keys())[0]
- delete_subject(policy_id, subject_id)
- subjects = get_subjects(policy_id, )
+ data_helper.delete_subject(policy_id, subject_id)
+ subjects = data_helper.get_subjects(policy_id, )
assert not subjects
@@ -515,30 +579,24 @@ def test_delete_subject_with_invalid_perimeter_id(db):
policy_id = "invalid"
perimeter_id = "invalid"
with pytest.raises(Exception) as exception_info:
- delete_subject(policy_id, perimeter_id)
- assert str(exception_info.value) == '400: Subject Unknown'
+ data_helper.delete_subject(policy_id, perimeter_id)
+ assert str(exception_info.value) == '400: Policy Unknown'
def test_get_available_metadata(db):
- policy_id = mock_data.get_policy_id()
- metadata = get_available_metadata(policy_id=policy_id)
- assert metadata
- assert metadata['object'][0] == "object_category_id1"
- assert metadata['subject'][0] == "subject_category_id1"
- assert metadata['subject'][1] == "subject_category_id2"
-
-
-def test_get_available_metadata_empty_model(db):
- import policies.test_policies as test_policies
- value = mock_data.create_policy("invalid")
- policy = test_policies.add_policies(value=value)
- assert policy
- policy_id = list(policy.keys())[0]
- metadata = get_available_metadata(policy_id=policy_id)
+ subject_category_id, object_category_id, action_category_id, meta_rule_id, policy_id = mock_data.create_new_policy(
+ subject_category_name="subject_category1",
+ object_category_name="object_category1",
+ action_category_name="action_category1",
+ meta_rule_name="meta_rule_1")
+ metadata = data_helper.get_available_metadata(policy_id=policy_id)
assert metadata
+ assert metadata['object'][0] == object_category_id
+ assert metadata['subject'][0] == subject_category_id
+ assert metadata['action'][0] == action_category_id
def test_get_available_metadata_with_invalid_policy_id(db):
with pytest.raises(Exception) as exception_info:
- get_available_metadata(policy_id='invalid')
+ data_helper.get_available_metadata(policy_id='invalid')
assert '400: Policy Unknown' == str(exception_info.value)
diff --git a/python_moondb/tests/unit_python/policies/test_policies.py b/python_moondb/tests/unit_python/policies/test_policies.py
index 148034ef..07ee87fd 100755
--- a/python_moondb/tests/unit_python/policies/test_policies.py
+++ b/python_moondb/tests/unit_python/policies/test_policies.py
@@ -4,69 +4,14 @@
# or at 'http://www.apache.org/licenses/LICENSE-2.0'.
import pytest
-import policies.mock_data as mock_data
-
-
-def get_policies():
- from python_moondb.core import PolicyManager
- return PolicyManager.get_policies("admin")
-
-
-def add_policies(policy_id=None, value=None):
- from python_moondb.core import PolicyManager
- if not value:
- value = {
- "name": "test_policiy",
- "model_id": "",
- "genre": "authz",
- "description": "test",
- }
- return PolicyManager.add_policy("admin", policy_id=policy_id, value=value)
-
-
-def delete_policies(uuid=None, name=None):
- from python_moondb.core import PolicyManager
- if not uuid:
- for policy_id, policy_value in get_policies():
- if name == policy_value['name']:
- uuid = policy_id
- break
- PolicyManager.delete_policy("admin", uuid)
-
-
-def update_policy(policy_id, value):
- from python_moondb.core import PolicyManager
- return PolicyManager.update_policy("admin", policy_id, value)
-
-
-def get_policy_from_meta_rules(meta_rule_id):
- from python_moondb.core import PolicyManager
- return PolicyManager.get_policy_from_meta_rules("admin", meta_rule_id)
-
-
-def get_rules(policy_id=None, meta_rule_id=None, rule_id=None):
- from python_moondb.core import PolicyManager
- return PolicyManager.get_rules("", policy_id, meta_rule_id, rule_id)
-
-
-def add_rule(policy_id=None, meta_rule_id=None, value=None):
- from python_moondb.core import PolicyManager
- if not value:
- value = {
- "rule": ("high", "medium", "vm-action"),
- "instructions": ({"decision": "grant"}),
- "enabled": "",
- }
- return PolicyManager.add_rule("", policy_id, meta_rule_id, value)
-
-
-def delete_rule(policy_id=None, rule_id=None):
- from python_moondb.core import PolicyManager
- PolicyManager.delete_rule("", policy_id, rule_id)
+import helpers.mock_data as mock_data
+import helpers.policy_helper as policy_helper
+from python_moonutilities.exceptions import *
+import helpers.pdp_helper as pdp_helper
def test_get_policies(db):
- policies = get_policies()
+ policies = policy_helper.get_policies()
assert isinstance(policies, dict)
assert not policies
@@ -78,7 +23,7 @@ def test_add_policies(db):
"genre": "authz",
"description": "test",
}
- policies = add_policies(value=value)
+ policies = policy_helper.add_policies(value=value)
assert isinstance(policies, dict)
assert policies
assert len(policies.keys()) == 1
@@ -96,10 +41,23 @@ def test_add_policies_twice_with_same_id(db):
"genre": "authz",
"description": "test",
}
- add_policies(policy_id, value)
+ policy_helper.add_policies(policy_id, value)
+ with pytest.raises(PolicyExisting) as exception_info:
+ policy_helper.add_policies(policy_id, value)
+ # assert str(exception_info.value) == '409: Policy Error'
+
+
+def test_add_policies_twice_with_same_name(db):
+ value = {
+ "name": "test_policy",
+ "model_id": "",
+ "genre": "authz",
+ "description": "test",
+ }
+ policy_helper.add_policies(value=value)
with pytest.raises(Exception) as exception_info:
- add_policies(policy_id, value)
- assert str(exception_info.value) == '409: Policy Error'
+ policy_helper.add_policies(value=value)
+ # assert str(exception_info.value) == '409: Policy Error'
def test_delete_policies(db):
@@ -109,7 +67,7 @@ def test_delete_policies(db):
"genre": "authz",
"description": "test",
}
- policies = add_policies(value=value)
+ policies = policy_helper.add_policies(value=value)
policy_id1 = list(policies.keys())[0]
value = {
"name": "test_policy2",
@@ -117,23 +75,23 @@ def test_delete_policies(db):
"genre": "authz",
"description": "test",
}
- policies = add_policies(value=value)
+ policies = policy_helper.add_policies(value=value)
policy_id2 = list(policies.keys())[0]
assert policy_id1 != policy_id2
- delete_policies(policy_id1)
- policies = get_policies()
+ policy_helper.delete_policies(policy_id1)
+ policies = policy_helper.get_policies()
assert policy_id1 not in policies
def test_delete_policies_with_invalid_id(db):
policy_id = 'policy_id_1'
- with pytest.raises(Exception) as exception_info:
- delete_policies(policy_id)
- assert str(exception_info.value) == '400: Policy Unknown'
+ with pytest.raises(PolicyUnknown) as exception_info:
+ policy_helper.delete_policies(policy_id)
+ # assert str(exception_info.value) == '400: Policy Unknown'
def test_update_policy(db):
- policies = add_policies()
+ policies = policy_helper.add_policies()
policy_id = list(policies.keys())[0]
value = {
"name": "test_policy4",
@@ -141,7 +99,7 @@ def test_update_policy(db):
"genre": "authz",
"description": "test-3",
}
- updated_policy = update_policy(policy_id, value)
+ updated_policy = policy_helper.update_policy(policy_id, value)
assert updated_policy
for key in ("genre", "name", "model_id", "description"):
assert key in updated_policy[policy_id]
@@ -156,33 +114,27 @@ def test_update_policy_with_invalid_id(db):
"genre": "authz",
"description": "test-3",
}
- with pytest.raises(Exception) as exception_info:
- update_policy(policy_id, value)
- assert str(exception_info.value) == '400: Policy Unknown'
+ with pytest.raises(PolicyUnknown) as exception_info:
+ policy_helper.update_policy(policy_id, value)
+ # assert str(exception_info.value) == '400: Policy Unknown'
def test_get_policy_from_meta_rules(db):
- import models.test_models as test_models
- import models.test_meta_rules as test_meta_rules
- import test_pdp as test_pdp
- meta_rule = test_meta_rules.add_meta_rule(value=mock_data.create_meta_rule())
- meta_rule_id = list(meta_rule.keys())[0]
- model = test_models.add_model(value=mock_data.create_model(meta_rule_id))
- model_id = list(model.keys())[0]
- value = mock_data.create_policy(model_id)
- policy = add_policies(value=value)
- assert policy
- policy_id = list(policy.keys())[0]
- pdp_ids = [policy_id,]
- pdp_obj = mock_data.create_pdp(pdp_ids)
- test_pdp.add_pdp(value=pdp_obj)
- matched_policy_id = get_policy_from_meta_rules(meta_rule_id)
+ subject_category_id, object_category_id, action_category_id, meta_rule_id, policy_id = mock_data.create_new_policy(
+ subject_category_name="subject_category1",
+ object_category_name="object_category1",
+ action_category_name="action_category1",
+ meta_rule_name="meta_rule_1",
+ model_name="model1")
+ security_pipeline = [policy_id]
+ pdp_obj = mock_data.create_pdp(security_pipeline)
+ pdp_helper.add_pdp(value=pdp_obj)
+ matched_policy_id = policy_helper.get_policy_from_meta_rules(meta_rule_id)
assert matched_policy_id
assert policy_id == matched_policy_id
def test_get_policy_from_meta_rules_with_no_policy_ids(db):
- import test_pdp as test_pdp
meta_rule_id = 'meta_rule_id'
value = {
"name": "test_pdp",
@@ -190,58 +142,31 @@ def test_get_policy_from_meta_rules_with_no_policy_ids(db):
"keystone_project_id": "keystone_project_id1",
"description": "...",
}
- test_pdp.add_pdp(value=value)
- matched_policy_id = get_policy_from_meta_rules(meta_rule_id)
+ pdp_helper.add_pdp(value=value)
+ matched_policy_id = policy_helper.get_policy_from_meta_rules(meta_rule_id)
assert not matched_policy_id
-def test_get_policy_from_meta_rules_with_no_policies(db):
- import test_pdp as test_pdp
- meta_rule_id = 'meta_rule_id'
- policy_id = 'invalid'
- pdp_ids = [policy_id,]
- pdp_obj = mock_data.create_pdp(pdp_ids)
- test_pdp.add_pdp(value=pdp_obj)
- with pytest.raises(Exception) as exception_info:
- get_policy_from_meta_rules(meta_rule_id)
- assert str(exception_info.value) == '400: Policy Unknown'
-
-
-def test_get_policy_from_meta_rules_with_no_models(db):
- import models.test_meta_rules as test_meta_rules
- import test_pdp as test_pdp
- meta_rule = test_meta_rules.add_meta_rule(value=mock_data.create_meta_rule())
- meta_rule_id = list(meta_rule.keys())[0]
- model_id = 'invalid'
- value = mock_data.create_policy(model_id)
- policy = add_policies(value=value)
- assert policy
- policy_id = list(policy.keys())[0]
- pdp_ids = [policy_id,]
- pdp_obj = mock_data.create_pdp(pdp_ids)
- test_pdp.add_pdp(value=pdp_obj)
- with pytest.raises(Exception) as exception_info:
- get_policy_from_meta_rules(meta_rule_id)
- assert str(exception_info.value) == '400: Model Unknown'
-
-
def test_get_rules(db):
+ subject_category_id, object_category_id, action_category_id, meta_rule_id, policy_id = mock_data.create_new_policy(
+ subject_category_name="subject_category12",
+ object_category_name="object_category12",
+ action_category_name="action_category12",
+ meta_rule_name="meta_rule_12",
+ model_name="model12")
value = {
"rule": ("low", "medium", "vm-action"),
"instructions": ({"decision": "grant"}),
"enabled": "",
}
- policy_id = mock_data.get_policy_id()
- meta_rule_id = "1"
- add_rule(policy_id, meta_rule_id, value)
+ policy_helper.add_rule(policy_id=policy_id, meta_rule_id=meta_rule_id, value=value)
value = {
"rule": ("low", "low", "vm-action"),
"instructions": ({"decision": "grant"}),
"enabled": "",
}
- meta_rule_id = "1"
- add_rule(policy_id, meta_rule_id, value)
- rules = get_rules(policy_id, meta_rule_id)
+ policy_helper.add_rule(policy_id=policy_id, meta_rule_id=meta_rule_id, value=value)
+ rules = policy_helper.get_rules(policy_id=policy_id, meta_rule_id=meta_rule_id)
assert isinstance(rules, dict)
assert rules
obj = rules.get('rules')
@@ -249,20 +174,25 @@ def test_get_rules(db):
def test_get_rules_with_invalid_policy_id_failure(db):
- rules = get_rules("invalid_policy_id", "meta_rule_id")
+ rules = policy_helper.get_rules("invalid_policy_id", "meta_rule_id")
assert not rules.get('meta_rule-id')
assert len(rules.get('rules')) == 0
def test_add_rule(db):
+ subject_category_id, object_category_id, action_category_id, meta_rule_id, policy_id = mock_data.create_new_policy(
+ subject_category_name="subject_category1",
+ object_category_name="object_category1",
+ action_category_name="action_category1",
+ meta_rule_name="meta_rule_1",
+ model_name="model1")
value = {
"rule": ("high", "medium", "vm-action"),
"instructions": ({"decision": "grant"}),
"enabled": "",
}
- policy_id = mock_data.get_policy_id()
- meta_rule_id = "1"
- rules = add_rule(policy_id, meta_rule_id, value)
+
+ rules = policy_helper.add_rule(policy_id=policy_id, meta_rule_id=meta_rule_id, value=value)
assert rules
assert len(rules) == 1
assert isinstance(rules, dict)
@@ -271,17 +201,45 @@ def test_add_rule(db):
assert key in rules[rule_id]
assert rules[rule_id][key] == value[key]
+ with pytest.raises(RuleExisting):
+ policy_helper.add_rule(policy_id=policy_id, meta_rule_id=meta_rule_id, value=value)
+
def test_delete_rule(db):
+ subject_category_id, object_category_id, action_category_id, meta_rule_id, policy_id = mock_data.create_new_policy(
+ subject_category_name="subject_category14",
+ object_category_name="object_category14",
+ action_category_name="action_category14",
+ meta_rule_name="meta_rule_14",
+ model_name="model14")
value = {
"rule": ("low", "low", "vm-action"),
"instructions": ({"decision": "grant"}),
"enabled": "",
}
- policy_id = mock_data.get_policy_id()
- meta_rule_id = "2"
- rules = add_rule(policy_id, meta_rule_id, value)
+ rules = policy_helper.add_rule(policy_id, meta_rule_id, value)
rule_id = list(rules.keys())[0]
- delete_rule(policy_id, rule_id)
- rules = get_rules(policy_id, meta_rule_id)
+ policy_helper.delete_rule(policy_id, rule_id)
+ rules = policy_helper.get_rules(policy_id, meta_rule_id)
assert not rules.get('rules')
+
+
+def test_delete_policies_with_pdp(db):
+ value = {
+ "name": "test_policy1",
+ "model_id": "",
+ "genre": "authz",
+ "description": "test",
+ }
+ policies = policy_helper.add_policies(value=value)
+ policy_id1 = list(policies.keys())[0]
+ pdp_id = "pdp_id1"
+ value = {
+ "name": "test_pdp",
+ "security_pipeline": [policy_id1],
+ "keystone_project_id": "keystone_project_id1",
+ "description": "...",
+ }
+ pdp_helper.add_pdp(pdp_id=pdp_id, value=value)
+ with pytest.raises(DeletePolicyWithPdp) as exception_info:
+ policy_helper.delete_policies(policy_id1)
diff --git a/python_moondb/tests/unit_python/requirements.txt b/python_moondb/tests/unit_python/requirements.txt
index 5f507ff7..ff727723 100644
--- a/python_moondb/tests/unit_python/requirements.txt
+++ b/python_moondb/tests/unit_python/requirements.txt
@@ -1,5 +1,4 @@
sqlalchemy
pymysql
-pytest
requests_mock
python_moonutilities \ No newline at end of file
diff --git a/python_moondb/tests/unit_python/test_pdp.py b/python_moondb/tests/unit_python/test_pdp.py
index 5134c0fb..4d245e4d 100755
--- a/python_moondb/tests/unit_python/test_pdp.py
+++ b/python_moondb/tests/unit_python/test_pdp.py
@@ -1,112 +1,149 @@
import pytest
-
-
-def update_pdp(pdp_id, value):
- from python_moondb.core import PDPManager
- return PDPManager.update_pdp("", pdp_id, value)
-
-
-def delete_pdp(pdp_id):
- from python_moondb.core import PDPManager
- PDPManager.delete_pdp("", pdp_id)
-
-
-def add_pdp(pdp_id=None, value=None):
- from python_moondb.core import PDPManager
- return PDPManager.add_pdp("", pdp_id, value)
-
-
-def get_pdp(pdp_id=None):
- from python_moondb.core import PDPManager
- return PDPManager.get_pdp("", pdp_id)
+import helpers.mock_data as mock_data
+import helpers.pdp_helper as pdp_helper
def test_update_pdp(db):
pdp_id = "pdp_id1"
+ subject_category_id, object_category_id, action_category_id, meta_rule_id, policy_id = mock_data.create_new_policy(
+ subject_category_name="subject_category1",
+ object_category_name="object_category1",
+ action_category_name="action_category1",
+ meta_rule_name="meta_rule_1",
+ model_name="model1")
value = {
"name": "test_pdp",
- "security_pipeline": ["policy_id_1", "policy_id_2"],
+ "security_pipeline": [policy_id],
"keystone_project_id": "keystone_project_id1",
"description": "...",
}
- add_pdp(pdp_id, value)
- pdp = update_pdp(pdp_id, value)
+ pdp_helper.add_pdp(pdp_id, value)
+ pdp = pdp_helper.update_pdp(pdp_id, value)
assert pdp
def test_update_pdp_with_invalid_id(db):
pdp_id = "pdp_id1"
+ subject_category_id, object_category_id, action_category_id, meta_rule_id, policy_id = mock_data.create_new_policy(
+ subject_category_name="subject_category1",
+ object_category_name="object_category1",
+ action_category_name="action_category1",
+ meta_rule_name="meta_rule_1",
+ model_name="model1")
value = {
"name": "test_pdp",
- "security_pipeline": ["policy_id_1", "policy_id_2"],
+ "security_pipeline": [policy_id],
"keystone_project_id": "keystone_project_id1",
"description": "...",
}
with pytest.raises(Exception) as exception_info:
- update_pdp(pdp_id, value)
+ pdp_helper.update_pdp(pdp_id, value)
assert str(exception_info.value) == '400: Pdp Unknown'
def test_delete_pdp(db):
pdp_id = "pdp_id1"
+ subject_category_id, object_category_id, action_category_id, meta_rule_id, policy_id = mock_data.create_new_policy(
+ subject_category_name="subject_category1",
+ object_category_name="object_category1",
+ action_category_name="action_category1",
+ meta_rule_name="meta_rule_1",
+ model_name="model1")
value = {
"name": "test_pdp",
- "security_pipeline": ["policy_id_1", "policy_id_2"],
+ "security_pipeline": [policy_id],
"keystone_project_id": "keystone_project_id1",
"description": "...",
}
- add_pdp(pdp_id, value)
- delete_pdp(pdp_id)
- assert len(get_pdp(pdp_id)) == 0
+ pdp_helper.add_pdp(pdp_id, value)
+ pdp_helper.delete_pdp(pdp_id)
+ assert len(pdp_helper.get_pdp(pdp_id)) == 0
def test_delete_pdp_with_invalid_id(db):
pdp_id = "pdp_id1"
with pytest.raises(Exception) as exception_info:
- delete_pdp(pdp_id)
+ pdp_helper.delete_pdp(pdp_id)
assert str(exception_info.value) == '400: Pdp Unknown'
def test_add_pdp(db):
pdp_id = "pdp_id1"
+ subject_category_id, object_category_id, action_category_id, meta_rule_id, policy_id = mock_data.create_new_policy(
+ subject_category_name="subject_category1",
+ object_category_name="object_category1",
+ action_category_name="action_category1",
+ meta_rule_name="meta_rule_1",
+ model_name="model1")
value = {
"name": "test_pdp",
- "security_pipeline": ["policy_id_1", "policy_id_2"],
+ "security_pipeline": [policy_id],
"keystone_project_id": "keystone_project_id1",
"description": "...",
}
- pdp = add_pdp(pdp_id, value)
+ pdp = pdp_helper.add_pdp(pdp_id, value)
assert pdp
def test_add_pdp_twice_with_same_id(db):
pdp_id = "pdp_id1"
+ subject_category_id, object_category_id, action_category_id, meta_rule_id, policy_id = mock_data.create_new_policy(
+ subject_category_name="subject_category1",
+ object_category_name="object_category1",
+ action_category_name="action_category1",
+ meta_rule_name="meta_rule_1",
+ model_name="model1")
+ value = {
+ "name": "test_pdp",
+ "security_pipeline": [policy_id],
+ "keystone_project_id": "keystone_project_id1",
+ "description": "...",
+ }
+ pdp_helper.add_pdp(pdp_id, value)
+ with pytest.raises(Exception) as exception_info:
+ pdp_helper.add_pdp(pdp_id, value)
+ assert str(exception_info.value) == '409: Pdp Error'
+
+
+def test_add_pdp_twice_with_same_name(db):
+ subject_category_id, object_category_id, action_category_id, meta_rule_id, policy_id = mock_data.create_new_policy(
+ subject_category_name="subject_category1",
+ object_category_name="object_category1",
+ action_category_name="action_category1",
+ meta_rule_name="meta_rule_1",
+ model_name="model1")
value = {
"name": "test_pdp",
- "security_pipeline": ["policy_id_1", "policy_id_2"],
+ "security_pipeline": [policy_id],
"keystone_project_id": "keystone_project_id1",
"description": "...",
}
- add_pdp(pdp_id, value)
+ pdp_helper.add_pdp(value=value)
with pytest.raises(Exception) as exception_info:
- add_pdp(pdp_id, value)
+ pdp_helper.add_pdp(value=value)
assert str(exception_info.value) == '409: Pdp Error'
def test_get_pdp(db):
pdp_id = "pdp_id1"
+ subject_category_id, object_category_id, action_category_id, meta_rule_id, policy_id = mock_data.create_new_policy(
+ subject_category_name="subject_category1",
+ object_category_name="object_category1",
+ action_category_name="action_category1",
+ meta_rule_name="meta_rule_1",
+ model_name="model1")
value = {
"name": "test_pdp",
- "security_pipeline": ["policy_id_1", "policy_id_2"],
+ "security_pipeline": [policy_id],
"keystone_project_id": "keystone_project_id1",
"description": "...",
}
- add_pdp(pdp_id, value)
- pdp = get_pdp(pdp_id)
+ pdp_helper.add_pdp(pdp_id, value)
+ pdp = pdp_helper.get_pdp(pdp_id)
assert len(pdp) == 1
def test_get_pdp_with_invalid_id(db):
pdp_id = "invalid"
- pdp = get_pdp(pdp_id)
+ pdp = pdp_helper.get_pdp(pdp_id)
assert len(pdp) == 0
diff --git a/python_moonutilities/Changelog b/python_moonutilities/Changelog
index ffc03809..ae7f352f 100644
--- a/python_moonutilities/Changelog
+++ b/python_moonutilities/Changelog
@@ -82,3 +82,19 @@ CHANGES
1.4.6
-----
- Add WrapperConflict, PipelineConflict, SlaveNameUnknown exceptions
+
+1.4.7
+-----
+- Delete the auth.py file to remove some code duplication
+
+1.4.8
+-----
+- Add SubjectScopeExisting, ObjectScopeExisting, ActionScopeExisting exceptions
+
+1.4.9
+-----
+- Add some exceptions when deletion of elements is impossible
+
+1.4.10
+-----
+- Add CategoryNameInvalid and PerimeterNameInvalid exceptions
diff --git a/python_moonutilities/Jenkinsfile b/python_moonutilities/Jenkinsfile
new file mode 100644
index 00000000..95939e9b
--- /dev/null
+++ b/python_moonutilities/Jenkinsfile
@@ -0,0 +1,10 @@
+pipeline {
+ agent { docker { image 'python:3.5.1' } }
+ stages {
+ stage('build') {
+ steps {
+ sh 'python --version'
+ }
+ }
+ }
+} \ No newline at end of file
diff --git a/python_moonutilities/python_moonutilities/__init__.py b/python_moonutilities/python_moonutilities/__init__.py
index 741ba4f6..6b30dedc 100644
--- a/python_moonutilities/python_moonutilities/__init__.py
+++ b/python_moonutilities/python_moonutilities/__init__.py
@@ -3,6 +3,6 @@
# license which can be found in the file 'LICENSE' in this package distribution
# or at 'http://www.apache.org/licenses/LICENSE-2.0'.
-__version__ = "1.4.6"
+__version__ = "1.4.10"
diff --git a/python_moonutilities/python_moonutilities/auth.py b/python_moonutilities/python_moonutilities/auth.py
deleted file mode 100644
index 5f921d0b..00000000
--- a/python_moonutilities/python_moonutilities/auth.py
+++ /dev/null
@@ -1,76 +0,0 @@
-# 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 os
-import requests
-import time
-from functools import wraps
-from flask import request
-from oslo_log import log as logging
-from python_moonutilities import exceptions, configuration
-
-
-logger = logging.getLogger(__name__)
-KEYSTONE_CONFIG = configuration.get_configuration("openstack/keystone")["openstack/keystone"]
-TOKENS = {}
-
-
-def check_token(token, url=None):
- _verify = False
- if KEYSTONE_CONFIG['certificate']:
- _verify = KEYSTONE_CONFIG['certificate']
- try:
- os.environ.pop("http_proxy")
- os.environ.pop("https_proxy")
- except KeyError:
- pass
- if not url:
- url = KEYSTONE_CONFIG['url']
- headers = {
- "Content-Type": "application/json",
- 'X-Subject-Token': token,
- 'X-Auth-Token': token,
- }
- if KEYSTONE_CONFIG['check_token'].lower() in ("false", "no", "n"):
- # TODO (asteroide): must send the admin id
- return "admin" if not token else token
- if KEYSTONE_CONFIG['check_token'].lower() in ("yes", "y", "true"):
- if token in TOKENS:
- delta = time.mktime(TOKENS[token]["expires_at"]) - time.mktime(time.gmtime())
- if delta > 0:
- return TOKENS[token]["user"]
- raise exceptions.KeystoneError
- else:
- req = requests.get("{}/auth/tokens".format(url), headers=headers, verify=_verify)
- if req.status_code in (200, 201):
- # Note (asteroide): the time stamps is not in ISO 8601, so it is necessary to delete
- # characters after the dot
- token_time = req.json().get("token").get("expires_at").split(".")
- TOKENS[token] = dict()
- TOKENS[token]["expires_at"] = time.strptime(token_time[0], "%Y-%m-%dT%H:%M:%S")
- TOKENS[token]["user"] = req.json().get("token").get("user").get("id")
- return TOKENS[token]["user"]
- logger.error("{} - {}".format(req.status_code, req.text))
- raise exceptions.KeystoneError
- elif KEYSTONE_CONFIG['check_token'].lower() == "strict":
- req = requests.head("{}/auth/tokens".format(url), headers=headers, verify=_verify)
- if req.status_code in (200, 201):
- return token
- logger.error("{} - {}".format(req.status_code, req.text))
- raise exceptions.KeystoneError
- raise exceptions.KeystoneError
-
-
-def check_auth(function):
- @wraps(function)
- def wrapper(*args, **kwargs):
- token = request.headers.get('X-Auth-Token')
- token = check_token(token)
- if not token:
- raise exceptions.AuthException
- user_id = kwargs.pop("user_id", token)
- result = function(*args, **kwargs, user_id=user_id)
- return result
- return wrapper
diff --git a/python_moonutilities/python_moonutilities/cache.py b/python_moonutilities/python_moonutilities/cache.py
index 1ea59d3a..1bb9d09e 100644
--- a/python_moonutilities/python_moonutilities/cache.py
+++ b/python_moonutilities/python_moonutilities/cache.py
@@ -101,14 +101,14 @@ class Cache(object):
raise exceptions.PolicyUnknown("Cannot find policy within policy_id {}".format(policy_id))
if policy_id in self.subjects:
- for _subject_id, _subject_dict in self.__SUBJECTS[policy_id].items():
+ for _subject_id, _subject_dict in self.subjects[policy_id].items():
if "name" in _subject_dict and _subject_dict["name"] == name:
return _subject_id
self.__update_subjects(policy_id)
if policy_id in self.subjects:
- for _subject_id, _subject_dict in self.__SUBJECTS[policy_id].items():
+ for _subject_id, _subject_dict in self.subjects[policy_id].items():
if "name" in _subject_dict and _subject_dict["name"] == name:
return _subject_id
@@ -488,6 +488,20 @@ class Cache(object):
logger.warning("Cannot find 'security_pipeline' "
"key within pdp ")
+ def get_meta_rule_ids_from_pdp_value(self, pdp_value):
+ meta_rules = []
+ if "security_pipeline" in pdp_value:
+ for policy_id in pdp_value["security_pipeline"]:
+ if policy_id not in self.policies or "model_id" not in self.policies[policy_id]:
+ raise exceptions.PolicyUnknown("Cannot find 'models' key")
+ model_id = self.policies[policy_id]["model_id"]
+ if model_id not in self.models or 'meta_rules' not in self.models[model_id]:
+ raise exceptions.ModelNotFound("Cannot find 'models' key")
+ for meta_rule in self.models[model_id]["meta_rules"]:
+ meta_rules.append(meta_rule)
+ return meta_rules
+ raise exceptions.PdpContentError
+
def get_pdp_from_keystone_project(self, keystone_project_id):
for pdp_key, pdp_value in self.pdp.items():
if "keystone_project_id" in pdp_value and \
@@ -566,8 +580,8 @@ class Cache(object):
:return:
"""
if all(k in container_data for k in ("keystone_project_id", "name", "container_id", "policy_id",
- "meta_rule_id", "port")) \
- and all(k in container_data['port'] for k in ("PublicPort", "Type", "IP", "PrivatePort")):
+ "meta_rule_id", "port")) \
+ and all(k in container_data['port'] for k in ("PublicPort", "Type", "IP", "PrivatePort")):
self.__CONTAINERS[uuid4().hex] = {
"keystone_project_id": container_data['keystone_project_id'],
@@ -641,7 +655,7 @@ class Cache(object):
container_ids = []
for pdp_id, pdp_value, in self.__PDP.items():
if pdp_value:
- if all(k in pdp_value for k in ("keystone_project_id", "security_pipeline")) \
+ if all(k in pdp_value for k in ("keystone_project_id", "security_pipeline")) \
and pdp_value["keystone_project_id"] == keystone_project_id:
for policy_id in pdp_value["security_pipeline"]:
if policy_id in self.policies and "model_id" in self.policies[policy_id]:
@@ -677,4 +691,3 @@ class Cache(object):
"and may not contains 'model_id' key".format(policy_id))
self.__CONTAINER_CHAINING[keystone_project_id] = container_ids
-
diff --git a/python_moonutilities/python_moonutilities/context.py b/python_moonutilities/python_moonutilities/context.py
index 626b25dc..1d25cda2 100644
--- a/python_moonutilities/python_moonutilities/context.py
+++ b/python_moonutilities/python_moonutilities/context.py
@@ -14,39 +14,35 @@ logger = logging.getLogger("moon.utilities." + __name__)
class Context:
def __init__(self, init_context, cache):
+ if init_context is None:
+ raise Exception("Invalid context content object")
+
self.cache = cache
self.__keystone_project_id = init_context.get("project_id")
- self.__pdp_id = None
- self.__pdp_value = None
- for _pdp_key, _pdp_value in self.cache.pdp.items():
- if _pdp_value["keystone_project_id"] == self.__keystone_project_id:
- self.__pdp_id = _pdp_key
- self.__pdp_value = copy.deepcopy(_pdp_value)
- break
- if not self.__pdp_value:
+ self.__pdp_id = self.cache.get_pdp_from_keystone_project(self.__keystone_project_id)
+
+ if not self.__pdp_id:
raise exceptions.AuthzException(
"Cannot create context for authz "
"with Keystone project ID {}".format(
self.__keystone_project_id
- ))
+ ))
+ self.__pdp_value = copy.deepcopy(self.cache.pdp[self.__pdp_id])
+
self.__subject = init_context.get("subject_name")
self.__object = init_context.get("object_name")
self.__action = init_context.get("action_name")
- self.__current_request = None
self.__request_id = init_context.get("req_id")
self.__cookie = init_context.get("cookie")
self.__manager_url = init_context.get("manager_url")
self.__interface_name = init_context.get("interface_name")
+ self.__current_request = None
+
self.__index = -1
# self.__init_initial_request()
- self.__headers = []
- policies = self.cache.policies
- models = self.cache.models
- for policy_id in self.__pdp_value["security_pipeline"]:
- model_id = policies[policy_id]["model_id"]
- for meta_rule in models[model_id]["meta_rules"]:
- self.__headers.append(meta_rule)
+ self.__meta_rule_ids = self.cache.get_meta_rule_ids_from_pdp_value(self.__pdp_value)
self.__meta_rules = self.cache.meta_rules
+
self.__pdp_set = {}
# self.__init_pdp_set()
@@ -63,20 +59,25 @@ class Context:
@property
def current_state(self):
- return self.__pdp_set[self.__headers[self.__index]]['effect']
+ self.__validate_meta_rule_content(self.__meta_rule_ids[self.__index])
+ return self.__pdp_set[self.__meta_rule_ids[self.__index]]['effect']
@current_state.setter
def current_state(self, state):
if state not in ("grant", "deny", "passed"):
state = "passed"
- self.__pdp_set[self.__headers[self.__index]]['effect'] = state
+ self.__validate_meta_rule_content(self.__meta_rule_ids[self.__index])
+ self.__pdp_set[self.__meta_rule_ids[self.__index]]['effect'] = state
@current_state.deleter
def current_state(self):
- self.__pdp_set[self.__headers[self.__index]]['effect'] = "unset"
+ self.__validate_meta_rule_content(self.__meta_rule_ids[self.__index])
+ self.__pdp_set[self.__meta_rule_ids[self.__index]]['effect'] = "unset"
@property
def current_policy_id(self):
+ if "security_pipeline" not in self.__pdp_value:
+ raise exceptions.AuthzException('Cannot find security_pipeline key within pdp.')
return self.__pdp_value["security_pipeline"][self.__index]
@current_policy_id.setter
@@ -88,6 +89,8 @@ class Context:
pass
def __init_current_request(self):
+ if "security_pipeline" not in self.__pdp_value:
+ raise exceptions.PdpContentError
self.__subject = self.cache.get_subject(
self.__pdp_value["security_pipeline"][self.__index],
self.__subject)
@@ -100,11 +103,11 @@ class Context:
self.__current_request = dict(self.initial_request)
def __init_pdp_set(self):
- for header in self.__headers:
- self.__pdp_set[header] = dict()
- self.__pdp_set[header]["meta_rules"] = self.__meta_rules[header]
- self.__pdp_set[header]["target"] = self.__add_target(header)
- self.__pdp_set[header]["effect"] = "unset"
+ for meta_rule_id in self.__meta_rule_ids:
+ self.__pdp_set[meta_rule_id] = dict()
+ self.__pdp_set[meta_rule_id]["meta_rules"] = self.__meta_rules[meta_rule_id]
+ self.__pdp_set[meta_rule_id]["target"] = self.__add_target(meta_rule_id)
+ self.__pdp_set[meta_rule_id]["effect"] = "unset"
self.__pdp_set["effect"] = "deny"
# def update_target(self, context):
@@ -151,23 +154,37 @@ class Context:
_subject = self.__current_request["subject"]
_object = self.__current_request["object"]
_action = self.__current_request["action"]
+
meta_rules = self.cache.meta_rules
policy_id = self.cache.get_policy_from_meta_rules(meta_rule_id)
+
+ if 'subject_categories' not in meta_rules[meta_rule_id]:
+ raise exceptions.MetaRuleContentError(" 'subject_categories' key not found ")
+
for sub_cat in meta_rules[meta_rule_id]['subject_categories']:
if sub_cat not in result:
result[sub_cat] = []
result[sub_cat].extend(
self.cache.get_subject_assignments(policy_id, _subject, sub_cat))
+
+ if 'object_categories' not in meta_rules[meta_rule_id]:
+ raise exceptions.MetaRuleContentError(" 'object_categories' key not found ")
+
for obj_cat in meta_rules[meta_rule_id]['object_categories']:
if obj_cat not in result:
result[obj_cat] = []
result[obj_cat].extend(
self.cache.get_object_assignments(policy_id, _object, obj_cat))
+
+ if 'action_categories' not in meta_rules[meta_rule_id]:
+ raise exceptions.MetaRuleContentError(" 'action_categories' key not found ")
+
for act_cat in meta_rules[meta_rule_id]['action_categories']:
if act_cat not in result:
result[act_cat] = []
result[act_cat].extend(
self.cache.get_action_assignments(policy_id, _action, act_cat))
+
return result
def __repr__(self):
@@ -181,7 +198,7 @@ pdp_set: {pdp_set}
id=self.__pdp_id,
current_request=self.__current_request,
request_id=self.__request_id,
- headers=self.__headers,
+ headers=self.__meta_rule_ids,
pdp_set=self.__pdp_set,
index=self.__index
)
@@ -190,7 +207,7 @@ pdp_set: {pdp_set}
return {
"initial_request": copy.deepcopy(self.initial_request),
"current_request": copy.deepcopy(self.__current_request),
- "headers": copy.deepcopy(self.__headers),
+ "headers": copy.deepcopy(self.__meta_rule_ids),
"index": copy.deepcopy(self.__index),
"pdp_set": copy.deepcopy(self.__pdp_set),
"request_id": copy.deepcopy(self.__request_id),
@@ -265,11 +282,12 @@ pdp_set: {pdp_set}
@property
def current_request(self):
if not self.__current_request:
- self.__current_request = copy.deepcopy(self.initial_request)
+ self.__current_request = dict(self.initial_request)
return self.__current_request
@current_request.setter
def current_request(self, value):
+
self.__current_request = copy.deepcopy(value)
# Note (asteroide): if the current request is modified,
# we must update the PDP Set.
@@ -280,17 +298,22 @@ pdp_set: {pdp_set}
self.__current_request = {}
self.__pdp_set = {}
+ '''
+ [Note ] Refactor name of headers to meta_rule_ids done ,
+ may need to refactor getter and setter of headers
+ '''
+
@property
def headers(self):
- return self.__headers
+ return self.__meta_rule_ids
@headers.setter
- def headers(self, headers):
- self.__headers = headers
+ def headers(self, meta_rule_ids):
+ self.__meta_rule_ids = meta_rule_ids
@headers.deleter
def headers(self):
- self.__headers = list()
+ self.__meta_rule_ids = list()
@property
def index(self):
@@ -316,4 +339,6 @@ pdp_set: {pdp_set}
def pdp_set(self):
self.__pdp_set = {}
-
+ def __validate_meta_rule_content(self, meta_rules):
+ if 'effect' not in meta_rules:
+ raise exceptions.PdpContentError
diff --git a/python_moonutilities/python_moonutilities/exceptions.py b/python_moonutilities/python_moonutilities/exceptions.py
index 1298f9e4..a43ac89f 100644
--- a/python_moonutilities/python_moonutilities/exceptions.py
+++ b/python_moonutilities/python_moonutilities/exceptions.py
@@ -197,6 +197,11 @@ class AdminRule(AdminException):
code = 400
title = 'Rule Exception'
+class CategoryNameInvalid(AdminMetaData):
+ description = _("The given category name is invalid.")
+ code = 409
+ title = 'Category Name Invalid'
+ logger = "ERROR"
class SubjectCategoryNameExisting(AdminMetaData):
description = _("The given subject category name already exists.")
@@ -261,6 +266,12 @@ class ActionCategoryUnknown(AdminMetaData):
logger = "ERROR"
+class PerimeterNameInvalid(AdminPerimeter):
+ description = _("The given name is not valid.")
+ code = 400
+ title = 'Perimeter Name is Invalid'
+ logger = "ERROR"
+
class SubjectUnknown(AdminPerimeter):
description = _("The given subject is unknown.")
code = 400
@@ -282,6 +293,26 @@ class ActionUnknown(AdminPerimeter):
logger = "ERROR"
+class SubjectExisting(AdminPerimeter):
+ description = _("The given subject is existing.")
+ code = 409
+ title = 'Subject Existing'
+ logger = "ERROR"
+
+
+class ObjectExisting(AdminPerimeter):
+ description = _("The given object is existing.")
+ code = 409
+ title = 'Object Existing'
+ logger = "ERROR"
+
+
+class ActionExisting(AdminPerimeter):
+ description = _("The given action is existing.")
+ code = 409
+ title = 'Action Existing'
+ logger = "ERROR"
+
class SubjectNameExisting(AdminPerimeter):
description = _("The given subject name is existing.")
code = 400
@@ -338,6 +369,27 @@ class ActionScopeUnknown(AdminScope):
logger = "ERROR"
+class SubjectScopeExisting(AdminScope):
+ description = _("The given subject scope is existing.")
+ code = 409
+ title = 'Subject Scope Existing'
+ logger = "ERROR"
+
+
+class ObjectScopeExisting(AdminScope):
+ description = _("The given object scope is existing.")
+ code = 409
+ title = 'Object Scope Existing'
+ logger = "ERROR"
+
+
+class ActionScopeExisting(AdminScope):
+ description = _("The given action scope is existing.")
+ code = 409
+ title = 'Action Scope Existing'
+ logger = "ERROR"
+
+
class SubjectScopeNameExisting(AdminScope):
description = _("The given subject scope name is existing.")
code = 400
@@ -444,7 +496,7 @@ class MetaRuleExisting(AdminMetaRule):
class MetaRuleContentError(AdminMetaRule):
- description = _("Invalid content of pdp.")
+ description = _("Invalid content of meta rule.")
code = 400
title = 'Meta Rule Error'
logger = "ERROR"
@@ -610,3 +662,45 @@ class PolicyExisting(MoonError):
code = 409
title = 'Policy Error'
logger = "Error"
+
+
+class DeleteData(MoonError):
+ description = _("Cannot delete data with assignment")
+ code = 400
+ title = 'Data Error'
+ logger = "Error"
+
+
+class DeleteCategoryWithData(MoonError):
+ description = _("Cannot delete category with data")
+ code = 400
+ title = 'Category Error'
+ logger = "Error"
+
+
+class DeleteCategoryWithMetaRule(MoonError):
+ description = _("Cannot delete category with meta rule")
+ code = 400
+ title = 'Category Error'
+ logger = "Error"
+
+
+class DeleteModelWithPolicy(MoonError):
+ description = _("Cannot delete model with policy")
+ code = 400
+ title = 'Model Error'
+ logger = "Error"
+
+
+class DeletePolicyWithPdp(MoonError):
+ description = _("Cannot delete policy with pdp")
+ code = 400
+ title = 'Policy Error'
+ logger = "Error"
+
+
+class DeleteMetaRuleWithModel(MoonError):
+ description = _("Cannot delete meta rule with model")
+ code = 400
+ title = 'Meta rule Error'
+ logger = "Error"
diff --git a/python_moonutilities/python_moonutilities/security_functions.py b/python_moonutilities/python_moonutilities/security_functions.py
index 15cbc8be..5d5275ee 100644
--- a/python_moonutilities/python_moonutilities/security_functions.py
+++ b/python_moonutilities/python_moonutilities/security_functions.py
@@ -22,7 +22,6 @@ __targets = {}
def filter_input(func_or_str):
-
def __filter(string):
if string and type(string) is str:
return "".join(re.findall("[\w\- +]*", string))
@@ -82,15 +81,124 @@ def filter_input(func_or_str):
return None
+"""
+To do should check value of Dictionary but it's dependent on from where it's coming
+"""
+
+
+def validate_data(data):
+ def __validate_string(string):
+ if not string:
+ raise ValueError('Empty String')
+ '''
+ is it valid to contains space inbetween
+
+ '''
+
+ if " " in string:
+ raise ValueError('String contains space')
+
+ def __validate_list_or_tuple(container):
+ if not container:
+ raise ValueError('Empty Container')
+ for i in container:
+ validate_data(i)
+
+ def __validate_dict(dictionary):
+ if not dictionary:
+ raise ValueError('Empty Dictionary')
+ for key in dictionary:
+ validate_data(dictionary[key])
+
+ if isinstance(data, str):
+ __validate_string(data)
+ elif isinstance(data, list) or isinstance(data, tuple):
+ __validate_list_or_tuple(data)
+ elif isinstance(data, dict):
+ __validate_dict(data)
+ else:
+ raise ValueError('Value is Not String or Container or Dictionary')
+
+
+def validate_input(type='get', args_state=[], kwargs_state=[], body_state=[]):
+ """
+ this fucntion works only on List or tuple or dictionary of Strings ,and String direct
+ Check if input of function is Valid or not, Valid if not has spaces and values is not None or empty.
+
+ :param type: type of request if function is used as decorator
+ :param args_state: list of Booleans for args,
+ values must be order as target values of arguments,
+ True if None is not Allowed and False if is allowed
+ :param kwargs_state: list of Booleans for kwargs as order of input kwargs,
+ values must be order as target values of arguments,
+ True if None is not Allowed and False if is allowed
+ :param body_state: list of Booleans for arguments in body of request if request is post,
+ values must be order as target values of arguments,
+ True if None is not Allowed and False if is allowed
+ :return:
+ """
+
+ def validate_input_decorator(func):
+ def wrapped(*args, **kwargs):
+
+ temp_args = []
+ """
+ this loop made to filter args from object class,
+ when put this function as decorator in function control
+ then there is copy of this class add to front of args
+ """
+ for arg in args:
+ if isinstance(arg, str) == True or \
+ isinstance(arg, list) == True or \
+ isinstance(arg, dict) == True:
+ temp_args.append(arg)
+
+ while len(args_state) < len(temp_args):
+ args_state.append(True)
+
+ for i in range(0, len(temp_args)):
+ if args_state[i]:
+ validate_data(temp_args[i])
+
+ while len(kwargs_state) < len(kwargs):
+ kwargs_state.append(True)
+ counter = 0
+ for i in kwargs:
+ if kwargs_state[counter]:
+ validate_data({i: kwargs[i]})
+
+ counter = counter + 1
+
+ if type == "post" or type == "patch":
+ body = request.json
+ while len(body_state) < len(body):
+ body_state.append(True)
+ counter = 0
+ for i in body:
+ if body_state[counter]:
+ validate_data({i: body[i]})
+
+ counter = counter + 1
+
+ return func(*args, **kwargs)
+
+ return wrapped
+
+ return validate_input_decorator
+
+
def enforce(action_names, object_name, **extra):
"""Fake version of the enforce decorator"""
+
def wrapper_func(func):
def wrapper_args(*args, **kwargs):
# LOG.info("kwargs={}".format(kwargs))
# kwargs['user_id'] = kwargs.pop('user_id', "admin")
# LOG.info("Calling enforce on {} with args={} kwargs={}".format(func.__name__, args, kwargs))
return func(*args, **kwargs)
+
return wrapper_args
+
return wrapper_func
@@ -221,4 +329,5 @@ def check_auth(function):
user_id = kwargs.pop("user_id", token)
result = function(*args, **kwargs, user_id=user_id)
return result
+
return wrapper
diff --git a/python_moonutilities/tests/unit_python/test_validated_input.py b/python_moonutilities/tests/unit_python/test_validated_input.py
new file mode 100644
index 00000000..c8e681e9
--- /dev/null
+++ b/python_moonutilities/tests/unit_python/test_validated_input.py
@@ -0,0 +1,191 @@
+import pytest
+
+
+def test_valid_string():
+ from python_moonutilities.security_functions import validate_data
+ validate_data("CorrectString")
+
+def test_unvalid_string():
+ from python_moonutilities.security_functions import validate_data
+ with pytest.raises(Exception) as exception_info:
+ validate_data("Notcorrect String")
+
+ assert str(exception_info.value) == 'String contains space'
+
+def test_empty_string():
+ from python_moonutilities.security_functions import validate_data
+ with pytest.raises(Exception) as exception_info:
+ validate_data("")
+
+ assert str(exception_info.value) == 'Empty String'
+
+
+def test_none_value():
+ from python_moonutilities.security_functions import validate_data
+ with pytest.raises(Exception) as exception_info:
+ validate_data(None)
+
+ assert str(exception_info.value) == 'Value is Not String or Container or Dictionary'
+
+
+def test_int_value():
+ from python_moonutilities.security_functions import validate_data
+ with pytest.raises(Exception) as exception_info:
+ validate_data(1)
+
+ assert str(exception_info.value) == 'Value is Not String or Container or Dictionary'
+
+
+def test_float_value():
+ from python_moonutilities.security_functions import validate_data
+ with pytest.raises(Exception) as exception_info:
+ validate_data(1.23)
+
+ assert str(exception_info.value) == 'Value is Not String or Container or Dictionary'
+
+
+def test_correct_list():
+ from python_moonutilities.security_functions import validate_data
+ validate_data(["skjdnfa","dao","daosdjpw"])
+
+
+def test_correct_list():
+ from python_moonutilities.security_functions import validate_data
+ validate_data(["skjdnfa"])
+
+
+def test_correct_instead_list():
+ from python_moonutilities.security_functions import validate_data
+ validate_data([["skjdnfa","daswi"],[["daskdlw"],["daklwo"]],["dawl","afioa"],["dawno"]])
+
+
+def test_empty_list():
+ from python_moonutilities.security_functions import validate_data
+ with pytest.raises(Exception) as exception_info:
+ validate_data([])
+
+ assert str(exception_info.value) == 'Empty Container'
+
+
+def test_empty_list_inside_other_list():
+ from python_moonutilities.security_functions import validate_data
+ with pytest.raises(Exception) as exception_info:
+ validate_data(["dajiwdj",[]])
+
+ assert str(exception_info.value) == 'Empty Container'
+
+
+def test_incorrect_string_inside_list():
+ from python_moonutilities.security_functions import validate_data
+ with pytest.raises(Exception) as exception_info:
+ validate_data(["dajiwdj",["dakwe","daow awoepa"]])
+
+ assert str(exception_info.value) == 'String contains space'
+
+
+def test_empty_string_inside_list():
+ from python_moonutilities.security_functions import validate_data
+ with pytest.raises(Exception) as exception_info:
+ validate_data(["dajiwdj", ["dakwe", ""]])
+
+ assert str(exception_info.value) == 'Empty String'
+
+
+def test_correct_tuples():
+ from python_moonutilities.security_functions import validate_data
+ validate_data(("dasdw","dawdwa"))
+
+
+def test_empty_tuples():
+ from python_moonutilities.security_functions import validate_data
+ with pytest.raises(Exception) as exception_info:
+ validate_data(())
+
+ assert str(exception_info.value) == 'Empty Container'
+
+def test_correct_tuple_of_tuple():
+ from python_moonutilities.security_functions import validate_data
+ validate_data(("gjosjefa",("diwajdi","oejfoea"),(("jwdi","fjia"),("nfioa","ifao"))))
+
+
+def test_incorrect_tuple():
+ from python_moonutilities.security_functions import validate_data
+ with pytest.raises(Exception) as exception_info:
+ validate_data(("djawo","dowa afw"))
+
+ assert str(exception_info.value) == 'String contains space'
+
+
+def test_correct_dictionary():
+ from python_moonutilities.security_functions import validate_data
+ validate_data({"daiwdw":"dwioajd"})
+
+
+def test_incorrect_dictionary():
+ from python_moonutilities.security_functions import validate_data
+ with pytest.raises(Exception) as exception_info:
+ validate_data({"daiwdw":"dwioa jd"})
+
+ assert str(exception_info.value) == 'String contains space'
+
+def test_empty_dictionary():
+ from python_moonutilities.security_functions import validate_data
+ with pytest.raises(Exception) as exception_info:
+ validate_data({})
+
+ assert str(exception_info.value) == 'Empty Dictionary'
+
+
+def test_correct_function_pass():
+ from python_moonutilities.security_functions import validate_input
+
+ @validate_input()
+ def temp_function(string,list,tuple):
+ if string!="teststring" :
+ raise ValueError("values which passed incorrect")
+
+ temp_function("teststring",["teststring",["teststring"]],("teststring",("teststring")))
+
+def test_incorrect_function_pass1():
+ from python_moonutilities.security_functions import validate_input
+
+ @validate_input()
+ def temp_function(string, list, tuple):
+ if string != "teststring":
+ raise ValueError("values which passed incorrect")
+
+ with pytest.raises(Exception) as exception_info:
+ temp_function("teststring",list=["teststring", ["testst ring"]],tuple=("teststring", ("teststri ng")))
+
+ assert str(exception_info.value) == 'String contains space'
+
+
+def test_incorrect_function_pass2():
+ from python_moonutilities.security_functions import validate_input
+
+ @validate_input()
+ def temp_function(string, list, dictionary):
+ if string != "teststring":
+ raise ValueError("values which passed incorrect")
+
+ with pytest.raises(Exception) as exception_info:
+ temp_function("teststring", ["teststring", ["teststri ng"]], {"teststring": ("teststring")})
+
+ assert str(exception_info.value) == 'String contains space'
+
+
+def test_incorrect_function_pass3():
+ from python_moonutilities.security_functions import validate_input
+
+ class x:
+ @validate_input()
+ def temp_function(string, list, dictionary):
+ if string != "teststring":
+ raise ValueError("values which passed incorrect")
+
+ e=x;
+
+ with pytest.raises(Exception) as exception_info:
+ e.temp_function("teststring", ["teststring", ["teststri ng"]], {"teststring": ("teststring")})
+
+ assert str(exception_info.value) == 'String contains space'
diff --git a/tests/functional/run_tests.sh b/tests/functional/run_tests.sh
index c5cbabbb..cf55c3bd 100644..100755
--- a/tests/functional/run_tests.sh
+++ b/tests/functional/run_tests.sh
@@ -1,13 +1,18 @@
#!/usr/bin/env bash
-echo "starting Moon Functional Tests"
+MOON_HOME=${1:-.}
-COMPONENTS="moon_authz, moon_interface, moon_manager, moon_orchestrator, moon_wrapper"
+echo "Starting Moon Functional Tests on ${MOON_HOME}"
+
+cd ${MOON_HOME}
+
+COMPONENTS="moon_manager moon_wrapper"
for dir in ${COMPONENTS}; do
echo "Testing component ${dir}"
cd ${MOON_HOME}/${dir}
- docker run --rm --volume $(pwd):/data wukongsun/moon_forming:latest /bin/bash /root/switch.sh functest
+ bash ../tests/functional/run_tests_for_component.sh
+ cd -
done
# TODO: download tests results
diff --git a/tests/functional/run_tests_for_component.sh b/tests/functional/run_tests_for_component.sh
index fd9ab7fa..6c6a0330 100644
--- a/tests/functional/run_tests_for_component.sh
+++ b/tests/functional/run_tests_for_component.sh
@@ -1,8 +1,8 @@
#!/usr/bin/env bash
CUR_PWD=$(pwd)
-INPUT_FILE=../tools/moon_kubernetes/templates/moon_forming_functest.yaml
-OUTPUT_FILE=tests/functional_pod/moon_forming_functest.yaml
+INPUT_FILE=../tools/moon_kubernetes/templates/moon_functest.yaml
+OUTPUT_FILE=tests/functional_pod/moon_functest.yaml
echo current working directory: ${CUR_PWD}
diff --git a/tests/python_unit/run_tests.sh b/tests/python_unit/run_tests.sh
index 33c1ab98..ab30e523 100644
--- a/tests/python_unit/run_tests.sh
+++ b/tests/python_unit/run_tests.sh
@@ -1,6 +1,6 @@
#!/usr/bin/env bash
-echo "starting Moon Functional Tests"
+echo "starting Moon Unit Tests"
cd python_moonutilities
docker run --rm --volume $(pwd):/data wukongsun/moon_python_unit_test:latest
@@ -9,4 +9,9 @@ cd ../python_moondb
docker run --rm --volume $(pwd):/data wukongsun/moon_python_unit_test:latest
cd ../python_moonclient
-docker run --rm --volume $(pwd):/data wukongsun/moon_python_unit_test:latest \ No newline at end of file
+docker run --rm --volume $(pwd):/data wukongsun/moon_python_unit_test:latest
+
+cd ../moon_manager
+rm -f tests/unit_python/database.db
+docker run --rm --volume $(pwd):/data wukongsun/moon_python_unit_test:latest
+
diff --git a/tools/moon_kubernetes/README.md b/tools/moon_kubernetes/README.md
index 2077e580..e75fe086 100644
--- a/tools/moon_kubernetes/README.md
+++ b/tools/moon_kubernetes/README.md
@@ -28,17 +28,17 @@ apt-get install -y kubelet kubeadm kubectl
```
## Moon Deployment
-### Initiate K8S
+### Deploy kubernete and moon
```bash
cd $MOON_HOME
-bash tools/moon_kubernetes/init_k8s.sh
+bash tools/moon_kubernetes/init_k8s_moon.sh
```
+This will wait for kubernetes and then moon to be up
-Wait until all the kubeadm containers are in the `running` state:
+To check that the platform is running correctely,
```bash
watch kubectl get po --namespace=kube-system
```
-
You must see something like this:
$ kubectl get po --namespace=kube-system
@@ -53,14 +53,6 @@ You must see something like this:
kube-proxy-x88wg 1/1 Running 0 1h
kube-scheduler-varuna 1/1 Running 0 1h
-
-### Deploy Moon
-```bash
-cd $MOON_HOME
-sudo bash tools/moon_kubernetes/start_moon.sh
-```
-
-Wait until all the Moon containers are in the `running` state:
```bash
watch kubectl get po --namespace=moon
```
@@ -79,6 +71,16 @@ You must see something like this:
orchestrator-65d8fb4574-tnfx2 1/1 Running 0 51m
wrapper-astonishing-748b7dcc4f-ngsvp 1/1 Running 0 51m
+
+### Deploy or redeploy Moon only
+
+Kubernete shall be running.
+
+```bash
+cd $MOON_HOME
+sudo bash tools/moon_kubernetes/init_k8s_moon.sh moon
+```
+
### Troubleshoot
check *Consul* for:
diff --git a/tools/moon_kubernetes/conf/moon.conf b/tools/moon_kubernetes/conf/moon.conf
index 28ad7a8e..5fc94edd 100644
--- a/tools/moon_kubernetes/conf/moon.conf
+++ b/tools/moon_kubernetes/conf/moon.conf
@@ -22,12 +22,12 @@ components:
port: 8080
bind: 0.0.0.0
hostname: interface
- container: wukongsun/moon_interface:latest
+ container: moonplatform/moon_interface:latest
authz:
port: 8081
bind: 0.0.0.0
hostname: interface
- container: wukongsun/moon_authz:latest
+ container: moonplatform/moon_authz:latest
session:
container: asteroide/session:latest
port: 8082
@@ -35,7 +35,7 @@ components:
port: 8083
bind: 0.0.0.0
hostname: orchestrator
- container: wukongsun/moon_orchestrator:latest
+ container: moonplatform/moon_orchestrator:latest
external:
port: 30003
hostname: orchestrator
@@ -43,13 +43,13 @@ components:
port: 8080
bind: 0.0.0.0
hostname: wrapper
- container: wukongsun/moon_wrapper:latest
+ container: moonplatform/moon_wrapper:latest
timeout: 5
manager:
port: 8082
bind: 0.0.0.0
hostname: manager
- container: wukongsun/moon_manager:latest
+ container: moonplatform/moon_manager:latest
external:
port: 30001
hostname: manager
@@ -67,7 +67,7 @@ logging:
handlers:
console:
class : logging.StreamHandler
- formatter: brief
+ formatter: custom
level : INFO
stream : ext://sys.stdout
file:
diff --git a/tools/moon_kubernetes/init_k8s.sh b/tools/moon_kubernetes/init_k8s.sh
deleted file mode 100644
index 8ec1237c..00000000
--- a/tools/moon_kubernetes/init_k8s.sh
+++ /dev/null
@@ -1,33 +0,0 @@
-#!/usr/bin/env bash
-
-set -x
-
-sudo kubeadm reset
-
-sudo swapoff -a
-
-sudo kubeadm init --pod-network-cidr=192.168.0.0/16 # network for Calico
-#sudo kubeadm init --pod-network-cidr=10.244.0.0/16 # network for Canal
-
-mkdir -p $HOME/.kube
-sudo cp -f /etc/kubernetes/admin.conf $HOME/.kube/config
-sudo chown $(id -u):$(id -g) $HOME/.kube/config
-
-kubectl apply -f http://docs.projectcalico.org/v2.4/getting-started/kubernetes/installation/hosted/kubeadm/1.6/calico.yaml
-#kubectl apply -f https://raw.githubusercontent.com/projectcalico/canal/master/k8s-install/1.6/rbac.yaml
-#kubectl apply -f https://raw.githubusercontent.com/projectcalico/canal/master/k8s-install/1.6/canal.yaml
-
-#kubectl create -f https://raw.githubusercontent.com/kubernetes/dashboard/master/src/deploy/recommended/kubernetes-dashboard.yaml
-
-kubectl delete deployment kube-dns --namespace=kube-system
-kubectl apply -f tools/moon_kubernetes/templates/kube-dns.yaml
-
-kubectl taint nodes --all node-role.kubernetes.io/master- # make the master also as a node
-
-kubectl proxy&
-sleep 5
-echo =========================================
-kubectl get po --namespace=kube-system
-echo =========================================
-
-
diff --git a/tools/moon_kubernetes/init_k8s_moon.sh b/tools/moon_kubernetes/init_k8s_moon.sh
new file mode 100644
index 00000000..0617de86
--- /dev/null
+++ b/tools/moon_kubernetes/init_k8s_moon.sh
@@ -0,0 +1,280 @@
+#!/bin/bash
+#number of pods type that should be running or be stopped
+declare -i pods_to_check=0
+ #global variable on current namespace to check
+current_namespace=""
+#if set to 1 we check that the pods are running, otherwise we chack that the pods are stopped
+declare -i check_running=1
+#name of the pod to check
+match_pattern=""
+#postfix used to recognize pods name
+OS="unknown_os"
+
+#this function checks if a pod with name starting with $1 is in the Running / Stopped state depending on $heck_running
+# $1 : the name the pods starts with (without the random string added by kubernate to the pod name)
+# $2 : either the number of identical pods that shall be run or #
+# $3 : if $2 is #, the number of lines of the pods name appear on which the pod appears
+function check_pod() {
+ declare -i nb_arguments=$#
+ match_pattern="$1"; shift
+ if [ $nb_arguments -gt 2 ]; then
+ shift; declare -i nb_pods_pattern="$1"
+ if [ $check_running -eq 1 ]; then #check if pods are running
+ declare -i result=$(sudo kubectl get po --namespace=${current_namespace} | grep $match_pattern | grep "1/1" | grep -c "Running")
+ if [ $result -eq $nb_pods_pattern ]; then
+ pods_to_check=$pods_to_check+1
+ fi
+ else #check if pods are stopped
+ declare -i result=$(sudo kubectl get po --namespace=${current_namespace} | grep $match_pattern | grep -c "Running\|Terminating")
+ if [ $result -eq 0 ]; then
+ pods_to_check=$pods_to_check+1
+ fi
+ fi
+ else
+ declare -i nb=$1
+ if [ $check_running -eq 1 ]; then #check if pods are running
+ declare -i result=$(sudo kubectl get po --namespace=${current_namespace} | grep $match_pattern | grep "$nb/$nb" | grep -c "Running")
+ if [ $result -eq 1 ]; then
+ pods_to_check=$pods_to_check+1
+ fi
+ else #check if pods are stopped
+ declare -i result=$(sudo kubectl get po --namespace=${current_namespace} | grep $match_pattern | grep -c "Running\|Terminating")
+ if [ $result -eq 0 ]; then
+ pods_to_check=$pods_to_check+1
+ fi
+ fi
+ fi
+}
+
+#this function tests a list of pods
+function check_pods() {
+ current_namespace="${1}"; shift
+ pods=("${@}")
+ declare -i pods_nb=${#pods[@]}
+ sleep 2
+ while [ $pods_to_check -lt $pods_nb ]
+ do
+ pods_to_check=0
+ for node in "${pods[@]}"
+ do
+ check_pod $node
+ done
+
+ if [ $check_running -eq 1 ]; then
+ echo -ne "$pods_to_check node types on $pods_nb are running...\033[0K\r"
+ else
+ declare -i running_pods=$pods_nb-$pods_to_check
+ echo -ne "$running_pods node types on $pods_nb are still running...\033[0K\r"
+ fi
+ sleep 2
+ done
+}
+
+#this function checks if a list of pods ($2) in a specific namspace ($1) are in the Running state
+function check_pods_running() {
+ check_running=1
+ check_pods "${@}"
+ pods_to_check=0
+}
+
+#this function checks if a list of pods ($2) are not in a specific namspace ($1)
+function check_pods_not_running() {
+ check_running=0
+ check_pods "${@}"
+ pods_to_check=0
+}
+
+function wait_for_kubernate_calico() {
+ echo -ne "Waiting for kubernate... "
+ kube_namespace="kube-system"
+ declare -a kube_pods=("calico-etcd 1" "calico-node 2" "calico-policy-controller 1" "etcd-${OS} 1" "kube-apiserver-${OS} 1" "kube-controller-manager-${OS} 1" "kube-dns 3" "kube-proxy 1" "kube-scheduler-${OS} 1")
+ check_pods_running "$kube_namespace" "${kube_pods[@]}"
+}
+
+function wait_for_moon_init() {
+ echo "Waiting for moon (consul, db, keystone) ..."
+ kube_namespace="moon"
+ declare -a kube_pods=("consul 1" "db 1" "keystone 1")
+ check_pods_running "$kube_namespace" "${kube_pods[@]}"
+}
+
+function wait_for_moon_forming() {
+ echo "Waiting for moon (forming) ..."
+ kube_namespace="moon"
+ declare -a kube_pods=("forming 1")
+ check_pods_running "$kube_namespace" "${kube_pods[@]}"
+}
+
+function wait_for_moon_manager() {
+ echo "Waiting for moon (manager) ..."
+ kube_namespace="moon"
+ declare -a kube_pods=("manager # 1")
+ check_pods_running "$kube_namespace" "${kube_pods[@]}"
+}
+
+function wait_for_moon_end() {
+ echo "Waiting for moon (orchestrator, gui) ..."
+ kube_namespace="moon"
+ declare -a kube_pods=("gui 1" "orchestrator 1")
+ check_pods_running "$kube_namespace" "${kube_pods[@]}"
+}
+
+function wait_for_moon_forming_to_end() {
+ echo "Waiting for moon forming to finish initialization. This can take few minutes..."
+ kube_namespace="moon"
+ declare -a kube_pods=("forming 1")
+ check_pods_not_running "$kube_namespace" "${kube_pods[@]}"
+}
+
+function wait_for_moon_delete_to_end(){
+ echo "Waiting for moon to terminate..."
+ kube_namespace="moon"
+ declare -a kube_pods=("consul 1" "db 1" "keystone 1" "manager # 3" "gui 1" "orchestrator 1")
+ check_pods_not_running "$kube_namespace" "${kube_pods[@]}"
+}
+
+function check_os(){
+ if [ -f /etc/os-release ]; then
+ # freedesktop.org and systemd
+ . /etc/os-release
+ OS=${ID}
+ elif type lsb_release >/dev/null 2>&1; then
+ # linuxbase.org
+ OS=$(lsb_release -si)
+ declare -i result=$(grep -i "debian" $OS)
+ if [ $result -eq 1 ]; then
+ OS="debian"
+ fi
+ declare -i result=$(grep -i "ubuntu" $OS)
+ if [ $result -eq 1 ]; then
+ OS="ubuntu"
+ fi
+ elif [ -f /etc/lsb-release ]; then
+ # For some versions of Debian/Ubuntu without lsb_release command
+ . /etc/lsb-release
+ OS=$DISTRIB_ID
+ declare -i result=$(grep -i "debian" $OS)
+ if [ $result -eq 1 ]; then
+ OS="debian"
+ fi
+ declare -i result=$(grep -i "ubuntu" $OS)
+ if [ $result -eq 1 ]; then
+ OS="ubuntu"
+ fi
+ elif [ -f /etc/debian_version ]; then
+ # Older Debian/Ubuntu/etc.
+ declare -i result=$(grep -i "debian" $OS)
+ if [ $result -eq 1 ]; then
+ OS="debian"
+ fi
+ declare -i result=$(grep -i "ubuntu" $OS)
+ if [ $result -eq 1 ]; then
+ OS="ubuntu"
+ fi
+ elif [ -f /etc/SuSe-release ]; then
+ # Older SuSE/etc.
+ echo "TO DO : get the name of the OS at the end of the pods name"
+ elif [ -f /etc/redhat-release ]; then
+ # Older Red Hat, CentOS, etc.
+ echo "TO DO : get the name of the OS at the end of the pods name"
+ else
+ # Fall back to uname, e.g. "Linux <version>", also works for BSD, etc.
+ OS=$(uname -s)
+ echo "TO DO : get the name of the OS at the end of the pods name"
+ fi
+ echo "postfix used to detect pods name : ${OS}"
+}
+
+declare -i nb_arguments=$#
+declare -i init_kubernate=1
+
+if [ $# -eq 1 ]; then
+ if [ $1 == "moon" ]; then
+ init_kubernate=0
+ fi
+
+ if [ $1 == "-h" ]; then
+ echo "Usage : "
+ echo " - 'bash tools/moon_kubernetes/init_k8s_moon.sh' launches the kubernates platform and the moon platform."
+ echo " - 'bash tools/moon_kubernetes/init_k8s_moon.sh moon' launches the moon platform only. If the moon platform is already launched, it deletes and recreates it."
+ echo " "
+ fi
+fi
+
+if [ $init_kubernate -eq 1 ]; then
+ check_os
+ echo "=============================="
+ echo "Launching kubernate "
+ echo "=============================="
+ sudo kubeadm reset
+ sudo swapoff -a
+ sudo kubeadm init --pod-network-cidr=192.168.0.0/16 # network for Calico
+ #sudo kubeadm init --pod-network-cidr=10.244.0.0/16 # network for Canal
+
+ mkdir -p $HOME/.kube
+ sudo cp -f /etc/kubernetes/admin.conf $HOME/.kube/config
+ sudo chown $(id -u):$(id -g) $HOME/.kube/config
+
+ kubectl apply -f http://docs.projectcalico.org/v2.4/getting-started/kubernetes/installation/hosted/kubeadm/1.6/calico.yaml
+ #kubectl apply -f https://raw.githubusercontent.com/projectcalico/canal/master/k8s-install/1.6/rbac.yaml
+ #kubectl apply -f https://raw.githubusercontent.com/projectcalico/canal/master/k8s-install/1.6/canal.yaml
+ #kubectl create -f https://raw.githubusercontent.com/kubernetes/dashboard/master/src/deploy/recommended/kubernetes-dashboard.yaml
+
+ kubectl delete deployment kube-dns --namespace=kube-system
+ kubectl apply -f tools/moon_kubernetes/templates/kube-dns.yaml
+ kubectl taint nodes --all node-role.kubernetes.io/master- # malke the master also as a node
+
+ kubectl proxy&
+
+ wait_for_kubernate_calico
+
+ echo "=============================="
+ echo "Kubernate platform is ready ! "
+ echo "=============================="
+fi
+
+echo "============================"
+echo "Launching moon "
+echo "============================"
+#check if the moon platform is running, if so we terminate it
+declare -i moon_is_running=$(sudo kubectl get namespace | grep -c moon)
+if [ $moon_is_running -eq 1 ]; then
+ sudo kubectl delete namespace moon
+ wait_for_moon_delete_to_end
+ sleep 2
+fi
+
+#launching moon
+kubectl create namespace moon
+kubectl create configmap moon-config --from-file tools/moon_kubernetes/conf/moon.conf -n moon
+kubectl create configmap config --from-file ~/.kube/config -n moon
+kubectl create configmap moon-policy-templates --from-file tests/functional/scenario_tests -n moon
+kubectl create secret generic mysql-root-pass --from-file=tools/moon_kubernetes/conf/password_root.txt -n moon
+kubectl create secret generic mysql-pass --from-file=tools/moon_kubernetes/conf/password_moon.txt -n moon
+
+kubectl create -n moon -f tools/moon_kubernetes/templates/consul.yaml
+kubectl create -n moon -f tools/moon_kubernetes/templates/db.yaml
+kubectl create -n moon -f tools/moon_kubernetes/templates/keystone.yaml
+wait_for_moon_init
+
+
+kubectl create -n moon -f tools/moon_kubernetes/templates/moon_forming.yaml
+wait_for_moon_forming
+
+
+kubectl create -n moon -f tools/moon_kubernetes/templates/moon_manager.yaml
+wait_for_moon_manager
+
+
+kubectl create -n moon -f tools/moon_kubernetes/templates/moon_orchestrator.yaml
+kubectl create -n moon -f tools/moon_kubernetes/templates/moon_gui.yaml
+wait_for_moon_end
+
+#wait the end of pods initialization performed by moon forming
+wait_for_moon_forming_to_end
+
+echo "========================== "
+echo "Moon platform is ready !"
+echo "=========================="
+
+
diff --git a/tools/moon_kubernetes/start_moon.sh b/tools/moon_kubernetes/start_moon.sh
deleted file mode 100644
index 32d9740d..00000000
--- a/tools/moon_kubernetes/start_moon.sh
+++ /dev/null
@@ -1,38 +0,0 @@
-#!/usr/bin/env bash
-
-set -x
-
-kubectl create namespace moon
-kubectl create configmap moon-config --from-file tools/moon_kubernetes/conf/moon.conf -n moon
-kubectl create configmap config --from-file ~/.kube/config -n moon
-kubectl create configmap moon-policy-templates --from-file tests/functional/scenario_tests -n moon
-kubectl create secret generic mysql-root-pass --from-file=tools/moon_kubernetes/conf/password_root.txt -n moon
-kubectl create secret generic mysql-pass --from-file=tools/moon_kubernetes/conf/password_moon.txt -n moon
-
-kubectl create -n moon -f tools/moon_kubernetes/templates/consul.yaml
-kubectl create -n moon -f tools/moon_kubernetes/templates/db.yaml
-kubectl create -n moon -f tools/moon_kubernetes/templates/keystone.yaml
-
-echo =========================================
-kubectl get pods -n moon
-echo =========================================
-
-sleep 10
-kubectl create -n moon -f tools/moon_kubernetes/templates/moon_forming.yaml
-
-echo Waiting for jobs forming
-sleep 5
-kubectl get jobs -n moon
-kubectl logs -n moon jobs/forming
-
-sleep 5
-kubectl create -n moon -f tools/moon_kubernetes/templates/moon_manager.yaml
-
-sleep 2
-kubectl create -n moon -f tools/moon_kubernetes/templates/moon_orchestrator.yaml
-
-kubectl create -n moon -f tools/moon_kubernetes/templates/moon_gui.yaml
-
-# load moon_wrapper on both master and slaves
-# moon_create_wrapper
-
diff --git a/tools/moon_kubernetes/templates/db.yaml b/tools/moon_kubernetes/templates/db.yaml
index a055507e..5a0e5e98 100644
--- a/tools/moon_kubernetes/templates/db.yaml
+++ b/tools/moon_kubernetes/templates/db.yaml
@@ -14,7 +14,7 @@ spec:
spec:
containers:
- name: db
- image: mysql:latest
+ image: mysql:5.7
env:
- name: MYSQL_DATABASE
value: "moon"
diff --git a/tools/moon_kubernetes/templates/moon_forming.yaml b/tools/moon_kubernetes/templates/moon_forming.yaml
index 334ee175..1214a41a 100644
--- a/tools/moon_kubernetes/templates/moon_forming.yaml
+++ b/tools/moon_kubernetes/templates/moon_forming.yaml
@@ -10,7 +10,7 @@ spec:
spec:
containers:
- name: forming
- image: wukongsun/moon_forming:latest
+ image: moonplatform/moon_forming:latest
env:
- name: POPULATE_ARGS
value: "--verbose" # debug mode: --debug
diff --git a/tools/moon_kubernetes/templates/moon_forming_functest.yaml b/tools/moon_kubernetes/templates/moon_functest.yaml
index 4cb2c3a0..e876849e 100644
--- a/tools/moon_kubernetes/templates/moon_forming_functest.yaml
+++ b/tools/moon_kubernetes/templates/moon_functest.yaml
@@ -10,10 +10,7 @@ spec:
spec:
containers:
- name: functest
- image: wukongsun/moon_forming:dev
- env:
- - name: COMMAND
- value: "functest"
+ image: moonplatform/moon_python_func_test:latest
volumeMounts:
- name: config-volume
mountPath: /etc/moon
@@ -27,4 +24,4 @@ spec:
hostPath:
path: "{{PATH}}"
restartPolicy: Never
- #backoffLimit: 4 \ No newline at end of file
+ #backoffLimit: 4
diff --git a/tools/moon_kubernetes/templates/moon_gui.yaml b/tools/moon_kubernetes/templates/moon_gui.yaml
index 7c6ab732..eca4267d 100644
--- a/tools/moon_kubernetes/templates/moon_gui.yaml
+++ b/tools/moon_kubernetes/templates/moon_gui.yaml
@@ -13,7 +13,7 @@ spec:
hostname: gui
containers:
- name: gui
- image: wukongsun/moon_gui:latest
+ image: moonplatform/moon_gui:latest
env:
- name: MANAGER_HOST
value: "127.0.0.1"
diff --git a/tools/moon_kubernetes/templates/moon_manager.yaml b/tools/moon_kubernetes/templates/moon_manager.yaml
index 28913f48..8eb59482 100644
--- a/tools/moon_kubernetes/templates/moon_manager.yaml
+++ b/tools/moon_kubernetes/templates/moon_manager.yaml
@@ -4,7 +4,7 @@ metadata:
name: manager
namespace: moon
spec:
- replicas: 3
+ replicas: 1
template:
metadata:
labels:
@@ -13,7 +13,7 @@ spec:
hostname: manager
containers:
- name: manager
- image: wukongsun/moon_manager:latest
+ image: moonplatform/moon_manager:latest
ports:
- containerPort: 8082
---
diff --git a/tools/moon_kubernetes/templates/moon_orchestrator.yaml b/tools/moon_kubernetes/templates/moon_orchestrator.yaml
index 9c34a60b..a4ae2bd9 100644
--- a/tools/moon_kubernetes/templates/moon_orchestrator.yaml
+++ b/tools/moon_kubernetes/templates/moon_orchestrator.yaml
@@ -13,7 +13,7 @@ spec:
hostname: orchestrator
containers:
- name: orchestrator
- image: wukongsun/moon_orchestrator:latest
+ image: moonplatform/moon_orchestrator:latest
ports:
- containerPort: 8083
volumeMounts:
diff --git a/tools/policies/generate_opst_policy.py b/tools/policies/generate_opst_policy.py
new file mode 100644
index 00000000..dd01d1c1
--- /dev/null
+++ b/tools/policies/generate_opst_policy.py
@@ -0,0 +1,167 @@
+import json
+import os
+import logging
+import argparse
+
+
+FILES = [
+ "cinder.policy.json",
+ "glance.policy.json",
+ "keystone.policy.json",
+ "neutron.policy.json",
+ "nova.policy.json",
+]
+policy = {
+ "pdps": [{
+ "name": "external_pdp",
+ "keystone_project_id": "",
+ "description": "",
+ "policies": [{"name": "OpenStack RBAC Policy"}]}
+ ],
+
+ "policies": [{
+ "name": "OpenStack RBAC Policy",
+ "genre": "authz",
+ "description": "A RBAC policy similar of what you can find through policy.json files",
+ "model": {"name": "OPST_RBAC"}, "mandatory": True, "override": True}
+ ],
+
+ "models": [{"name": "OPST_RBAC", "description": "", "meta_rules": [{"name": "rbac"}], "override": True}],
+
+ "subjects": [
+ {"name": "admin", "description": "", "extra": {}, "policies": [{"name": "OpenStack RBAC Policy"}]},
+ {"name": "demo", "description": "", "extra": {}, "policies": [{"name": "OpenStack RBAC Policy"}]}
+ ],
+
+ "subject_categories": [{"name": "role", "description": "a role in OpenStack"}],
+
+ "subject_data": [
+ {"name": "admin", "description": "the admin role", "policies": [], "category": {"name": "role"}},
+ {"name": "member", "description": "the member role", "policies": [], "category": {"name": "role"}}
+ ],
+
+ "subject_assignments": [
+ {"subject": {"name": "admin"}, "category": {"name": "role"}, "assignments": [{"name": "admin"}, {"name": "member"}]},
+ {"subject": {"name": "demo"}, "category": {"name": "role"}, "assignments": [{"name": "member"}]}
+ ],
+
+ "objects": [],
+
+ "object_categories": [{"name": "id", "description": "the UID of each virtual machine"}],
+
+ "object_data": [
+ {
+ "name": "all_vm",
+ "description": "represents all virtual machines in this project",
+ "policies": [],
+ "category": {"name": "id"}},
+ ],
+
+ "object_assignments": [],
+
+ "actions": [],
+
+ "action_categories": [{"name": "action_id", "description": ""}],
+
+ "action_data": [],
+
+ "action_assignments": [],
+
+ "meta_rules": [
+ {
+ "name": "rbac", "description": "",
+ "subject_categories": [{"name": "role"}],
+ "object_categories": [{"name": "id"}],
+ "action_categories": [{"name": "action_id"}]
+ }
+ ],
+
+ "rules": [],
+
+}
+logger = logging.getLogger(__name__)
+
+
+def init():
+ parser = argparse.ArgumentParser()
+ parser.add_argument("--verbose", '-v', action='store_true', help='verbose mode')
+ parser.add_argument("--debug", '-d', action='store_true', help='debug mode')
+ parser.add_argument("--dir", help='directory containing policy files', default="./policy.json.d")
+ parser.add_argument("--indent", '-i', help='indent the output (default:None)', type=int, default=None)
+ parser.add_argument("--output", '-o', help='output name', type=str, default="opst_default_policy.json")
+ args = parser.parse_args()
+ logging_format = "%(levelname)s: %(message)s"
+ if args.verbose:
+ logging.basicConfig(level=logging.INFO, format=logging_format)
+ if args.debug:
+ logging.basicConfig(level=logging.DEBUG, format=logging_format)
+ else:
+ logging.basicConfig(format=logging_format)
+ return args
+
+
+def get_rules(args):
+ results = {}
+ for f in FILES:
+ _json_file = json.loads(open(os.path.join(args.dir, f)).read())
+ keys = list(_json_file.keys())
+ values = list(_json_file.values())
+ for value in values:
+ if value in keys:
+ keys.remove(value)
+ component = os.path.basename(f).split(".")[0]
+ results[component] = keys
+ return results
+
+
+def build_dict(results):
+ for key in results:
+ for rule in results[key]:
+ _output = {
+ "name": rule,
+ "description": "{} action for {}".format(rule, key),
+ "extra": {"component": key},
+ "policies": []
+ }
+ policy['actions'].append(_output)
+ _output = {
+ "name": rule,
+ "description": "{} action for {}".format(rule, key),
+ "policies": [],
+ "category": {"name": "action_id"}
+ }
+ policy['action_data'].append(_output)
+ _output = {
+ "action": {"name": rule},
+ "category": {"name": "action_id"},
+ "assignments": [{"name": rule}, ]}
+ policy['action_assignments'].append(_output)
+ _output = {
+ "meta_rule": {"name": "rbac"},
+ "rule": {
+ "subject_data": [{"name": "admin"}],
+ "object_data": [{"name": "all_vm"}],
+ "action_data": [{"name": rule}]
+ },
+ "policy": {"name": "OpenStack RBAC Policy"},
+ "instructions": {"decision": "grant"},
+ "enabled": True
+ }
+ policy['rules'].append(_output)
+ # TODO: add rules for member only
+ # TODO: add rules for everyone
+
+
+def write_dict(args):
+ json.dump(policy, open(args.output, "w"), indent=args.indent)
+
+
+def main():
+ args = init()
+ rules = get_rules(args)
+ build_dict(rules)
+ write_dict(args)
+
+
+if __name__ == "__main__":
+ main() \ No newline at end of file
diff --git a/tools/policies/policy.json.d/cinder.policy.json b/tools/policies/policy.json.d/cinder.policy.json
new file mode 100644
index 00000000..02af88bd
--- /dev/null
+++ b/tools/policies/policy.json.d/cinder.policy.json
@@ -0,0 +1,104 @@
+{
+ "context_is_admin": "role:admin",
+ "admin_or_owner": "is_admin:True or project_id:%(project_id)s",
+ "default": "rule:admin_or_owner",
+
+ "admin_api": "is_admin:True",
+
+ "volume:create": "",
+ "volume:delete": "rule:admin_or_owner",
+ "volume:get": "rule:admin_or_owner",
+ "volume:get_all": "rule:admin_or_owner",
+ "volume:get_volume_metadata": "rule:admin_or_owner",
+ "volume:delete_volume_metadata": "rule:admin_or_owner",
+ "volume:update_volume_metadata": "rule:admin_or_owner",
+ "volume:get_volume_admin_metadata": "rule:admin_api",
+ "volume:update_volume_admin_metadata": "rule:admin_api",
+ "volume:get_snapshot": "rule:admin_or_owner",
+ "volume:get_all_snapshots": "rule:admin_or_owner",
+ "volume:create_snapshot": "rule:admin_or_owner",
+ "volume:delete_snapshot": "rule:admin_or_owner",
+ "volume:update_snapshot": "rule:admin_or_owner",
+ "volume:extend": "rule:admin_or_owner",
+ "volume:update_readonly_flag": "rule:admin_or_owner",
+ "volume:retype": "rule:admin_or_owner",
+ "volume:update": "rule:admin_or_owner",
+
+ "volume_extension:types_manage": "rule:admin_api",
+ "volume_extension:types_extra_specs": "rule:admin_api",
+ "volume_extension:access_types_qos_specs_id": "rule:admin_api",
+ "volume_extension:access_types_extra_specs": "rule:admin_api",
+ "volume_extension:volume_type_access": "rule:admin_or_owner",
+ "volume_extension:volume_type_access:addProjectAccess": "rule:admin_api",
+ "volume_extension:volume_type_access:removeProjectAccess": "rule:admin_api",
+ "volume_extension:volume_type_encryption": "rule:admin_api",
+ "volume_extension:volume_encryption_metadata": "rule:admin_or_owner",
+ "volume_extension:extended_snapshot_attributes": "rule:admin_or_owner",
+ "volume_extension:volume_image_metadata": "rule:admin_or_owner",
+
+ "volume_extension:quotas:show": "",
+ "volume_extension:quotas:update": "rule:admin_api",
+ "volume_extension:quotas:delete": "rule:admin_api",
+ "volume_extension:quota_classes": "rule:admin_api",
+ "volume_extension:quota_classes:validate_setup_for_nested_quota_use": "rule:admin_api",
+
+ "volume_extension:volume_admin_actions:reset_status": "rule:admin_api",
+ "volume_extension:snapshot_admin_actions:reset_status": "rule:admin_api",
+ "volume_extension:backup_admin_actions:reset_status": "rule:admin_api",
+ "volume_extension:volume_admin_actions:force_delete": "rule:admin_api",
+ "volume_extension:volume_admin_actions:force_detach": "rule:admin_api",
+ "volume_extension:snapshot_admin_actions:force_delete": "rule:admin_api",
+ "volume_extension:backup_admin_actions:force_delete": "rule:admin_api",
+ "volume_extension:volume_admin_actions:migrate_volume": "rule:admin_api",
+ "volume_extension:volume_admin_actions:migrate_volume_completion": "rule:admin_api",
+
+ "volume_extension:volume_host_attribute": "rule:admin_api",
+ "volume_extension:volume_tenant_attribute": "rule:admin_or_owner",
+ "volume_extension:volume_mig_status_attribute": "rule:admin_api",
+ "volume_extension:hosts": "rule:admin_api",
+ "volume_extension:services:index": "rule:admin_api",
+ "volume_extension:services:update" : "rule:admin_api",
+
+ "volume_extension:volume_manage": "rule:admin_api",
+ "volume_extension:volume_unmanage": "rule:admin_api",
+
+ "volume_extension:capabilities": "rule:admin_api",
+
+ "volume:create_transfer": "rule:admin_or_owner",
+ "volume:accept_transfer": "",
+ "volume:delete_transfer": "rule:admin_or_owner",
+ "volume:get_all_transfers": "rule:admin_or_owner",
+
+ "volume_extension:replication:promote": "rule:admin_api",
+ "volume_extension:replication:reenable": "rule:admin_api",
+
+ "volume:enable_replication": "rule:admin_api",
+ "volume:disable_replication": "rule:admin_api",
+ "volume:failover_replication": "rule:admin_api",
+ "volume:list_replication_targets": "rule:admin_api",
+
+ "backup:create" : "",
+ "backup:delete": "rule:admin_or_owner",
+ "backup:get": "rule:admin_or_owner",
+ "backup:get_all": "rule:admin_or_owner",
+ "backup:restore": "rule:admin_or_owner",
+ "backup:backup-import": "rule:admin_api",
+ "backup:backup-export": "rule:admin_api",
+
+ "snapshot_extension:snapshot_actions:update_snapshot_status": "",
+ "snapshot_extension:snapshot_manage": "rule:admin_api",
+ "snapshot_extension:snapshot_unmanage": "rule:admin_api",
+
+ "consistencygroup:create" : "group:nobody",
+ "consistencygroup:delete": "group:nobody",
+ "consistencygroup:update": "group:nobody",
+ "consistencygroup:get": "group:nobody",
+ "consistencygroup:get_all": "group:nobody",
+
+ "consistencygroup:create_cgsnapshot" : "group:nobody",
+ "consistencygroup:delete_cgsnapshot": "group:nobody",
+ "consistencygroup:get_cgsnapshot": "group:nobody",
+ "consistencygroup:get_all_cgsnapshots": "group:nobody",
+
+ "scheduler_extension:scheduler_stats:get_pools" : "rule:admin_api"
+}
diff --git a/tools/policies/policy.json.d/glance.policy.json b/tools/policies/policy.json.d/glance.policy.json
new file mode 100644
index 00000000..5b1f6be7
--- /dev/null
+++ b/tools/policies/policy.json.d/glance.policy.json
@@ -0,0 +1,63 @@
+{
+ "context_is_admin": "role:admin",
+ "default": "role:admin",
+
+ "add_image": "",
+ "delete_image": "",
+ "get_image": "",
+ "get_images": "",
+ "modify_image": "",
+ "publicize_image": "role:admin",
+ "communitize_image": "",
+ "copy_from": "",
+
+ "download_image": "",
+ "upload_image": "",
+
+ "delete_image_location": "",
+ "get_image_location": "",
+ "set_image_location": "",
+
+ "add_member": "",
+ "delete_member": "",
+ "get_member": "",
+ "get_members": "",
+ "modify_member": "",
+
+ "manage_image_cache": "role:admin",
+
+ "get_task": "",
+ "get_tasks": "",
+ "add_task": "",
+ "modify_task": "",
+ "tasks_api_access": "role:admin",
+
+ "deactivate": "",
+ "reactivate": "",
+
+ "get_metadef_namespace": "",
+ "get_metadef_namespaces":"",
+ "modify_metadef_namespace":"",
+ "add_metadef_namespace":"",
+
+ "get_metadef_object":"",
+ "get_metadef_objects":"",
+ "modify_metadef_object":"",
+ "add_metadef_object":"",
+
+ "list_metadef_resource_types":"",
+ "get_metadef_resource_type":"",
+ "add_metadef_resource_type_association":"",
+
+ "get_metadef_property":"",
+ "get_metadef_properties":"",
+ "modify_metadef_property":"",
+ "add_metadef_property":"",
+
+ "get_metadef_tag":"",
+ "get_metadef_tags":"",
+ "modify_metadef_tag":"",
+ "add_metadef_tag":"",
+ "add_metadef_tags":""
+
+}
diff --git a/tools/policies/policy.json.d/keystone.policy.json b/tools/policies/policy.json.d/keystone.policy.json
new file mode 100644
index 00000000..263912bf
--- /dev/null
+++ b/tools/policies/policy.json.d/keystone.policy.json
@@ -0,0 +1,260 @@
+{
+ "admin_required": "role:admin",
+ "cloud_admin": "role:admin and (is_admin_project:True or domain_id:admin_domain_id)",
+ "service_role": "role:service",
+ "service_or_admin": "rule:admin_required or rule:service_role",
+ "owner": "user_id:%(user_id)s or user_id:%(target.token.user_id)s",
+ "admin_or_owner": "(rule:admin_required and domain_id:%(target.token.user.domain.id)s) or rule:owner",
+ "admin_and_matching_domain_id": "rule:admin_required and domain_id:%(domain_id)s",
+ "service_admin_or_owner": "rule:service_or_admin or rule:owner",
+
+ "default": "rule:admin_required",
+
+ "identity:get_region": "",
+ "identity:list_regions": "",
+ "identity:create_region": "rule:cloud_admin",
+ "identity:update_region": "rule:cloud_admin",
+ "identity:delete_region": "rule:cloud_admin",
+
+ "identity:get_service": "rule:admin_required",
+ "identity:list_services": "rule:admin_required",
+ "identity:create_service": "rule:cloud_admin",
+ "identity:update_service": "rule:cloud_admin",
+ "identity:delete_service": "rule:cloud_admin",
+
+ "identity:get_endpoint": "rule:admin_required",
+ "identity:list_endpoints": "rule:admin_required",
+ "identity:create_endpoint": "rule:cloud_admin",
+ "identity:update_endpoint": "rule:cloud_admin",
+ "identity:delete_endpoint": "rule:cloud_admin",
+
+ "identity:get_registered_limit": "",
+ "identity:list_registered_limits": "",
+ "identity:create_registered_limits": "rule:admin_required",
+ "identity:update_registered_limits": "rule:admin_required",
+ "identity:delete_registered_limit": "rule:admin_required",
+
+ "identity:get_limit": "",
+ "identity:list_limits": "",
+ "identity:create_limits": "rule:admin_required",
+ "identity:update_limits": "rule:admin_required",
+ "identity:delete_limit": "rule:admin_required",
+
+ "identity:get_domain": "rule:cloud_admin or rule:admin_and_matching_domain_id or token.project.domain.id:%(target.domain.id)s",
+ "identity:list_domains": "rule:cloud_admin",
+ "identity:create_domain": "rule:cloud_admin",
+ "identity:update_domain": "rule:cloud_admin",
+ "identity:delete_domain": "rule:cloud_admin",
+
+ "admin_and_matching_target_project_domain_id": "rule:admin_required and domain_id:%(target.project.domain_id)s",
+ "admin_and_matching_project_domain_id": "rule:admin_required and domain_id:%(project.domain_id)s",
+ "identity:get_project": "rule:cloud_admin or rule:admin_and_matching_target_project_domain_id or project_id:%(target.project.id)s",
+ "identity:list_projects": "rule:cloud_admin or rule:admin_and_matching_domain_id",
+ "identity:list_user_projects": "rule:owner or rule:admin_and_matching_domain_id",
+ "identity:create_project": "rule:cloud_admin or rule:admin_and_matching_project_domain_id",
+ "identity:update_project": "rule:cloud_admin or rule:admin_and_matching_target_project_domain_id",
+ "identity:delete_project": "rule:cloud_admin or rule:admin_and_matching_target_project_domain_id",
+ "identity:create_project_tag": "rule:admin_required",
+ "identity:delete_project_tag": "rule:admin_required",
+ "identity:get_project_tag": "rule:admin_required",
+ "identity:list_project_tags": "rule:admin_required",
+ "identity:delete_project_tags": "rule:admin_required",
+ "identity:update_project_tags": "rule:admin_required",
+
+ "admin_and_matching_target_user_domain_id": "rule:admin_required and domain_id:%(target.user.domain_id)s",
+ "admin_and_matching_user_domain_id": "rule:admin_required and domain_id:%(user.domain_id)s",
+ "identity:get_user": "rule:cloud_admin or rule:admin_and_matching_target_user_domain_id or rule:owner",
+ "identity:list_users": "rule:cloud_admin or rule:admin_and_matching_domain_id",
+ "identity:create_user": "rule:cloud_admin or rule:admin_and_matching_user_domain_id",
+ "identity:update_user": "rule:cloud_admin or rule:admin_and_matching_target_user_domain_id",
+ "identity:delete_user": "rule:cloud_admin or rule:admin_and_matching_target_user_domain_id",
+
+ "admin_and_matching_target_group_domain_id": "rule:admin_required and domain_id:%(target.group.domain_id)s",
+ "admin_and_matching_group_domain_id": "rule:admin_required and domain_id:%(group.domain_id)s",
+ "identity:get_group": "rule:cloud_admin or rule:admin_and_matching_target_group_domain_id",
+ "identity:list_groups": "rule:cloud_admin or rule:admin_and_matching_domain_id",
+ "identity:list_groups_for_user": "rule:owner or rule:admin_and_matching_target_user_domain_id",
+ "identity:create_group": "rule:cloud_admin or rule:admin_and_matching_group_domain_id",
+ "identity:update_group": "rule:cloud_admin or rule:admin_and_matching_target_group_domain_id",
+ "identity:delete_group": "rule:cloud_admin or rule:admin_and_matching_target_group_domain_id",
+ "identity:list_users_in_group": "rule:cloud_admin or rule:admin_and_matching_target_group_domain_id",
+ "identity:remove_user_from_group": "rule:cloud_admin or rule:admin_and_matching_target_group_domain_id",
+ "identity:check_user_in_group": "rule:cloud_admin or rule:admin_and_matching_target_group_domain_id",
+ "identity:add_user_to_group": "rule:cloud_admin or rule:admin_and_matching_target_group_domain_id",
+
+ "identity:get_credential": "rule:admin_required",
+ "identity:list_credentials": "rule:admin_required or user_id:%(user_id)s",
+ "identity:create_credential": "rule:admin_required",
+ "identity:update_credential": "rule:admin_required",
+ "identity:delete_credential": "rule:admin_required",
+
+ "identity:ec2_get_credential": "rule:admin_required or (rule:owner and user_id:%(target.credential.user_id)s)",
+ "identity:ec2_list_credentials": "rule:admin_required or rule:owner",
+ "identity:ec2_create_credential": "rule:admin_required or rule:owner",
+ "identity:ec2_delete_credential": "rule:admin_required or (rule:owner and user_id:%(target.credential.user_id)s)",
+
+ "identity:get_role": "rule:admin_required",
+ "identity:list_roles": "rule:admin_required",
+ "identity:create_role": "rule:cloud_admin",
+ "identity:update_role": "rule:cloud_admin",
+ "identity:delete_role": "rule:cloud_admin",
+
+ "identity:get_domain_role": "rule:cloud_admin or rule:get_domain_roles",
+ "identity:list_domain_roles": "rule:cloud_admin or rule:list_domain_roles",
+ "identity:create_domain_role": "rule:cloud_admin or rule:domain_admin_matches_domain_role",
+ "identity:update_domain_role": "rule:cloud_admin or rule:domain_admin_matches_target_domain_role",
+ "identity:delete_domain_role": "rule:cloud_admin or rule:domain_admin_matches_target_domain_role",
+ "domain_admin_matches_domain_role": "rule:admin_required and domain_id:%(role.domain_id)s",
+ "get_domain_roles": "rule:domain_admin_matches_target_domain_role or rule:project_admin_matches_target_domain_role",
+ "domain_admin_matches_target_domain_role": "rule:admin_required and domain_id:%(target.role.domain_id)s",
+ "project_admin_matches_target_domain_role": "rule:admin_required and project_domain_id:%(target.role.domain_id)s",
+ "list_domain_roles": "rule:domain_admin_matches_filter_on_list_domain_roles or rule:project_admin_matches_filter_on_list_domain_roles",
+ "domain_admin_matches_filter_on_list_domain_roles": "rule:admin_required and domain_id:%(domain_id)s",
+ "project_admin_matches_filter_on_list_domain_roles": "rule:admin_required and project_domain_id:%(domain_id)s",
+ "admin_and_matching_prior_role_domain_id": "rule:admin_required and domain_id:%(target.prior_role.domain_id)s",
+ "implied_role_matches_prior_role_domain_or_global": "(domain_id:%(target.implied_role.domain_id)s or None:%(target.implied_role.domain_id)s)",
+
+ "identity:get_implied_role": "rule:cloud_admin or rule:admin_and_matching_prior_role_domain_id",
+ "identity:list_implied_roles": "rule:cloud_admin or rule:admin_and_matching_prior_role_domain_id",
+ "identity:create_implied_role": "rule:cloud_admin or (rule:admin_and_matching_prior_role_domain_id and rule:implied_role_matches_prior_role_domain_or_global)",
+ "identity:delete_implied_role": "rule:cloud_admin or rule:admin_and_matching_prior_role_domain_id",
+ "identity:list_role_inference_rules": "rule:cloud_admin",
+ "identity:check_implied_role": "rule:cloud_admin or rule:admin_and_matching_prior_role_domain_id",
+
+ "identity:list_system_grants_for_user": "rule:admin_required",
+ "identity:check_system_grant_for_user": "rule:admin_required",
+ "identity:create_system_grant_for_user": "rule:admin_required",
+ "identity:revoke_system_grant_for_user": "rule:admin_required",
+
+ "identity:list_system_grants_for_group": "rule:admin_required",
+ "identity:check_system_grant_for_group": "rule:admin_required",
+ "identity:create_system_grant_for_group": "rule:admin_required",
+ "identity:revoke_system_grant_for_group": "rule:admin_required",
+
+ "identity:check_grant": "rule:cloud_admin or rule:domain_admin_for_grants or rule:project_admin_for_grants",
+ "identity:list_grants": "rule:cloud_admin or rule:domain_admin_for_list_grants or rule:project_admin_for_list_grants",
+ "identity:create_grant": "rule:cloud_admin or rule:domain_admin_for_grants or rule:project_admin_for_grants",
+ "identity:revoke_grant": "rule:cloud_admin or rule:domain_admin_for_grants or rule:project_admin_for_grants",
+ "domain_admin_for_grants": "rule:domain_admin_for_global_role_grants or rule:domain_admin_for_domain_role_grants",
+ "domain_admin_for_global_role_grants": "rule:admin_required and None:%(target.role.domain_id)s and rule:domain_admin_grant_match",
+ "domain_admin_for_domain_role_grants": "rule:admin_required and domain_id:%(target.role.domain_id)s and rule:domain_admin_grant_match",
+ "domain_admin_grant_match": "domain_id:%(domain_id)s or domain_id:%(target.project.domain_id)s",
+ "project_admin_for_grants": "rule:project_admin_for_global_role_grants or rule:project_admin_for_domain_role_grants",
+ "project_admin_for_global_role_grants": "rule:admin_required and None:%(target.role.domain_id)s and project_id:%(project_id)s",
+ "project_admin_for_domain_role_grants": "rule:admin_required and project_domain_id:%(target.role.domain_id)s and project_id:%(project_id)s",
+ "domain_admin_for_list_grants": "rule:admin_required and rule:domain_admin_grant_match",
+ "project_admin_for_list_grants": "rule:admin_required and project_id:%(project_id)s",
+
+ "admin_on_domain_filter": "rule:admin_required and domain_id:%(scope.domain.id)s",
+ "admin_on_project_filter": "rule:admin_required and project_id:%(scope.project.id)s",
+ "admin_on_domain_of_project_filter": "rule:admin_required and domain_id:%(target.project.domain_id)s",
+ "identity:list_role_assignments": "rule:cloud_admin or rule:admin_on_domain_filter or rule:admin_on_project_filter",
+ "identity:list_role_assignments_for_tree": "rule:cloud_admin or rule:admin_on_domain_of_project_filter",
+ "identity:get_policy": "rule:cloud_admin",
+ "identity:list_policies": "rule:cloud_admin",
+ "identity:create_policy": "rule:cloud_admin",
+ "identity:update_policy": "rule:cloud_admin",
+ "identity:delete_policy": "rule:cloud_admin",
+
+ "identity:check_token": "rule:admin_or_owner",
+ "identity:validate_token": "rule:service_admin_or_owner",
+ "identity:validate_token_head": "rule:service_or_admin",
+ "identity:revocation_list": "rule:service_or_admin",
+ "identity:revoke_token": "rule:admin_or_owner",
+
+ "identity:create_trust": "user_id:%(trust.trustor_user_id)s",
+ "identity:list_trusts": "",
+ "identity:list_roles_for_trust": "",
+ "identity:get_role_for_trust": "",
+ "identity:delete_trust": "",
+ "identity:get_trust": "",
+
+ "identity:create_consumer": "rule:admin_required",
+ "identity:get_consumer": "rule:admin_required",
+ "identity:list_consumers": "rule:admin_required",
+ "identity:delete_consumer": "rule:admin_required",
+ "identity:update_consumer": "rule:admin_required",
+
+ "identity:authorize_request_token": "rule:admin_required",
+ "identity:list_access_token_roles": "rule:admin_required",
+ "identity:get_access_token_role": "rule:admin_required",
+ "identity:list_access_tokens": "rule:admin_required",
+ "identity:get_access_token": "rule:admin_required",
+ "identity:delete_access_token": "rule:admin_required",
+
+ "identity:list_projects_for_endpoint": "rule:admin_required",
+ "identity:add_endpoint_to_project": "rule:admin_required",
+ "identity:check_endpoint_in_project": "rule:admin_required",
+ "identity:list_endpoints_for_project": "rule:admin_required",
+ "identity:remove_endpoint_from_project": "rule:admin_required",
+
+ "identity:create_endpoint_group": "rule:admin_required",
+ "identity:list_endpoint_groups": "rule:admin_required",
+ "identity:get_endpoint_group": "rule:admin_required",
+ "identity:update_endpoint_group": "rule:admin_required",
+ "identity:delete_endpoint_group": "rule:admin_required",
+ "identity:list_projects_associated_with_endpoint_group": "rule:admin_required",
+ "identity:list_endpoints_associated_with_endpoint_group": "rule:admin_required",
+ "identity:get_endpoint_group_in_project": "rule:admin_required",
+ "identity:list_endpoint_groups_for_project": "rule:admin_required",
+ "identity:add_endpoint_group_to_project": "rule:admin_required",
+ "identity:remove_endpoint_group_from_project": "rule:admin_required",
+
+ "identity:create_identity_provider": "rule:cloud_admin",
+ "identity:list_identity_providers": "rule:cloud_admin",
+ "identity:get_identity_provider": "rule:cloud_admin",
+ "identity:update_identity_provider": "rule:cloud_admin",
+ "identity:delete_identity_provider": "rule:cloud_admin",
+
+ "identity:create_protocol": "rule:cloud_admin",
+ "identity:update_protocol": "rule:cloud_admin",
+ "identity:get_protocol": "rule:cloud_admin",
+ "identity:list_protocols": "rule:cloud_admin",
+ "identity:delete_protocol": "rule:cloud_admin",
+
+ "identity:create_mapping": "rule:cloud_admin",
+ "identity:get_mapping": "rule:cloud_admin",
+ "identity:list_mappings": "rule:cloud_admin",
+ "identity:delete_mapping": "rule:cloud_admin",
+ "identity:update_mapping": "rule:cloud_admin",
+
+ "identity:create_service_provider": "rule:cloud_admin",
+ "identity:list_service_providers": "rule:cloud_admin",
+ "identity:get_service_provider": "rule:cloud_admin",
+ "identity:update_service_provider": "rule:cloud_admin",
+ "identity:delete_service_provider": "rule:cloud_admin",
+
+ "identity:get_auth_catalog": "",
+ "identity:get_auth_projects": "",
+ "identity:get_auth_domains": "",
+ "identity:get_auth_system": "",
+
+ "identity:list_projects_for_user": "",
+ "identity:list_domains_for_user": "",
+
+ "identity:list_revoke_events": "rule:service_or_admin",
+
+ "identity:create_policy_association_for_endpoint": "rule:cloud_admin",
+ "identity:check_policy_association_for_endpoint": "rule:cloud_admin",
+ "identity:delete_policy_association_for_endpoint": "rule:cloud_admin",
+ "identity:create_policy_association_for_service": "rule:cloud_admin",
+ "identity:check_policy_association_for_service": "rule:cloud_admin",
+ "identity:delete_policy_association_for_service": "rule:cloud_admin",
+ "identity:create_policy_association_for_region_and_service": "rule:cloud_admin",
+ "identity:check_policy_association_for_region_and_service": "rule:cloud_admin",
+ "identity:delete_policy_association_for_region_and_service": "rule:cloud_admin",
+ "identity:get_policy_for_endpoint": "rule:cloud_admin",
+ "identity:list_endpoints_for_policy": "rule:cloud_admin",
+
+ "identity:create_domain_config": "rule:cloud_admin",
+ "identity:get_domain_config": "rule:cloud_admin",
+ "identity:get_security_compliance_domain_config": "",
+ "identity:update_domain_config": "rule:cloud_admin",
+ "identity:delete_domain_config": "rule:cloud_admin",
+ "identity:get_domain_config_default": "rule:cloud_admin",
+
+ "identity:get_application_credential": "rule:admin_or_owner",
+ "identity:list_application_credentials": "rule:admin_or_owner",
+ "identity:create_application_credential": "rule:admin_or_owner",
+ "identity:delete_application_credential": "rule:admin_or_owner"
+}
diff --git a/tools/policies/policy.json.d/neutron.policy.json b/tools/policies/policy.json.d/neutron.policy.json
new file mode 100644
index 00000000..15f17203
--- /dev/null
+++ b/tools/policies/policy.json.d/neutron.policy.json
@@ -0,0 +1,235 @@
+{
+ "context_is_admin": "role:admin or user_name:neutron",
+ "owner": "tenant_id:%(tenant_id)s",
+ "admin_or_owner": "rule:context_is_admin or rule:owner",
+ "context_is_advsvc": "role:advsvc",
+ "admin_or_network_owner": "rule:context_is_admin or tenant_id:%(network:tenant_id)s",
+ "admin_owner_or_network_owner": "rule:owner or rule:admin_or_network_owner",
+ "admin_only": "rule:context_is_admin",
+ "regular_user": "",
+ "admin_or_data_plane_int": "rule:context_is_admin or role:data_plane_integrator",
+ "shared": "field:networks:shared=True",
+ "shared_subnetpools": "field:subnetpools:shared=True",
+ "shared_address_scopes": "field:address_scopes:shared=True",
+ "external": "field:networks:router:external=True",
+ "default": "rule:admin_or_owner",
+
+ "create_subnet": "rule:admin_or_network_owner",
+ "create_subnet:segment_id": "rule:admin_only",
+ "create_subnet:service_types": "rule:admin_only",
+ "get_subnet": "rule:admin_or_owner or rule:shared",
+ "get_subnet:segment_id": "rule:admin_only",
+ "update_subnet": "rule:admin_or_network_owner",
+ "update_subnet:service_types": "rule:admin_only",
+ "delete_subnet": "rule:admin_or_network_owner",
+
+ "create_subnetpool": "",
+ "create_subnetpool:shared": "rule:admin_only",
+ "create_subnetpool:is_default": "rule:admin_only",
+ "get_subnetpool": "rule:admin_or_owner or rule:shared_subnetpools",
+ "update_subnetpool": "rule:admin_or_owner",
+ "update_subnetpool:is_default": "rule:admin_only",
+ "delete_subnetpool": "rule:admin_or_owner",
+
+ "create_address_scope": "",
+ "create_address_scope:shared": "rule:admin_only",
+ "get_address_scope": "rule:admin_or_owner or rule:shared_address_scopes",
+ "update_address_scope": "rule:admin_or_owner",
+ "update_address_scope:shared": "rule:admin_only",
+ "delete_address_scope": "rule:admin_or_owner",
+
+ "create_network": "",
+ "get_network": "rule:admin_or_owner or rule:shared or rule:external or rule:context_is_advsvc",
+ "get_network:router:external": "rule:regular_user",
+ "get_network:segments": "rule:admin_only",
+ "get_network:provider:network_type": "rule:admin_only",
+ "get_network:provider:physical_network": "rule:admin_only",
+ "get_network:provider:segmentation_id": "rule:admin_only",
+ "get_network:queue_id": "rule:admin_only",
+ "get_network_ip_availabilities": "rule:admin_only",
+ "get_network_ip_availability": "rule:admin_only",
+ "create_network:shared": "rule:admin_only",
+ "create_network:router:external": "rule:admin_only",
+ "create_network:is_default": "rule:admin_only",
+ "create_network:segments": "rule:admin_only",
+ "create_network:provider:network_type": "rule:admin_only",
+ "create_network:provider:physical_network": "rule:admin_only",
+ "create_network:provider:segmentation_id": "rule:admin_only",
+ "update_network": "rule:admin_or_owner",
+ "update_network:segments": "rule:admin_only",
+ "update_network:shared": "rule:admin_only",
+ "update_network:provider:network_type": "rule:admin_only",
+ "update_network:provider:physical_network": "rule:admin_only",
+ "update_network:provider:segmentation_id": "rule:admin_only",
+ "update_network:router:external": "rule:admin_only",
+ "delete_network": "rule:admin_or_owner",
+
+ "create_segment": "rule:admin_only",
+ "get_segment": "rule:admin_only",
+ "update_segment": "rule:admin_only",
+ "delete_segment": "rule:admin_only",
+
+ "network_device": "field:port:device_owner=~^network:",
+ "create_port": "",
+ "create_port:device_owner": "not rule:network_device or rule:context_is_advsvc or rule:admin_or_network_owner",
+ "create_port:mac_address": "rule:context_is_advsvc or rule:admin_or_network_owner",
+ "create_port:fixed_ips:ip_address": "rule:context_is_advsvc or rule:admin_or_network_owner",
+ "create_port:fixed_ips:subnet_id": "rule:context_is_advsvc or rule:admin_or_network_owner or rule:shared",
+ "create_port:port_security_enabled": "rule:context_is_advsvc or rule:admin_or_network_owner",
+ "create_port:binding:host_id": "rule:admin_only",
+ "create_port:binding:profile": "rule:admin_only",
+ "create_port:mac_learning_enabled": "rule:context_is_advsvc or rule:admin_or_network_owner",
+ "create_port:allowed_address_pairs": "rule:admin_or_network_owner",
+ "get_port": "rule:context_is_advsvc or rule:admin_owner_or_network_owner",
+ "get_port:queue_id": "rule:admin_only",
+ "get_port:binding:vif_type": "rule:admin_only",
+ "get_port:binding:vif_details": "rule:admin_only",
+ "get_port:binding:host_id": "rule:admin_only",
+ "get_port:binding:profile": "rule:admin_only",
+ "update_port": "rule:admin_or_owner or rule:context_is_advsvc",
+ "update_port:device_owner": "not rule:network_device or rule:context_is_advsvc or rule:admin_or_network_owner",
+ "update_port:mac_address": "rule:admin_only or rule:context_is_advsvc",
+ "update_port:fixed_ips:ip_address": "rule:context_is_advsvc or rule:admin_or_network_owner",
+ "update_port:fixed_ips:subnet_id": "rule:context_is_advsvc or rule:admin_or_network_owner or rule:shared",
+ "update_port:port_security_enabled": "rule:context_is_advsvc or rule:admin_or_network_owner",
+ "update_port:binding:host_id": "rule:admin_only",
+ "update_port:binding:profile": "rule:admin_only",
+ "update_port:mac_learning_enabled": "rule:context_is_advsvc or rule:admin_or_network_owner",
+ "update_port:allowed_address_pairs": "rule:admin_or_network_owner",
+ "update_port:data_plane_status": "rule:admin_or_data_plane_int",
+ "delete_port": "rule:context_is_advsvc or rule:admin_owner_or_network_owner",
+
+ "get_router:ha": "rule:admin_only",
+ "create_router": "rule:regular_user",
+ "create_router:external_gateway_info:enable_snat": "rule:admin_only",
+ "create_router:distributed": "rule:admin_only",
+ "create_router:ha": "rule:admin_only",
+ "get_router": "http://192.168.1.50:31002/wrapper/authz/grant",
+ "get_router:distributed": "rule:admin_only",
+ "update_router": "rule:admin_or_owner",
+ "update_router:external_gateway_info": "rule:admin_or_owner",
+ "update_router:external_gateway_info:network_id": "rule:admin_or_owner",
+ "update_router:external_gateway_info:enable_snat": "rule:admin_only",
+ "update_router:distributed": "rule:admin_only",
+ "update_router:ha": "rule:admin_only",
+ "delete_router": "rule:admin_or_owner",
+
+ "add_router_interface": "rule:admin_or_owner",
+ "remove_router_interface": "rule:admin_or_owner",
+
+ "create_router:external_gateway_info:external_fixed_ips": "rule:admin_only",
+ "update_router:external_gateway_info:external_fixed_ips": "rule:admin_only",
+
+ "create_qos_queue": "rule:admin_only",
+ "get_qos_queue": "rule:admin_only",
+
+ "update_agent": "rule:admin_only",
+ "delete_agent": "rule:admin_only",
+ "get_agent": "rule:admin_only",
+
+ "create_dhcp-network": "rule:admin_only",
+ "delete_dhcp-network": "rule:admin_only",
+ "get_dhcp-networks": "rule:admin_only",
+ "create_l3-router": "rule:admin_only",
+ "delete_l3-router": "rule:admin_only",
+ "get_l3-routers": "rule:admin_only",
+ "get_dhcp-agents": "rule:admin_only",
+ "get_l3-agents": "rule:admin_only",
+ "get_loadbalancer-agent": "rule:admin_only",
+ "get_loadbalancer-pools": "rule:admin_only",
+ "get_agent-loadbalancers": "rule:admin_only",
+ "get_loadbalancer-hosting-agent": "rule:admin_only",
+
+ "create_floatingip": "rule:regular_user",
+ "create_floatingip:floating_ip_address": "rule:admin_only",
+ "update_floatingip": "rule:admin_or_owner",
+ "delete_floatingip": "rule:admin_or_owner",
+ "get_floatingip": "rule:admin_or_owner",
+
+ "create_network_profile": "rule:admin_only",
+ "update_network_profile": "rule:admin_only",
+ "delete_network_profile": "rule:admin_only",
+ "get_network_profiles": "",
+ "get_network_profile": "",
+ "update_policy_profiles": "rule:admin_only",
+ "get_policy_profiles": "",
+ "get_policy_profile": "",
+
+ "create_metering_label": "rule:admin_only",
+ "delete_metering_label": "rule:admin_only",
+ "get_metering_label": "rule:admin_only",
+
+ "create_metering_label_rule": "rule:admin_only",
+ "delete_metering_label_rule": "rule:admin_only",
+ "get_metering_label_rule": "rule:admin_only",
+
+ "get_service_provider": "rule:regular_user",
+ "get_lsn": "rule:admin_only",
+ "create_lsn": "rule:admin_only",
+
+ "create_flavor": "rule:admin_only",
+ "update_flavor": "rule:admin_only",
+ "delete_flavor": "rule:admin_only",
+ "get_flavors": "rule:regular_user",
+ "get_flavor": "rule:regular_user",
+ "create_service_profile": "rule:admin_only",
+ "update_service_profile": "rule:admin_only",
+ "delete_service_profile": "rule:admin_only",
+ "get_service_profiles": "rule:admin_only",
+ "get_service_profile": "rule:admin_only",
+
+ "get_policy": "rule:regular_user",
+ "create_policy": "rule:admin_only",
+ "update_policy": "rule:admin_only",
+ "delete_policy": "rule:admin_only",
+ "get_policy_bandwidth_limit_rule": "rule:regular_user",
+ "create_policy_bandwidth_limit_rule": "rule:admin_only",
+ "delete_policy_bandwidth_limit_rule": "rule:admin_only",
+ "update_policy_bandwidth_limit_rule": "rule:admin_only",
+ "get_policy_dscp_marking_rule": "rule:regular_user",
+ "create_policy_dscp_marking_rule": "rule:admin_only",
+ "delete_policy_dscp_marking_rule": "rule:admin_only",
+ "update_policy_dscp_marking_rule": "rule:admin_only",
+ "get_rule_type": "rule:regular_user",
+ "get_policy_minimum_bandwidth_rule": "rule:regular_user",
+ "create_policy_minimum_bandwidth_rule": "rule:admin_only",
+ "delete_policy_minimum_bandwidth_rule": "rule:admin_only",
+ "update_policy_minimum_bandwidth_rule": "rule:admin_only",
+
+ "restrict_wildcard": "(not field:rbac_policy:target_tenant=*) or rule:admin_only",
+ "create_rbac_policy": "",
+ "create_rbac_policy:target_tenant": "rule:restrict_wildcard",
+ "update_rbac_policy": "rule:admin_or_owner",
+ "update_rbac_policy:target_tenant": "rule:restrict_wildcard and rule:admin_or_owner",
+ "get_rbac_policy": "rule:admin_or_owner",
+ "delete_rbac_policy": "rule:admin_or_owner",
+
+ "create_flavor_service_profile": "rule:admin_only",
+ "delete_flavor_service_profile": "rule:admin_only",
+ "get_flavor_service_profile": "rule:regular_user",
+ "get_auto_allocated_topology": "rule:admin_or_owner",
+
+ "create_trunk": "rule:regular_user",
+ "get_trunk": "rule:admin_or_owner",
+ "delete_trunk": "rule:admin_or_owner",
+ "get_subports": "",
+ "add_subports": "rule:admin_or_owner",
+ "remove_subports": "rule:admin_or_owner",
+
+ "get_security_groups": "rule:admin_or_owner",
+ "get_security_group": "rule:admin_or_owner",
+ "create_security_group": "rule:admin_or_owner",
+ "update_security_group": "rule:admin_or_owner",
+ "delete_security_group": "rule:admin_or_owner",
+ "get_security_group_rules": "rule:admin_or_owner",
+ "get_security_group_rule": "rule:admin_or_owner",
+ "create_security_group_rule": "rule:admin_or_owner",
+ "delete_security_group_rule": "rule:admin_or_owner",
+
+ "get_loggable_resources": "rule:admin_only",
+ "create_log": "rule:admin_only",
+ "update_log": "rule:admin_only",
+ "delete_log": "rule:admin_only",
+ "get_logs": "rule:admin_only",
+ "get_log": "rule:admin_only"
+}
diff --git a/tools/policies/policy.json.d/nova.policy.json b/tools/policies/policy.json.d/nova.policy.json
new file mode 100644
index 00000000..da8f5740
--- /dev/null
+++ b/tools/policies/policy.json.d/nova.policy.json
@@ -0,0 +1,485 @@
+{
+ "context_is_admin": "role:admin",
+ "admin_or_owner": "is_admin:True or project_id:%(project_id)s",
+ "default": "rule:admin_or_owner",
+
+ "cells_scheduler_filter:TargetCellFilter": "is_admin:True",
+
+ "compute:create": "",
+ "compute:create:attach_network": "",
+ "compute:create:attach_volume": "",
+ "compute:create:forced_host": "is_admin:True",
+
+ "compute:get": "",
+ "compute:get_all": "",
+ "compute:get_all_tenants": "is_admin:True",
+
+ "compute:update": "",
+
+ "compute:get_instance_metadata": "",
+ "compute:get_all_instance_metadata": "",
+ "compute:get_all_instance_system_metadata": "",
+ "compute:update_instance_metadata": "",
+ "compute:delete_instance_metadata": "",
+
+ "compute:get_instance_faults": "",
+ "compute:get_diagnostics": "",
+ "compute:get_instance_diagnostics": "",
+
+ "compute:start": "rule:admin_or_owner",
+ "compute:stop": "rule:admin_or_owner",
+
+ "compute:get_lock": "",
+ "compute:lock": "rule:admin_or_owner",
+ "compute:unlock": "rule:admin_or_owner",
+ "compute:unlock_override": "rule:admin_api",
+
+ "compute:get_vnc_console": "",
+ "compute:get_spice_console": "",
+ "compute:get_rdp_console": "",
+ "compute:get_serial_console": "",
+ "compute:get_mks_console": "",
+ "compute:get_console_output": "",
+
+ "compute:reset_network": "",
+ "compute:inject_network_info": "",
+ "compute:add_fixed_ip": "",
+ "compute:remove_fixed_ip": "",
+
+ "compute:attach_volume": "",
+ "compute:detach_volume": "",
+ "compute:swap_volume": "",
+
+ "compute:attach_interface": "",
+ "compute:detach_interface": "",
+
+ "compute:set_admin_password": "",
+
+ "compute:rescue": "",
+ "compute:unrescue": "",
+
+ "compute:suspend": "",
+ "compute:resume": "",
+
+ "compute:pause": "",
+ "compute:unpause": "",
+
+ "compute:shelve": "",
+ "compute:shelve_offload": "",
+ "compute:unshelve": "",
+
+ "compute:snapshot": "",
+ "compute:snapshot_volume_backed": "",
+ "compute:backup": "",
+
+ "compute:resize": "",
+ "compute:confirm_resize": "",
+ "compute:revert_resize": "",
+
+ "compute:rebuild": "",
+ "compute:reboot": "",
+ "compute:delete": "rule:admin_or_owner",
+ "compute:soft_delete": "rule:admin_or_owner",
+ "compute:force_delete": "rule:admin_or_owner",
+
+ "compute:security_groups:add_to_instance": "",
+ "compute:security_groups:remove_from_instance": "",
+
+ "compute:restore": "",
+
+ "compute:volume_snapshot_create": "",
+ "compute:volume_snapshot_delete": "",
+
+ "admin_api": "is_admin:True",
+ "compute_extension:accounts": "rule:admin_api",
+ "compute_extension:admin_actions": "rule:admin_api",
+ "compute_extension:admin_actions:pause": "rule:admin_or_owner",
+ "compute_extension:admin_actions:unpause": "rule:admin_or_owner",
+ "compute_extension:admin_actions:suspend": "rule:admin_or_owner",
+ "compute_extension:admin_actions:resume": "rule:admin_or_owner",
+ "compute_extension:admin_actions:lock": "rule:admin_or_owner",
+ "compute_extension:admin_actions:unlock": "rule:admin_or_owner",
+ "compute_extension:admin_actions:resetNetwork": "rule:admin_api",
+ "compute_extension:admin_actions:injectNetworkInfo": "rule:admin_api",
+ "compute_extension:admin_actions:createBackup": "rule:admin_or_owner",
+ "compute_extension:admin_actions:migrateLive": "rule:admin_api",
+ "compute_extension:admin_actions:resetState": "rule:admin_api",
+ "compute_extension:admin_actions:migrate": "rule:admin_api",
+ "compute_extension:aggregates": "rule:admin_api",
+ "compute_extension:agents": "rule:admin_api",
+ "compute_extension:attach_interfaces": "",
+ "compute_extension:baremetal_nodes": "rule:admin_api",
+ "compute_extension:cells": "rule:admin_api",
+ "compute_extension:cells:create": "rule:admin_api",
+ "compute_extension:cells:delete": "rule:admin_api",
+ "compute_extension:cells:update": "rule:admin_api",
+ "compute_extension:cells:sync_instances": "rule:admin_api",
+ "compute_extension:certificates": "",
+ "compute_extension:cloudpipe": "rule:admin_api",
+ "compute_extension:cloudpipe_update": "rule:admin_api",
+ "compute_extension:config_drive": "",
+ "compute_extension:console_output": "",
+ "compute_extension:consoles": "",
+ "compute_extension:createserverext": "",
+ "compute_extension:deferred_delete": "",
+ "compute_extension:disk_config": "",
+ "compute_extension:evacuate": "rule:admin_api",
+ "compute_extension:extended_server_attributes": "rule:admin_api",
+ "compute_extension:extended_status": "",
+ "compute_extension:extended_availability_zone": "",
+ "compute_extension:extended_ips": "",
+ "compute_extension:extended_ips_mac": "",
+ "compute_extension:extended_vif_net": "",
+ "compute_extension:extended_volumes": "",
+ "compute_extension:fixed_ips": "rule:admin_api",
+ "compute_extension:flavor_access": "",
+ "compute_extension:flavor_access:addTenantAccess": "rule:admin_api",
+ "compute_extension:flavor_access:removeTenantAccess": "rule:admin_api",
+ "compute_extension:flavor_disabled": "",
+ "compute_extension:flavor_rxtx": "",
+ "compute_extension:flavor_swap": "",
+ "compute_extension:flavorextradata": "",
+ "compute_extension:flavorextraspecs:index": "",
+ "compute_extension:flavorextraspecs:show": "",
+ "compute_extension:flavorextraspecs:create": "rule:admin_api",
+ "compute_extension:flavorextraspecs:update": "rule:admin_api",
+ "compute_extension:flavorextraspecs:delete": "rule:admin_api",
+ "compute_extension:flavormanage": "rule:admin_api",
+ "compute_extension:floating_ip_dns": "",
+ "compute_extension:floating_ip_pools": "",
+ "compute_extension:floating_ips": "",
+ "compute_extension:floating_ips_bulk": "rule:admin_api",
+ "compute_extension:fping": "",
+ "compute_extension:fping:all_tenants": "rule:admin_api",
+ "compute_extension:hide_server_addresses": "is_admin:False",
+ "compute_extension:hosts": "rule:admin_api",
+ "compute_extension:hypervisors": "rule:admin_api",
+ "compute_extension:image_size": "",
+ "compute_extension:instance_actions": "",
+ "compute_extension:instance_actions:events": "rule:admin_api",
+ "compute_extension:instance_usage_audit_log": "rule:admin_api",
+ "compute_extension:keypairs": "",
+ "compute_extension:keypairs:index": "",
+ "compute_extension:keypairs:show": "",
+ "compute_extension:keypairs:create": "",
+ "compute_extension:keypairs:delete": "",
+ "compute_extension:multinic": "",
+ "compute_extension:networks": "rule:admin_api",
+ "compute_extension:networks:view": "",
+ "compute_extension:networks_associate": "rule:admin_api",
+ "compute_extension:os-tenant-networks": "",
+ "compute_extension:quotas:show": "",
+ "compute_extension:quotas:update": "rule:admin_api",
+ "compute_extension:quotas:delete": "rule:admin_api",
+ "compute_extension:quota_classes": "",
+ "compute_extension:rescue": "",
+ "compute_extension:security_group_default_rules": "rule:admin_api",
+ "compute_extension:security_groups": "",
+ "compute_extension:server_diagnostics": "rule:admin_api",
+ "compute_extension:server_groups": "",
+ "compute_extension:server_password": "",
+ "compute_extension:server_usage": "",
+ "compute_extension:services": "rule:admin_api",
+ "compute_extension:shelve": "",
+ "compute_extension:shelveOffload": "rule:admin_api",
+ "compute_extension:simple_tenant_usage:show": "rule:admin_or_owner",
+ "compute_extension:simple_tenant_usage:list": "rule:admin_api",
+ "compute_extension:unshelve": "",
+ "compute_extension:users": "rule:admin_api",
+ "compute_extension:virtual_interfaces": "",
+ "compute_extension:virtual_storage_arrays": "",
+ "compute_extension:volumes": "",
+ "compute_extension:volume_attachments:index": "",
+ "compute_extension:volume_attachments:show": "",
+ "compute_extension:volume_attachments:create": "",
+ "compute_extension:volume_attachments:update": "",
+ "compute_extension:volume_attachments:delete": "",
+ "compute_extension:volumetypes": "",
+ "compute_extension:availability_zone:list": "",
+ "compute_extension:availability_zone:detail": "rule:admin_api",
+ "compute_extension:used_limits_for_admin": "rule:admin_api",
+ "compute_extension:migrations:index": "rule:admin_api",
+ "compute_extension:os-assisted-volume-snapshots:create": "rule:admin_api",
+ "compute_extension:os-assisted-volume-snapshots:delete": "rule:admin_api",
+ "compute_extension:console_auth_tokens": "rule:admin_api",
+ "compute_extension:os-server-external-events:create": "rule:admin_api",
+
+ "network:get_all": "",
+ "network:get": "",
+ "network:create": "",
+ "network:delete": "",
+ "network:associate": "",
+ "network:disassociate": "",
+ "network:get_vifs_by_instance": "",
+ "network:allocate_for_instance": "",
+ "network:deallocate_for_instance": "",
+ "network:validate_networks": "",
+ "network:get_instance_uuids_by_ip_filter": "",
+ "network:get_instance_id_by_floating_address": "",
+ "network:setup_networks_on_host": "",
+ "network:get_backdoor_port": "",
+
+ "network:get_floating_ip": "",
+ "network:get_floating_ip_pools": "",
+ "network:get_floating_ip_by_address": "",
+ "network:get_floating_ips_by_project": "",
+ "network:get_floating_ips_by_fixed_address": "",
+ "network:allocate_floating_ip": "",
+ "network:associate_floating_ip": "",
+ "network:disassociate_floating_ip": "",
+ "network:release_floating_ip": "",
+ "network:migrate_instance_start": "",
+ "network:migrate_instance_finish": "",
+
+ "network:get_fixed_ip": "",
+ "network:get_fixed_ip_by_address": "",
+ "network:add_fixed_ip_to_instance": "",
+ "network:remove_fixed_ip_from_instance": "",
+ "network:add_network_to_project": "",
+ "network:get_instance_nw_info": "",
+
+ "network:get_dns_domains": "",
+ "network:add_dns_entry": "",
+ "network:modify_dns_entry": "",
+ "network:delete_dns_entry": "",
+ "network:get_dns_entries_by_address": "",
+ "network:get_dns_entries_by_name": "",
+ "network:create_private_dns_domain": "",
+ "network:create_public_dns_domain": "",
+ "network:delete_dns_domain": "",
+ "network:attach_external_network": "rule:admin_api",
+ "network:get_vif_by_mac_address": "",
+
+ "os_compute_api:servers:detail:get_all_tenants": "is_admin:True",
+ "os_compute_api:servers:index:get_all_tenants": "is_admin:True",
+ "os_compute_api:servers:confirm_resize": "",
+ "os_compute_api:servers:create": "",
+ "os_compute_api:servers:create:attach_network": "",
+ "os_compute_api:servers:create:attach_volume": "",
+ "os_compute_api:servers:create:forced_host": "rule:admin_api",
+ "os_compute_api:servers:delete": "",
+ "os_compute_api:servers:update": "",
+ "os_compute_api:servers:detail": "",
+ "os_compute_api:servers:index": "",
+ "os_compute_api:servers:reboot": "",
+ "os_compute_api:servers:rebuild": "",
+ "os_compute_api:servers:resize": "",
+ "os_compute_api:servers:revert_resize": "",
+ "os_compute_api:servers:show": "",
+ "os_compute_api:servers:create_image": "",
+ "os_compute_api:servers:create_image:allow_volume_backed": "",
+ "os_compute_api:servers:start": "rule:admin_or_owner",
+ "os_compute_api:servers:stop": "rule:admin_or_owner",
+ "os_compute_api:os-access-ips:discoverable": "",
+ "os_compute_api:os-access-ips": "",
+ "os_compute_api:os-admin-actions": "rule:admin_api",
+ "os_compute_api:os-admin-actions:discoverable": "",
+ "os_compute_api:os-admin-actions:reset_network": "rule:admin_api",
+ "os_compute_api:os-admin-actions:inject_network_info": "rule:admin_api",
+ "os_compute_api:os-admin-actions:reset_state": "rule:admin_api",
+ "os_compute_api:os-admin-password": "",
+ "os_compute_api:os-admin-password:discoverable": "",
+ "os_compute_api:os-aggregates:discoverable": "",
+ "os_compute_api:os-aggregates:index": "rule:admin_api",
+ "os_compute_api:os-aggregates:create": "rule:admin_api",
+ "os_compute_api:os-aggregates:show": "rule:admin_api",
+ "os_compute_api:os-aggregates:update": "rule:admin_api",
+ "os_compute_api:os-aggregates:delete": "rule:admin_api",
+ "os_compute_api:os-aggregates:add_host": "rule:admin_api",
+ "os_compute_api:os-aggregates:remove_host": "rule:admin_api",
+ "os_compute_api:os-aggregates:set_metadata": "rule:admin_api",
+ "os_compute_api:os-agents": "rule:admin_api",
+ "os_compute_api:os-agents:discoverable": "",
+ "os_compute_api:os-attach-interfaces": "",
+ "os_compute_api:os-attach-interfaces:discoverable": "",
+ "os_compute_api:os-baremetal-nodes": "rule:admin_api",
+ "os_compute_api:os-baremetal-nodes:discoverable": "",
+ "os_compute_api:os-block-device-mapping-v1:discoverable": "",
+ "os_compute_api:os-cells": "rule:admin_api",
+ "os_compute_api:os-cells:create": "rule:admin_api",
+ "os_compute_api:os-cells:delete": "rule:admin_api",
+ "os_compute_api:os-cells:update": "rule:admin_api",
+ "os_compute_api:os-cells:sync_instances": "rule:admin_api",
+ "os_compute_api:os-cells:discoverable": "",
+ "os_compute_api:os-certificates:create": "",
+ "os_compute_api:os-certificates:show": "",
+ "os_compute_api:os-certificates:discoverable": "",
+ "os_compute_api:os-cloudpipe": "rule:admin_api",
+ "os_compute_api:os-cloudpipe:discoverable": "",
+ "os_compute_api:os-config-drive": "",
+ "os_compute_api:os-consoles:discoverable": "",
+ "os_compute_api:os-consoles:create": "",
+ "os_compute_api:os-consoles:delete": "",
+ "os_compute_api:os-consoles:index": "",
+ "os_compute_api:os-consoles:show": "",
+ "os_compute_api:os-console-output:discoverable": "",
+ "os_compute_api:os-console-output": "",
+ "os_compute_api:os-remote-consoles": "",
+ "os_compute_api:os-remote-consoles:discoverable": "",
+ "os_compute_api:os-create-backup:discoverable": "",
+ "os_compute_api:os-create-backup": "rule:admin_or_owner",
+ "os_compute_api:os-deferred-delete": "",
+ "os_compute_api:os-deferred-delete:discoverable": "",
+ "os_compute_api:os-disk-config": "",
+ "os_compute_api:os-disk-config:discoverable": "",
+ "os_compute_api:os-evacuate": "rule:admin_api",
+ "os_compute_api:os-evacuate:discoverable": "",
+ "os_compute_api:os-extended-server-attributes": "rule:admin_api",
+ "os_compute_api:os-extended-server-attributes:discoverable": "",
+ "os_compute_api:os-extended-status": "",
+ "os_compute_api:os-extended-status:discoverable": "",
+ "os_compute_api:os-extended-availability-zone": "",
+ "os_compute_api:os-extended-availability-zone:discoverable": "",
+ "os_compute_api:extensions": "",
+ "os_compute_api:extension_info:discoverable": "",
+ "os_compute_api:os-extended-volumes": "",
+ "os_compute_api:os-extended-volumes:discoverable": "",
+ "os_compute_api:os-fixed-ips": "rule:admin_api",
+ "os_compute_api:os-fixed-ips:discoverable": "",
+ "os_compute_api:os-flavor-access": "",
+ "os_compute_api:os-flavor-access:discoverable": "",
+ "os_compute_api:os-flavor-access:remove_tenant_access": "rule:admin_api",
+ "os_compute_api:os-flavor-access:add_tenant_access": "rule:admin_api",
+ "os_compute_api:os-flavor-rxtx": "",
+ "os_compute_api:os-flavor-rxtx:discoverable": "",
+ "os_compute_api:flavors:discoverable": "",
+ "os_compute_api:os-flavor-extra-specs:discoverable": "",
+ "os_compute_api:os-flavor-extra-specs:index": "",
+ "os_compute_api:os-flavor-extra-specs:show": "",
+ "os_compute_api:os-flavor-extra-specs:create": "rule:admin_api",
+ "os_compute_api:os-flavor-extra-specs:update": "rule:admin_api",
+ "os_compute_api:os-flavor-extra-specs:delete": "rule:admin_api",
+ "os_compute_api:os-flavor-manage:discoverable": "",
+ "os_compute_api:os-flavor-manage": "rule:admin_api",
+ "os_compute_api:os-floating-ip-dns": "",
+ "os_compute_api:os-floating-ip-dns:discoverable": "",
+ "os_compute_api:os-floating-ip-dns:domain:update": "rule:admin_api",
+ "os_compute_api:os-floating-ip-dns:domain:delete": "rule:admin_api",
+ "os_compute_api:os-floating-ip-pools": "",
+ "os_compute_api:os-floating-ip-pools:discoverable": "",
+ "os_compute_api:os-floating-ips": "",
+ "os_compute_api:os-floating-ips:discoverable": "",
+ "os_compute_api:os-floating-ips-bulk": "rule:admin_api",
+ "os_compute_api:os-floating-ips-bulk:discoverable": "",
+ "os_compute_api:os-fping": "",
+ "os_compute_api:os-fping:discoverable": "",
+ "os_compute_api:os-fping:all_tenants": "rule:admin_api",
+ "os_compute_api:os-hide-server-addresses": "is_admin:False",
+ "os_compute_api:os-hide-server-addresses:discoverable": "",
+ "os_compute_api:os-hosts": "rule:admin_api",
+ "os_compute_api:os-hosts:discoverable": "",
+ "os_compute_api:os-hypervisors": "rule:admin_api",
+ "os_compute_api:os-hypervisors:discoverable": "",
+ "os_compute_api:images:discoverable": "",
+ "os_compute_api:image-size": "",
+ "os_compute_api:image-size:discoverable": "",
+ "os_compute_api:os-instance-actions": "",
+ "os_compute_api:os-instance-actions:discoverable": "",
+ "os_compute_api:os-instance-actions:events": "rule:admin_api",
+ "os_compute_api:os-instance-usage-audit-log": "rule:admin_api",
+ "os_compute_api:os-instance-usage-audit-log:discoverable": "",
+ "os_compute_api:ips:discoverable": "",
+ "os_compute_api:ips:index": "rule:admin_or_owner",
+ "os_compute_api:ips:show": "rule:admin_or_owner",
+ "os_compute_api:os-keypairs:discoverable": "",
+ "os_compute_api:os-keypairs": "",
+ "os_compute_api:os-keypairs:index": "rule:admin_api or user_id:%(user_id)s",
+ "os_compute_api:os-keypairs:show": "rule:admin_api or user_id:%(user_id)s",
+ "os_compute_api:os-keypairs:create": "rule:admin_api or user_id:%(user_id)s",
+ "os_compute_api:os-keypairs:delete": "rule:admin_api or user_id:%(user_id)s",
+ "os_compute_api:limits:discoverable": "",
+ "os_compute_api:limits": "",
+ "os_compute_api:os-lock-server:discoverable": "",
+ "os_compute_api:os-lock-server:lock": "rule:admin_or_owner",
+ "os_compute_api:os-lock-server:unlock": "rule:admin_or_owner",
+ "os_compute_api:os-lock-server:unlock:unlock_override": "rule:admin_api",
+ "os_compute_api:os-migrate-server:discoverable": "",
+ "os_compute_api:os-migrate-server:migrate": "rule:admin_api",
+ "os_compute_api:os-migrate-server:migrate_live": "rule:admin_api",
+ "os_compute_api:os-multinic": "",
+ "os_compute_api:os-multinic:discoverable": "",
+ "os_compute_api:os-networks": "rule:admin_api",
+ "os_compute_api:os-networks:view": "",
+ "os_compute_api:os-networks:discoverable": "",
+ "os_compute_api:os-networks-associate": "rule:admin_api",
+ "os_compute_api:os-networks-associate:discoverable": "",
+ "os_compute_api:os-pause-server:discoverable": "",
+ "os_compute_api:os-pause-server:pause": "rule:admin_or_owner",
+ "os_compute_api:os-pause-server:unpause": "rule:admin_or_owner",
+ "os_compute_api:os-pci:pci_servers": "",
+ "os_compute_api:os-pci:discoverable": "",
+ "os_compute_api:os-pci:index": "rule:admin_api",
+ "os_compute_api:os-pci:detail": "rule:admin_api",
+ "os_compute_api:os-pci:show": "rule:admin_api",
+ "os_compute_api:os-personality:discoverable": "",
+ "os_compute_api:os-preserve-ephemeral-rebuild:discoverable": "",
+ "os_compute_api:os-quota-sets:discoverable": "",
+ "os_compute_api:os-quota-sets:show": "rule:admin_or_owner",
+ "os_compute_api:os-quota-sets:defaults": "",
+ "os_compute_api:os-quota-sets:update": "rule:admin_api",
+ "os_compute_api:os-quota-sets:delete": "rule:admin_api",
+ "os_compute_api:os-quota-sets:detail": "rule:admin_api",
+ "os_compute_api:os-quota-class-sets:update": "rule:admin_api",
+ "os_compute_api:os-quota-class-sets:show": "is_admin:True or quota_class:%(quota_class)s",
+ "os_compute_api:os-quota-class-sets:discoverable": "",
+ "os_compute_api:os-rescue": "",
+ "os_compute_api:os-rescue:discoverable": "",
+ "os_compute_api:os-scheduler-hints:discoverable": "",
+ "os_compute_api:os-security-group-default-rules:discoverable": "",
+ "os_compute_api:os-security-group-default-rules": "rule:admin_api",
+ "os_compute_api:os-security-groups": "",
+ "os_compute_api:os-security-groups:discoverable": "",
+ "os_compute_api:os-server-diagnostics": "rule:admin_api",
+ "os_compute_api:os-server-diagnostics:discoverable": "",
+ "os_compute_api:os-server-password": "",
+ "os_compute_api:os-server-password:discoverable": "",
+ "os_compute_api:os-server-usage": "",
+ "os_compute_api:os-server-usage:discoverable": "",
+ "os_compute_api:os-server-groups": "",
+ "os_compute_api:os-server-groups:discoverable": "",
+ "os_compute_api:os-services": "rule:admin_api",
+ "os_compute_api:os-services:discoverable": "",
+ "os_compute_api:server-metadata:discoverable": "",
+ "os_compute_api:server-metadata:index": "rule:admin_or_owner",
+ "os_compute_api:server-metadata:show": "rule:admin_or_owner",
+ "os_compute_api:server-metadata:delete": "rule:admin_or_owner",
+ "os_compute_api:server-metadata:create": "rule:admin_or_owner",
+ "os_compute_api:server-metadata:update": "rule:admin_or_owner",
+ "os_compute_api:server-metadata:update_all": "rule:admin_or_owner",
+ "os_compute_api:servers:discoverable": "",
+ "os_compute_api:os-shelve:shelve": "",
+ "os_compute_api:os-shelve:shelve:discoverable": "",
+ "os_compute_api:os-shelve:shelve_offload": "rule:admin_api",
+ "os_compute_api:os-simple-tenant-usage:discoverable": "",
+ "os_compute_api:os-simple-tenant-usage:show": "rule:admin_or_owner",
+ "os_compute_api:os-simple-tenant-usage:list": "rule:admin_api",
+ "os_compute_api:os-suspend-server:discoverable": "",
+ "os_compute_api:os-suspend-server:suspend": "rule:admin_or_owner",
+ "os_compute_api:os-suspend-server:resume": "rule:admin_or_owner",
+ "os_compute_api:os-tenant-networks": "rule:admin_or_owner",
+ "os_compute_api:os-tenant-networks:discoverable": "",
+ "os_compute_api:os-shelve:unshelve": "",
+ "os_compute_api:os-user-data:discoverable": "",
+ "os_compute_api:os-virtual-interfaces": "",
+ "os_compute_api:os-virtual-interfaces:discoverable": "",
+ "os_compute_api:os-volumes": "",
+ "os_compute_api:os-volumes:discoverable": "",
+ "os_compute_api:os-volumes-attachments:index": "",
+ "os_compute_api:os-volumes-attachments:show": "",
+ "os_compute_api:os-volumes-attachments:create": "",
+ "os_compute_api:os-volumes-attachments:update": "",
+ "os_compute_api:os-volumes-attachments:delete": "",
+ "os_compute_api:os-volumes-attachments:discoverable": "",
+ "os_compute_api:os-availability-zone:list": "",
+ "os_compute_api:os-availability-zone:discoverable": "",
+ "os_compute_api:os-availability-zone:detail": "rule:admin_api",
+ "os_compute_api:os-used-limits": "rule:admin_api",
+ "os_compute_api:os-used-limits:discoverable": "",
+ "os_compute_api:os-migrations:index": "rule:admin_api",
+ "os_compute_api:os-migrations:discoverable": "",
+ "os_compute_api:os-assisted-volume-snapshots:create": "rule:admin_api",
+ "os_compute_api:os-assisted-volume-snapshots:delete": "rule:admin_api",
+ "os_compute_api:os-assisted-volume-snapshots:discoverable": "",
+ "os_compute_api:os-console-auth-tokens": "rule:admin_api",
+ "os_compute_api:os-server-external-events:create": "rule:admin_api"
+}