aboutsummaryrefslogtreecommitdiffstats
path: root/moonv4
diff options
context:
space:
mode:
Diffstat (limited to 'moonv4')
-rw-r--r--moonv4/DEV.md52
-rw-r--r--moonv4/README.md415
-rw-r--r--moonv4/TODO18
-rw-r--r--moonv4/bin/README.md5
-rw-r--r--moonv4/bin/bootstrap.py102
-rw-r--r--moonv4/bin/delete_orchestrator.sh63
-rw-r--r--moonv4/bin/moon_lib_update.sh43
-rw-r--r--moonv4/conf/moon.conf41
-rw-r--r--moonv4/kubernetes/README.md50
-rw-r--r--moonv4/kubernetes/conf/password_moon.txt1
-rw-r--r--moonv4/kubernetes/conf/password_root.txt1
-rw-r--r--moonv4/kubernetes/conf/ports.conf24
-rw-r--r--moonv4/kubernetes/init_k8s.sh33
-rw-r--r--moonv4/kubernetes/start_moon.sh37
-rw-r--r--moonv4/kubernetes/templates/consul.yaml33
-rw-r--r--moonv4/kubernetes/templates/db.yaml84
-rw-r--r--moonv4/kubernetes/templates/keystone.yaml39
-rw-r--r--moonv4/kubernetes/templates/kube-dns.yaml183
-rw-r--r--moonv4/kubernetes/templates/moon_configuration.yaml25
-rw-r--r--moonv4/kubernetes/templates/moon_gui.yaml42
-rw-r--r--moonv4/kubernetes/templates/moon_manager.yaml33
-rw-r--r--moonv4/kubernetes/templates/moon_orchestrator.yaml40
-rw-r--r--moonv4/moon_authz/Dockerfile7
-rw-r--r--moonv4/moon_authz/LICENSE54
-rw-r--r--moonv4/moon_authz/moon_authz/__main__.py3
-rw-r--r--moonv4/moon_authz/moon_authz/api/authorization.py387
-rw-r--r--moonv4/moon_authz/moon_authz/api/generic.py123
-rw-r--r--moonv4/moon_authz/moon_authz/http_server.py (renamed from moonv4/moon_consul/moon_consul/http_server.py)48
-rw-r--r--moonv4/moon_authz/moon_authz/messenger.py50
-rw-r--r--moonv4/moon_authz/moon_authz/server.py50
-rw-r--r--moonv4/moon_authz/requirements.txt9
-rw-r--r--moonv4/moon_authz/tests/unit_python/conftest.py29
-rw-r--r--moonv4/moon_authz/tests/unit_python/mock_pods.py545
-rw-r--r--moonv4/moon_authz/tests/unit_python/requirements.txt (renamed from moonv4/moon_consul/requirements.txt)4
-rw-r--r--moonv4/moon_authz/tests/unit_python/test_authz.py50
-rw-r--r--moonv4/moon_authz/tests/unit_python/utilities.py173
-rw-r--r--moonv4/moon_bouchon/Dockerfile8
-rw-r--r--moonv4/moon_bouchon/README.md42
-rw-r--r--moonv4/moon_bouchon/moon_bouchon/__init__.py (renamed from moonv4/moon_router/moon_router/__init__.py)3
-rw-r--r--moonv4/moon_bouchon/moon_bouchon/__main__.py (renamed from moonv4/moon_consul/MANIFEST.in)10
-rw-r--r--moonv4/moon_bouchon/moon_bouchon/server.py138
-rw-r--r--moonv4/moon_bouchon/requirements.txt1
-rw-r--r--moonv4/moon_bouchon/setup.cfg2
-rw-r--r--moonv4/moon_bouchon/setup.py (renamed from moonv4/moon_router/setup.py)11
-rw-r--r--moonv4/moon_bouchon/tests/test_interface.py61
-rw-r--r--moonv4/moon_bouchon/tests/test_wrapper.py38
-rw-r--r--moonv4/moon_consul/Dockerfile37
-rw-r--r--moonv4/moon_consul/LICENSE204
-rw-r--r--moonv4/moon_consul/README.md9
-rw-r--r--moonv4/moon_consul/moon_consul/__init__.py1
-rw-r--r--moonv4/moon_consul/moon_consul/__main__.py3
-rw-r--r--moonv4/moon_consul/moon_consul/api/database.py72
-rw-r--r--moonv4/moon_consul/moon_consul/api/messenger.py67
-rw-r--r--moonv4/moon_consul/moon_consul/api/openstack.py63
-rw-r--r--moonv4/moon_consul/moon_consul/api/slave.py72
-rw-r--r--moonv4/moon_consul/moon_consul/api/system.py169
-rw-r--r--moonv4/moon_consul/moon_consul/server.py82
-rw-r--r--moonv4/moon_consul/setup.py50
-rw-r--r--moonv4/moon_db/Changelog20
-rw-r--r--moonv4/moon_db/LICENSE54
-rw-r--r--moonv4/moon_db/MANIFEST.in1
-rw-r--r--moonv4/moon_db/README.md32
-rw-r--r--moonv4/moon_db/README.rst9
-rw-r--r--moonv4/moon_db/build.sh38
-rw-r--r--moonv4/moon_db/moon_db/__init__.py2
-rw-r--r--moonv4/moon_db/moon_db/api/policy.py22
-rw-r--r--moonv4/moon_db/moon_db/api/tenants.py137
-rw-r--r--moonv4/moon_db/moon_db/backends/memory.py60
-rw-r--r--moonv4/moon_db/moon_db/db_manager.py84
-rw-r--r--moonv4/moon_db/setup.py3
-rw-r--r--moonv4/moon_db/tests/configure_db.sh9
-rw-r--r--moonv4/moon_db/tests/test_intraextension.py44
-rw-r--r--moonv4/moon_db/tests/test_tenant.py86
-rw-r--r--moonv4/moon_db/tests/unit_python/conftest.py145
-rw-r--r--moonv4/moon_db/tests/unit_python/mock_components.py27
-rw-r--r--moonv4/moon_db/tests/unit_python/mock_keystone.py23
-rw-r--r--moonv4/moon_db/tests/unit_python/requirements.txt5
-rw-r--r--moonv4/moon_db/tests/unit_python/test_policies.py77
-rw-r--r--moonv4/moon_db/tests/unit_python/utilities.py136
-rw-r--r--moonv4/moon_gui/DEV.md49
-rw-r--r--moonv4/moon_gui/Dockerfile13
-rw-r--r--moonv4/moon_gui/README.md (renamed from moonv4/moon_gui/readme.md)0
-rw-r--r--moonv4/moon_gui/run.sh17
-rwxr-xr-x[-rw-r--r--]moonv4/moon_gui/static/app/authentication/authentication.controller.js0
-rwxr-xr-x[-rw-r--r--]moonv4/moon_gui/static/app/authentication/authentication.tpl.html0
-rwxr-xr-x[-rw-r--r--]moonv4/moon_gui/static/app/common/404/404.tpl.html0
-rwxr-xr-x[-rw-r--r--]moonv4/moon_gui/static/app/common/compatibility/compatibility.tpl.html0
-rwxr-xr-x[-rw-r--r--]moonv4/moon_gui/static/app/common/footer/footer.controller.js0
-rwxr-xr-x[-rw-r--r--]moonv4/moon_gui/static/app/common/footer/footer.tpl.html0
-rwxr-xr-x[-rw-r--r--]moonv4/moon_gui/static/app/common/header/header.controller.js0
-rwxr-xr-x[-rw-r--r--]moonv4/moon_gui/static/app/common/header/header.tpl.html0
-rwxr-xr-x[-rw-r--r--]moonv4/moon_gui/static/app/common/loader/loader.dir.js0
-rwxr-xr-x[-rw-r--r--]moonv4/moon_gui/static/app/common/loader/loader.tpl.html0
-rwxr-xr-x[-rw-r--r--]moonv4/moon_gui/static/app/common/waiting/waiting.tpl.html0
-rwxr-xr-x[-rw-r--r--]moonv4/moon_gui/static/app/dashboard/dashboard.tpl.html0
-rwxr-xr-x[-rw-r--r--]moonv4/moon_gui/static/app/logs/logs.controller.js0
-rwxr-xr-x[-rw-r--r--]moonv4/moon_gui/static/app/logs/logs.tpl.html0
-rwxr-xr-x[-rw-r--r--]moonv4/moon_gui/static/app/model/action/model-add.tpl.html0
-rwxr-xr-x[-rw-r--r--]moonv4/moon_gui/static/app/model/action/model-delete.tpl.html0
-rwxr-xr-x[-rw-r--r--]moonv4/moon_gui/static/app/model/action/model-view.tpl.html0
-rwxr-xr-x[-rw-r--r--]moonv4/moon_gui/static/app/model/action/model.controller.add.js0
-rwxr-xr-x[-rw-r--r--]moonv4/moon_gui/static/app/model/action/model.controller.delete.js0
-rwxr-xr-x[-rw-r--r--]moonv4/moon_gui/static/app/model/action/model.controller.view.js0
-rwxr-xr-x[-rw-r--r--]moonv4/moon_gui/static/app/model/edit/metadata/metadata-edit.tpl.html0
-rwxr-xr-x[-rw-r--r--]moonv4/moon_gui/static/app/model/edit/metadata/metadata-list.tpl.html0
-rwxr-xr-x[-rw-r--r--]moonv4/moon_gui/static/app/model/edit/metadata/metadata.edit.dir.js0
-rwxr-xr-x[-rw-r--r--]moonv4/moon_gui/static/app/model/edit/metadata/metadata.list.dir.js0
-rwxr-xr-x[-rw-r--r--]moonv4/moon_gui/static/app/model/edit/metarules/action/mapping/metarules-add.tpl.html0
-rwxr-xr-x[-rw-r--r--]moonv4/moon_gui/static/app/model/edit/metarules/action/mapping/metarules-map.tpl.html0
-rwxr-xr-x[-rw-r--r--]moonv4/moon_gui/static/app/model/edit/metarules/action/mapping/metarules-unmap.tpl.html0
-rwxr-xr-x[-rw-r--r--]moonv4/moon_gui/static/app/model/edit/metarules/action/mapping/metarules.controller.add.js0
-rwxr-xr-x[-rw-r--r--]moonv4/moon_gui/static/app/model/edit/metarules/action/mapping/metarules.map.controller.js0
-rwxr-xr-x[-rw-r--r--]moonv4/moon_gui/static/app/model/edit/metarules/action/mapping/metarules.unmap.controller.js0
-rwxr-xr-x[-rw-r--r--]moonv4/moon_gui/static/app/model/edit/metarules/action/metarules-edit-basic.tpl.html0
-rwxr-xr-x[-rw-r--r--]moonv4/moon_gui/static/app/model/edit/metarules/action/metarules-edit.tpl.html0
-rwxr-xr-x[-rw-r--r--]moonv4/moon_gui/static/app/model/edit/metarules/action/metarules.controller.edit.js0
-rwxr-xr-x[-rw-r--r--]moonv4/moon_gui/static/app/model/edit/metarules/action/metarules.edit.basic.dir.js0
-rwxr-xr-x[-rw-r--r--]moonv4/moon_gui/static/app/model/edit/metarules/metarules-list.tpl.html0
-rwxr-xr-x[-rw-r--r--]moonv4/moon_gui/static/app/model/edit/metarules/metarules.list.dir.js0
-rwxr-xr-x[-rw-r--r--]moonv4/moon_gui/static/app/model/edit/model-edit-basic.tpl.html0
-rwxr-xr-x[-rw-r--r--]moonv4/moon_gui/static/app/model/edit/model-edit.tpl.html0
-rwxr-xr-x[-rw-r--r--]moonv4/moon_gui/static/app/model/edit/model.controller.edit.js0
-rwxr-xr-x[-rw-r--r--]moonv4/moon_gui/static/app/model/edit/model.edit.basic.dir.js0
-rwxr-xr-x[-rw-r--r--]moonv4/moon_gui/static/app/model/model-list.tpl.html0
-rwxr-xr-x[-rw-r--r--]moonv4/moon_gui/static/app/model/model.controller.list.js0
-rw-r--r--moonv4/moon_gui/static/app/moon.constants.js24
-rwxr-xr-x[-rw-r--r--]moonv4/moon_gui/static/app/moon.module.js0
-rwxr-xr-x[-rw-r--r--]moonv4/moon_gui/static/app/pdp/action/pdp-add.tpl.html0
-rwxr-xr-x[-rw-r--r--]moonv4/moon_gui/static/app/pdp/action/pdp-delete.tpl.html0
-rwxr-xr-x[-rw-r--r--]moonv4/moon_gui/static/app/pdp/action/pdp.controller.add.js0
-rwxr-xr-x[-rw-r--r--]moonv4/moon_gui/static/app/pdp/action/pdp.controller.delete.js0
-rwxr-xr-x[-rw-r--r--]moonv4/moon_gui/static/app/pdp/edit/pdp-edit-basic.tpl.html0
-rwxr-xr-x[-rw-r--r--]moonv4/moon_gui/static/app/pdp/edit/pdp-edit.tpl.html0
-rwxr-xr-x[-rw-r--r--]moonv4/moon_gui/static/app/pdp/edit/pdp.controller.edit.js0
-rwxr-xr-x[-rw-r--r--]moonv4/moon_gui/static/app/pdp/edit/pdp.edit.basic.dir.js0
-rwxr-xr-x[-rw-r--r--]moonv4/moon_gui/static/app/pdp/pdp-list.tpl.html0
-rwxr-xr-x[-rw-r--r--]moonv4/moon_gui/static/app/pdp/pdp.controller.list.js0
-rwxr-xr-x[-rw-r--r--]moonv4/moon_gui/static/app/policy/action/mapping/policy-map.tpl.html0
-rwxr-xr-x[-rw-r--r--]moonv4/moon_gui/static/app/policy/action/mapping/policy-unmap.tpl.html0
-rwxr-xr-x[-rw-r--r--]moonv4/moon_gui/static/app/policy/action/mapping/policy.controller.map.js0
-rwxr-xr-x[-rw-r--r--]moonv4/moon_gui/static/app/policy/action/mapping/policy.controller.unmap.js0
-rwxr-xr-x[-rw-r--r--]moonv4/moon_gui/static/app/policy/action/policy-add.tpl.html0
-rwxr-xr-x[-rw-r--r--]moonv4/moon_gui/static/app/policy/action/policy-delete.tpl.html0
-rwxr-xr-x[-rw-r--r--]moonv4/moon_gui/static/app/policy/action/policy.controller.add.js0
-rwxr-xr-x[-rw-r--r--]moonv4/moon_gui/static/app/policy/action/policy.controller.delete.js0
-rwxr-xr-xmoonv4/moon_gui/static/app/policy/edit/parameter/assignments/assignments-edit.tpl.html165
-rwxr-xr-x[-rw-r--r--]moonv4/moon_gui/static/app/policy/edit/parameter/assignments/assignments-list.tpl.html0
-rwxr-xr-xmoonv4/moon_gui/static/app/policy/edit/parameter/assignments/assignments.edit.dir.js439
-rwxr-xr-x[-rw-r--r--]moonv4/moon_gui/static/app/policy/edit/parameter/assignments/assignments.list.dir.js0
-rwxr-xr-xmoonv4/moon_gui/static/app/policy/edit/parameter/data/data-edit.tpl.html110
-rwxr-xr-x[-rw-r--r--]moonv4/moon_gui/static/app/policy/edit/parameter/data/data-list.tpl.html0
-rwxr-xr-x[-rw-r--r--]moonv4/moon_gui/static/app/policy/edit/parameter/data/data.edit.dir.js0
-rwxr-xr-x[-rw-r--r--]moonv4/moon_gui/static/app/policy/edit/parameter/data/data.list.dir.js0
-rwxr-xr-xmoonv4/moon_gui/static/app/policy/edit/parameter/perimeter/perimeter-edit.tpl.html166
-rwxr-xr-x[-rw-r--r--]moonv4/moon_gui/static/app/policy/edit/parameter/perimeter/perimeter-list.tpl.html0
-rwxr-xr-xmoonv4/moon_gui/static/app/policy/edit/parameter/perimeter/perimeter.edit.dir.js437
-rwxr-xr-x[-rw-r--r--]moonv4/moon_gui/static/app/policy/edit/parameter/perimeter/perimeter.list.dir.js0
-rwxr-xr-xmoonv4/moon_gui/static/app/policy/edit/parameter/rules/rules-edit.tpl.html341
-rwxr-xr-x[-rw-r--r--]moonv4/moon_gui/static/app/policy/edit/parameter/rules/rules-list.tpl.html0
-rwxr-xr-xmoonv4/moon_gui/static/app/policy/edit/parameter/rules/rules.edit.dir.js537
-rwxr-xr-x[-rw-r--r--]moonv4/moon_gui/static/app/policy/edit/parameter/rules/rules.list.dir.js0
-rwxr-xr-x[-rw-r--r--]moonv4/moon_gui/static/app/policy/edit/policy-edit-basic.tpl.html0
-rwxr-xr-x[-rw-r--r--]moonv4/moon_gui/static/app/policy/edit/policy-edit.tpl.html0
-rwxr-xr-x[-rw-r--r--]moonv4/moon_gui/static/app/policy/edit/policy.controller.edit.js0
-rwxr-xr-x[-rw-r--r--]moonv4/moon_gui/static/app/policy/edit/policy.edit.basic.dir.js0
-rwxr-xr-x[-rw-r--r--]moonv4/moon_gui/static/app/policy/policy-list.tpl.html0
-rwxr-xr-x[-rw-r--r--]moonv4/moon_gui/static/app/policy/policy-mapped-list.tpl.html0
-rwxr-xr-x[-rw-r--r--]moonv4/moon_gui/static/app/policy/policy.controller.list.js0
-rwxr-xr-x[-rw-r--r--]moonv4/moon_gui/static/app/policy/policy.mapped.list.dir.js0
-rwxr-xr-x[-rw-r--r--]moonv4/moon_gui/static/app/project/action/mapping/project-map.tpl.html0
-rwxr-xr-x[-rw-r--r--]moonv4/moon_gui/static/app/project/action/mapping/project-unmap.tpl.html0
-rwxr-xr-x[-rw-r--r--]moonv4/moon_gui/static/app/project/action/mapping/project.controller.map.js0
-rwxr-xr-x[-rw-r--r--]moonv4/moon_gui/static/app/project/action/mapping/project.controller.unmap.js0
-rwxr-xr-x[-rw-r--r--]moonv4/moon_gui/static/app/project/action/project-add.tpl.html0
-rwxr-xr-x[-rw-r--r--]moonv4/moon_gui/static/app/project/action/project-delete.tpl.html0
-rwxr-xr-x[-rw-r--r--]moonv4/moon_gui/static/app/project/action/project-view.tpl.html0
-rwxr-xr-x[-rw-r--r--]moonv4/moon_gui/static/app/project/action/project.controller.add.js0
-rwxr-xr-x[-rw-r--r--]moonv4/moon_gui/static/app/project/action/project.controller.delete.js0
-rwxr-xr-x[-rw-r--r--]moonv4/moon_gui/static/app/project/action/project.controller.view.js0
-rwxr-xr-x[-rw-r--r--]moonv4/moon_gui/static/app/project/project-list.tpl.html0
-rwxr-xr-x[-rw-r--r--]moonv4/moon_gui/static/app/project/project.controller.list.js0
-rwxr-xr-x[-rw-r--r--]moonv4/moon_gui/static/app/services/gui/alert.service.js0
-rwxr-xr-x[-rw-r--r--]moonv4/moon_gui/static/app/services/gui/browser.service.js0
-rwxr-xr-x[-rw-r--r--]moonv4/moon_gui/static/app/services/gui/form.service.js0
-rwxr-xr-x[-rw-r--r--]moonv4/moon_gui/static/app/services/gui/menu.service.js0
-rwxr-xr-x[-rw-r--r--]moonv4/moon_gui/static/app/services/gui/security.pipeline.service.js0
-rwxr-xr-x[-rw-r--r--]moonv4/moon_gui/static/app/services/gui/util.service.js0
-rwxr-xr-x[-rw-r--r--]moonv4/moon_gui/static/app/services/gui/version.service.js0
-rwxr-xr-x[-rw-r--r--]moonv4/moon_gui/static/app/services/moon/model/model.service.js0
-rwxr-xr-x[-rw-r--r--]moonv4/moon_gui/static/app/services/moon/pdp.service.js0
-rwxr-xr-x[-rw-r--r--]moonv4/moon_gui/static/app/services/moon/policy/parameters/assignements.service.js0
-rwxr-xr-x[-rw-r--r--]moonv4/moon_gui/static/app/services/moon/policy/parameters/data.service.js0
-rwxr-xr-x[-rw-r--r--]moonv4/moon_gui/static/app/services/moon/policy/parameters/perimeter.service.js0
-rwxr-xr-xmoonv4/moon_gui/static/app/services/moon/policy/parameters/rules.service.js56
-rwxr-xr-x[-rw-r--r--]moonv4/moon_gui/static/app/services/moon/policy/policy.service.js0
-rwxr-xr-x[-rw-r--r--]moonv4/moon_gui/static/app/services/moon/rule/metadata.service.js0
-rwxr-xr-x[-rw-r--r--]moonv4/moon_gui/static/app/services/moon/rule/metarule.service.js0
-rwxr-xr-x[-rw-r--r--]moonv4/moon_gui/static/app/services/partner/authentication.service.js0
-rwxr-xr-x[-rw-r--r--]moonv4/moon_gui/static/app/services/partner/nova.service.js0
-rwxr-xr-x[-rw-r--r--]moonv4/moon_gui/static/app/services/partner/project.service.js0
-rw-r--r--moonv4/moon_interface/Dockerfile1
-rw-r--r--moonv4/moon_interface/LICENSE54
-rw-r--r--moonv4/moon_interface/moon_interface/__main__.py3
-rw-r--r--moonv4/moon_interface/moon_interface/api/assignments.py264
-rw-r--r--moonv4/moon_interface/moon_interface/api/authz.py164
-rw-r--r--moonv4/moon_interface/moon_interface/api/data.py259
-rw-r--r--moonv4/moon_interface/moon_interface/api/generic.py26
-rw-r--r--moonv4/moon_interface/moon_interface/api/meta_data.py204
-rw-r--r--moonv4/moon_interface/moon_interface/api/meta_rules.py138
-rw-r--r--moonv4/moon_interface/moon_interface/api/models.py101
-rw-r--r--moonv4/moon_interface/moon_interface/api/pdp.py106
-rw-r--r--moonv4/moon_interface/moon_interface/api/perimeter.py312
-rw-r--r--moonv4/moon_interface/moon_interface/api/policies.py106
-rw-r--r--moonv4/moon_interface/moon_interface/api/rules.py114
-rw-r--r--moonv4/moon_interface/moon_interface/authz_requests.py159
-rw-r--r--moonv4/moon_interface/moon_interface/containers.py102
-rw-r--r--moonv4/moon_interface/moon_interface/http_server.py50
-rw-r--r--moonv4/moon_interface/moon_interface/server.py8
-rw-r--r--moonv4/moon_interface/requirements.txt5
-rw-r--r--moonv4/moon_interface/tests/apitests/README.md33
-rw-r--r--moonv4/moon_interface/tests/apitests/plot_json.py852
-rw-r--r--moonv4/moon_interface/tests/apitests/scenario/delegation.py40
-rw-r--r--moonv4/moon_interface/tests/apitests/scenario/rbac_large.py233
-rw-r--r--moonv4/moon_interface/tests/apitests/scenario/rbac_mls.py50
-rw-r--r--moonv4/moon_interface/tests/apitests/scenario/session.py60
-rw-r--r--moonv4/moon_interface/tests/apitests/scenario/session_large.py389
-rw-r--r--moonv4/moon_interface/tests/apitests/set_authz.py388
-rw-r--r--moonv4/moon_interface/tests/apitests/test_models.py37
-rw-r--r--moonv4/moon_interface/tests/apitests/test_pdp.py16
-rw-r--r--moonv4/moon_interface/tests/apitests/test_policies.py157
-rw-r--r--moonv4/moon_interface/tests/unit_python/api/__init__.py (renamed from moonv4/moon_consul/moon_consul/api/__init__.py)0
-rw-r--r--moonv4/moon_interface/tests/unit_python/api/test_authz.py23
-rw-r--r--moonv4/moon_interface/tests/unit_python/conftest.py678
-rw-r--r--moonv4/moon_interface/tests/unit_python/requirements.txt5
-rw-r--r--moonv4/moon_interface/tools/get_keystone_token.py1
-rw-r--r--moonv4/moon_manager/Dockerfile1
-rw-r--r--moonv4/moon_manager/LICENSE54
-rw-r--r--moonv4/moon_manager/moon_manager/__main__.py3
-rw-r--r--moonv4/moon_manager/moon_manager/api/assignments.py18
-rw-r--r--moonv4/moon_manager/moon_manager/api/containers.py179
-rw-r--r--moonv4/moon_manager/moon_manager/api/data.py83
-rw-r--r--moonv4/moon_manager/moon_manager/api/generic.py6
-rw-r--r--moonv4/moon_manager/moon_manager/api/meta_data.py45
-rw-r--r--moonv4/moon_manager/moon_manager/api/meta_rules.py41
-rw-r--r--moonv4/moon_manager/moon_manager/api/models.py14
-rw-r--r--moonv4/moon_manager/moon_manager/api/pdp.py69
-rw-r--r--moonv4/moon_manager/moon_manager/api/perimeter.py87
-rw-r--r--moonv4/moon_manager/moon_manager/api/policies.py14
-rw-r--r--moonv4/moon_manager/moon_manager/api/rules.py40
-rw-r--r--moonv4/moon_manager/moon_manager/http_server.py25
-rw-r--r--moonv4/moon_manager/moon_manager/server.py5
-rw-r--r--moonv4/moon_manager/requirements.txt3
-rw-r--r--moonv4/moon_manager/tests/unit_python/__init__.py (renamed from moonv4/moon_interface/tests/apitests/utils/__init__.py)0
-rw-r--r--moonv4/moon_manager/tests/unit_python/api/__init__.py (renamed from moonv4/moon_router/moon_router/api/__init__.py)0
-rw-r--r--moonv4/moon_manager/tests/unit_python/api/test_perimeter.py59
-rw-r--r--moonv4/moon_manager/tests/unit_python/conftest.py195
-rw-r--r--moonv4/moon_manager/tests/unit_python/requirements.txt5
-rw-r--r--moonv4/moon_orchestrator/Dockerfile3
-rw-r--r--moonv4/moon_orchestrator/LICENSE54
-rw-r--r--moonv4/moon_orchestrator/bootstrap.py203
-rw-r--r--moonv4/moon_orchestrator/moon_orchestrator/__main__.py3
-rw-r--r--moonv4/moon_orchestrator/moon_orchestrator/api/configuration.py63
-rw-r--r--moonv4/moon_orchestrator/moon_orchestrator/api/containers.py123
-rw-r--r--moonv4/moon_orchestrator/moon_orchestrator/api/generic.py124
-rw-r--r--moonv4/moon_orchestrator/moon_orchestrator/api/pods.py127
-rw-r--r--moonv4/moon_orchestrator/moon_orchestrator/api/slaves.py78
-rw-r--r--moonv4/moon_orchestrator/moon_orchestrator/drivers.py175
-rw-r--r--moonv4/moon_orchestrator/moon_orchestrator/http_server.py292
-rw-r--r--moonv4/moon_orchestrator/moon_orchestrator/messenger.py63
-rw-r--r--moonv4/moon_orchestrator/moon_orchestrator/server.py179
-rw-r--r--moonv4/moon_orchestrator/requirements.txt16
-rw-r--r--moonv4/moon_orchestrator/tests/unit_python/conftest.py18
-rw-r--r--moonv4/moon_orchestrator/tests/unit_python/mock_pods.py404
-rw-r--r--moonv4/moon_orchestrator/tests/unit_python/requirements.txt5
-rw-r--r--moonv4/moon_orchestrator/tests/unit_python/test_pods.py43
-rw-r--r--moonv4/moon_orchestrator/tests/unit_python/utilities.py173
-rw-r--r--moonv4/moon_router/Dockerfile11
-rw-r--r--moonv4/moon_router/README.md18
-rw-r--r--moonv4/moon_router/doc/api-moon-secrouter.pdfbin195778 -> 0 bytes
-rw-r--r--moonv4/moon_router/doc/api.pdfbin195377 -> 0 bytes
-rw-r--r--moonv4/moon_router/moon_router/__main__.py3
-rw-r--r--moonv4/moon_router/moon_router/api/generic.py46
-rw-r--r--moonv4/moon_router/moon_router/api/route.py472
-rw-r--r--moonv4/moon_router/moon_router/messenger.py69
-rw-r--r--moonv4/moon_router/moon_router/server.py63
-rw-r--r--moonv4/moon_router/tests/moon_db-0.1.0.tar.gzbin21423 -> 0 bytes
-rw-r--r--moonv4/moon_router/tests/moon_policy-0.1.0.tar.gzbin8640 -> 0 bytes
-rw-r--r--moonv4/moon_utilities/Changelog28
-rw-r--r--moonv4/moon_utilities/LICENSE54
-rw-r--r--moonv4/moon_utilities/README.md33
-rw-r--r--moonv4/moon_utilities/README.rst9
-rw-r--r--moonv4/moon_utilities/moon_utilities/__init__.py2
-rw-r--r--moonv4/moon_utilities/moon_utilities/cache.py543
-rw-r--r--moonv4/moon_utilities/moon_utilities/configuration.py16
-rw-r--r--moonv4/moon_utilities/moon_utilities/exceptions.py20
-rw-r--r--moonv4/moon_utilities/moon_utilities/get_os_apis.py122
-rw-r--r--moonv4/moon_utilities/moon_utilities/misc.py119
-rw-r--r--moonv4/moon_utilities/moon_utilities/options.py300
-rw-r--r--moonv4/moon_utilities/moon_utilities/security_functions.py318
-rw-r--r--moonv4/moon_utilities/requirements.txt5
-rw-r--r--moonv4/moon_utilities/setup.py19
-rw-r--r--moonv4/moon_utilities/tests/unit_python/conftest.py17
-rw-r--r--moonv4/moon_utilities/tests/unit_python/mock_cache.py321
-rw-r--r--moonv4/moon_utilities/tests/unit_python/mock_components.py27
-rw-r--r--moonv4/moon_utilities/tests/unit_python/mock_keystone.py23
-rw-r--r--moonv4/moon_utilities/tests/unit_python/requirements.txt2
-rw-r--r--moonv4/moon_utilities/tests/unit_python/test_cache.py75
-rw-r--r--moonv4/moon_utilities/tests/unit_python/test_configuration.py5
-rw-r--r--moonv4/moon_utilities/tests/unit_python/utilities.py136
-rw-r--r--moonv4/moon_wrapper/Dockerfile1
-rw-r--r--moonv4/moon_wrapper/LICENSE54
-rw-r--r--moonv4/moon_wrapper/moon_wrapper/__main__.py3
-rw-r--r--moonv4/moon_wrapper/moon_wrapper/api/__init__.py0
-rw-r--r--moonv4/moon_wrapper/moon_wrapper/api/generic.py (renamed from moonv4/moon_consul/moon_consul/api/generic.py)71
-rw-r--r--moonv4/moon_wrapper/moon_wrapper/api/wrapper.py127
-rw-r--r--moonv4/moon_wrapper/moon_wrapper/http_server.py197
-rw-r--r--moonv4/moon_wrapper/moon_wrapper/server.py5
-rw-r--r--moonv4/moon_wrapper/requirements.txt3
-rw-r--r--moonv4/moon_wrapper/tests/README.md35
-rw-r--r--moonv4/moon_wrapper/tests/unit_python/api/__init__.py0
-rw-r--r--moonv4/moon_wrapper/tests/unit_python/api/test_wrapper.py28
-rw-r--r--moonv4/moon_wrapper/tests/unit_python/conftest.py687
-rw-r--r--moonv4/moon_wrapper/tests/unit_python/requirements.txt5
-rw-r--r--moonv4/python_moonclient/Changelog (renamed from moonv4/moon_consul/Changelog)3
-rw-r--r--moonv4/python_moonclient/LICENSE (renamed from moonv4/moon_router/LICENSE)54
-rw-r--r--moonv4/python_moonclient/MANIFEST.in (renamed from moonv4/moon_router/MANIFEST.in)3
-rw-r--r--moonv4/python_moonclient/README.md33
-rw-r--r--moonv4/python_moonclient/python_moonclient/__init__.py6
-rw-r--r--moonv4/python_moonclient/python_moonclient/config.py44
-rw-r--r--moonv4/python_moonclient/requirements.txt3
-rw-r--r--moonv4/python_moonclient/setup.py42
-rw-r--r--moonv4/python_moonclient/tests/unit_python/conftest.py12
-rw-r--r--moonv4/python_moonclient/tests/unit_python/mock_config.py35
-rw-r--r--moonv4/python_moonclient/tests/unit_python/requirements.txt2
-rw-r--r--moonv4/python_moonclient/tests/unit_python/test_config.py8
-rw-r--r--moonv4/python_moonclient/tests/unit_python/utilities.py153
-rw-r--r--moonv4/templates/glance/policy.json62
-rw-r--r--moonv4/templates/moonforming/Dockerfile10
-rw-r--r--moonv4/templates/moonforming/README.md12
-rw-r--r--moonv4/templates/moonforming/conf/mls.py (renamed from moonv4/moon_interface/tests/apitests/scenario/mls.py)19
-rw-r--r--moonv4/templates/moonforming/conf/rbac.py (renamed from moonv4/moon_interface/tests/apitests/scenario/rbac.py)29
-rw-r--r--moonv4/templates/moonforming/conf2consul.py103
-rw-r--r--moonv4/templates/moonforming/moon.conf79
-rw-r--r--moonv4/templates/moonforming/populate_default_values.py (renamed from moonv4/moon_interface/tests/apitests/populate_default_values.py)20
-rw-r--r--moonv4/templates/moonforming/run.sh44
-rw-r--r--moonv4/templates/moonforming/utils/__init__.py0
-rw-r--r--moonv4/templates/moonforming/utils/config.py22
-rw-r--r--moonv4/templates/moonforming/utils/models.py (renamed from moonv4/moon_interface/tests/apitests/utils/models.py)25
-rw-r--r--moonv4/templates/moonforming/utils/pdp.py (renamed from moonv4/moon_interface/tests/apitests/utils/pdp.py)34
-rw-r--r--moonv4/templates/moonforming/utils/policies.py (renamed from moonv4/moon_interface/tests/apitests/utils/policies.py)27
-rw-r--r--moonv4/templates/nova/policy.json488
-rw-r--r--moonv4/templates/python_unit_test/Dockerfile8
-rw-r--r--moonv4/templates/python_unit_test/README.md8
-rw-r--r--moonv4/templates/python_unit_test/requirements.txt (renamed from moonv4/moon_router/requirements.txt)9
-rw-r--r--moonv4/templates/python_unit_test/run_tests.sh13
-rw-r--r--moonv4/tests/get_keystone_projects.py19
-rw-r--r--moonv4/tests/populate_default_values.py135
-rw-r--r--moonv4/tests/send_authz.py243
-rw-r--r--moonv4/tests/utils/config.py62
-rw-r--r--moonv4/tests/utils/models.py19
-rw-r--r--moonv4/tests/utils/parse.py83
-rw-r--r--moonv4/tests/utils/pdp.py42
-rw-r--r--moonv4/tests/utils/policies.py23
363 files changed, 13424 insertions, 8341 deletions
diff --git a/moonv4/DEV.md b/moonv4/DEV.md
index 70bcc4fc..0dff2f17 100644
--- a/moonv4/DEV.md
+++ b/moonv4/DEV.md
@@ -1,6 +1,52 @@
-# Build Python Packages and Docker Images
-
-## Python Package
+# Developer Tutorial
+
+## Gerrit Setup
+### Git Install
+- `sudo apt-get install git`
+- `git config --global user.email "example@wikimedia.org"`
+- `git config --global user.name "example"`
+
+### ssh key
+- `cd ~/.ssh`
+- `ssh-keygen -t rsa -C your_email@youremail.com`
+- `~/.ssh/id_rsa`: identification (private) key`
+- `~/.ssh/id_rsa.pub`: public key
+- copy the public key to Gerrit web
+- add Gerrit web上 entry to `~/.ssh/known_hosts`
+- eval `ssh-agent`: start ssh-agent
+- `ssh-add ~/.ssh/id_rsa`: add private key to ssh
+- `ssh -p 29418 <USERNAME>@gerrit.opnfv.org`: test
+
+### Gerrit clone
+- `git clone https://WuKong@gerrit.opnfv.org:29418/moon`
+- the password is dynamically generated on the Gerrit web
+
+### Gerrit Setting
+- `sudo apt-get install python-pip`
+- `sudo pip install git-review`
+- `git remote add gerrit ssh://<yourname>@gerrit.opnfv.org:29418/moon.git`
+- add the ssh public key to the Gerrit web
+- `git review –s`: test the Gerrit review connection
+- add Contributor Agreement, from settings/Agreement
+
+### Gerrit-Review
+- git add XXX
+- git commit --signoff --all
+- git review
+
+### Review Correction
+- `git clone https://git.opnfv.org/moon`
+- `cd moon`
+- get the commit id from Gerrit dashboard
+- `git checkout commit_id`
+- `git checkout -b 48957-1` (where '48957' is the change number and '1' is the patch_number)
+- do your changes ex:`vi specs/policy/external-pdp.rst`
+- `git add specs/policy/external-pdp.rst`
+- `git commit –amend`
+- `git review`
+
+
+## Build Python Package
### pre-requist
Get the code
```bash
diff --git a/moonv4/README.md b/moonv4/README.md
index 95499589..ba3604d6 100644
--- a/moonv4/README.md
+++ b/moonv4/README.md
@@ -1,122 +1,381 @@
-# Moon Version 4
-
-This directory contains all the modules for MoonV4
+# Moon
+__Version 4.3__
+This directory contains all the modules for running the Moon platform.
## Installation
-### Prerequisite
+### kubeadm
+You must follow those explanations to install `kubeadm`:
+> https://kubernetes.io/docs/setup/independent/install-kubeadm/
+
+To summarize, you must install `docker`:
```bash
-sudo apt install python3-dev python3-pip
-sudo pip3 install pip --upgrade
-sudo apt -y install docker-engine # ([Get Docker](https://docs.docker.com/engine/installation/))
-echo 127.0.0.1 messenger db keystone | sudo tee -a /etc/hosts
+apt update
+apt install -y docker.io
```
-
-
-### Docker Engine Configuration
+
+And then, install `kubeadm`:
```bash
-cat <<EOF | sudo tee /etc/docker/daemon.json
-{
- "hosts": ["fd://", "tcp://0.0.0.0:2376"]
-}
+apt update && apt install -y apt-transport-https
+curl -s https://packages.cloud.google.com/apt/doc/apt-key.gpg | apt-key add -
+cat <<EOF >/etc/apt/sources.list.d/kubernetes.list
+deb http://apt.kubernetes.io/ kubernetes-xenial main
EOF
-sudo mv /lib/systemd/system/docker.service /lib/systemd/system/docker.service.bak
-sudo sed 's/ExecStart=\/usr\/bin\/dockerd -H fd:\/\//ExecStart=\/usr\/bin\/dockerd/' /lib/systemd/system/docker.service.bak | sudo tee /lib/systemd/system/docker.service
-sudo service docker restart
-# if you have a firewall:
-sudo ufw allow in from 172.88.88.0/16
+apt update
+apt install -y kubelet kubeadm kubectl
```
-## Run Standard Containers
-### Cleanup
-Remove already running containers
+### Moon
+The Moon code is not necessary to start the platform but you need
+Kubernetes configuration files from the GIT repository.
+
+The easy way is to clone the Moon code:
```bash
-docker container rm -f $(docker ps -a | grep moon | cut -d " " -f 1) 2>/dev/null
-docker container rm -f messenger db keystone consul 2>/dev/null
+git clone https://git.opnfv.org/moon
+cd moon/moonv4
+export MOON=$(pwd)
```
+### OpenStack
+You must have the following OpenStack components installed somewhere:
+- nova, see [Nova install](https://docs.openstack.org/mitaka/install-guide-ubuntu/nova-controller-install.html)
+- glance, see [Glance install](https://docs.openstack.org/glance/pike/install/)
-### Internal Network Creation
-Create an internal Docker network called `moon`
-```bash
-docker network create -d bridge --subnet=172.88.88.0/16 --gateway=172.88.88.1 moon
-```
+A Keystone component is automatically installed and configured in the Moon platform.
+After the Moon platform installation, the Keystone server will be available
+at: `http://localhost:30005 or http://\<servername\>:30005`
+You can also use your own Keystone server if you want.
-### MySql
-Run the standard `MySql` container in the `moon` network
+## Initialisation
+### kubeadm
+The `kubeadm` platform can be initialized with the following shell script:
```bash
-docker container run -dti --net=moon --hostname db --name db -e MYSQL_ROOT_PASSWORD=p4sswOrd1 -e MYSQL_DATABASE=moon -e MYSQL_USER=moon -e MYSQL_PASSWORD=p4sswOrd1 -p 3306:3306 mysql:latest
+sh kubernetes/init_k8s.sh
```
-
-### Rabbitmq
-Run the standard `Rabbitmq` container in the `moon` network
+
+Wait until all the kubeadm containers are in the `running` state:
```bash
-docker container run -dti --net=moon --hostname messenger --name messenger -e RABBITMQ_DEFAULT_USER=moon -e RABBITMQ_DEFAULT_PASS=p4sswOrd1 -e RABBITMQ_NODENAME=rabbit@messenger -e RABBITMQ_DEFAULT_VHOST=moon -e RABBITMQ_HIPE_COMPILE=1 -p 5671:5671 -p 5672:5672 -p 8080:15672 rabbitmq:3-management
+watch kubectl get po --namespace=kube-system
```
+
+You must see something like this:
+
+ $ kubectl get po --namespace=kube-system
+ NAME READY STATUS RESTARTS AGE
+ calico-etcd-7qgjb 1/1 Running 0 1h
+ calico-node-f8zvm 2/2 Running 1 1h
+ calico-policy-controller-59fc4f7888-ns9kv 1/1 Running 0 1h
+ etcd-varuna 1/1 Running 0 1h
+ kube-apiserver-varuna 1/1 Running 0 1h
+ kube-controller-manager-varuna 1/1 Running 0 1h
+ kube-dns-bfbb49cd7-rgqxn 3/3 Running 0 1h
+ kube-proxy-x88wg 1/1 Running 0 1h
+ kube-scheduler-varuna 1/1 Running 0 1h
+
+### Moon
+The Moon platform is composed on the following components:
+* `consul`: a Consul configuration server
+* `db`: a MySQL database server
+* `keystone`: a Keystone authentication server
+* `gui`: a Moon web interface
+* `manager`: the Moon manager for the database
+* `orchestrator`: the Moon component that manage pods in te K8S platform
+* `wrapper`: the Moon endpoint where OpenStack component connect to.
+At this point, you must choose one of the following options:
+* Specific configuration
+* Generic configuration
-### moon_keystone
-Run the `keystone` container (created by the `Moon` project) in the `moon` network
+#### Specific Configuration
+Why using a specific configuration:
+1. The `db` and `keystone` can be installed by yourself but you must configure the
+Moon platform to use them.
+2. You want to change the default passwords in the Moon platform
+
+Use the following commands: `TODO`
+
+#### Generic Configuration
+Why using a specific configuration:
+1. You just want to test the platform
+2. You want to develop on the Moon platform
+
+The `Moon` platform can be initialized with the following shell script:
```bash
-docker container run -dti --net moon --hostname keystone --name keystone -e DB_HOST=db -e DB_PASSWORD_ROOT=p4sswOrd1 -p 35357:35357 -p 5000:5000 wukongsun/moon_keystone:ocata
+sh kubernetes/start_moon.sh
```
-### Consul
-Run the standard `Consul` container in the `moon` network
+Wait until all the Moon containers are in the `running` state:
```bash
-docker run -d --net=moon --name=consul --hostname=consul -p 8500:8500 consul
+watch kubectl get po --namespace=moon
```
+You must see something like this:
-## Run Moon's Containers
-### Automatic Launch
-To start the `Moon` framework, you only have to run the `moon_orchestrator` container
-```bash
-docker container run -dti --net moon --hostname orchestrator --name orchestrator wukongsun/moon_orchestrator:v4.1
+ $ kubectl get po --namespace=moon
+ NAME READY STATUS RESTARTS AGE
+ consul-57b6d66975-9qnfx 1/1 Running 0 52m
+ db-867f9c6666-bq8cf 1/1 Running 0 52m
+ gui-bc9878b58-q288x 1/1 Running 0 51m
+ keystone-7d9cdbb69f-bl6ln 1/1 Running 0 52m
+ manager-5bfbb96988-2nvhd 1/1 Running 0 51m
+ manager-5bfbb96988-fg8vj 1/1 Running 0 51m
+ manager-5bfbb96988-w9wnk 1/1 Running 0 51m
+ orchestrator-65d8fb4574-tnfx2 1/1 Running 0 51m
+ wrapper-astonishing-748b7dcc4f-ngsvp 1/1 Running 0 51m
+
+## Configuration
+### Moon
+#### Introduction
+The Moon platform is already configured after the installation.
+If you want to see or modify the configuration, go with a web browser
+to the following page:
+
+> http://localhost:30006
+
+This is a consul server, you can update the configuration in the `KEY/VALUE` tab.
+There are some configuration items, lots of them are only read when a new K8S pod is started
+and not during its life cycle.
+
+**WARNING: some confidential information are put here in clear text.
+This is a known security issue.**
+
+#### Keystone
+If you have your own Keystone server, you can point Moon to your server in the
+`openstack/keystone` element or through the link:
+> http://localhost:30005/ui/#/dc1/kv/openstack/keystone/edit
+
+This configuration element is read every time Moon need it, specially when adding users.
+
+#### Database
+The database can also be modified here:
+> http://varuna:30005/ui/#/dc1/kv/database/edit
+
+**WARNING: the password is in clear text, this is a known security issue.**
+
+If you want to use your own database server, change the configuration:
+
+ {"url": "mysql+pymysql://my_user:my_secret_password@my_server/moon", "driver": "sql"}
+
+Then you have to rebuild the database before using it.
+This can be done with the following commands:
+
+ cd $MOON
+ kubectl delete -f kubernetes/templates/moon_configuration.yaml
+ kubectl create -f kubernetes/templates/moon_configuration.yaml
+
+
+### OpenStack
+Before updating the configuration of the OpenStack platform, check that the platform
+is working without Moon, use the following commands:
+```bash
+# set authentication
+openstack endpoint list
+openstack user list
+openstack server list
```
+In order to connect the OpenStack platform with the Moon platform, you must update some
+configuration files in Nova and Glance:
+* `/etc/nova/policy.json`
+* `/etc/glance/policy.json`
+
+In some installed platform, the `/etc/nova/policy.json` can be absent so you have
+to create one. You can find example files in those directory:
+> ${MOON}/moonv4/templates/nova/policy.json
+> ${MOON}/moonv4/templates/glance/policy.json
+
+Each line is mapped to an OpenStack API interface, for example, the following line
+allows the user to get details for every virtual machines in the cloud
+(the corresponding shell command is `openstack server list`):
-### Manuel Launch
-We can also manually start the `Moon` framework
+ "os_compute_api:servers:detail": "",
-#### moon_router
+This lines indicates that there is no special authorisation to use this API,
+every users can use it. If you want that the Moon platform handles that authorisation,
+update this line with:
+
+ "os_compute_api:servers:detail": "http://my_hostname:31001/authz"
+
+1) by replacing `my_hostname` with the hostname (od the IP address) of the Moon platform.
+2) by updating the TCP port (default: 31001) with the good one.
+
+To find this TCP port, use the following command:
+
+ $ kubectl get services -n moon | grep wrapper | cut -d ":" -f 2 | cut -d " " -f 1
+ 31002/TCP
+
+### Moon
+The Moon platform comes with a graphical user interface which can be used with
+a web browser at this URL:
+> http://$MOON_HOST:30002
+
+You will be asked to put a login and password. Those elements are the login and password
+of the Keystone server, if you didn't modify the Keystone server, you will find the
+login and password here:
+> http://$MOON_HOST:30005/ui/#/dc1/kv/openstack/keystone/edit
+
+**WARNING: the password is in clear text, this is a known security issue.**
+
+The Moon platform can also be requested through its API:
+> http://$MOON_HOST:30001
+
+**WARNING: By default, no login/password will be needed because of
+the configuration which is in DEV mode.**
+
+If you want more security, you have to update the configuration of the Keystone server here:
+> http://$MOON_HOST:30005/ui/#/dc1/kv/openstack/keystone/edit
+
+by modifying the `check_token` argument to `yes`.
+If you write this modification, your requests to Moon API must always include a valid token
+taken from the Keystone server. This token must be place in the header of the request
+(`X-Auth-Token`).
+
+## usage
+### tests the platform
+In order to know if the platform is healthy, here are some commands you can use.
+1) Check that all the K8S pods in the Moon namespace are in running state:
+`kubectl get pods -n moon`
+
+2) Check if the Manager API is running:
```bash
-docker container run -dti --net moon --hostname router --name router wukongsun/moon_router:v4.1
+curl http://$MOON_HOST:30001
+curl http://$MOON_HOST:30001/pdp
+curl http://$MOON_HOST:30001/policies
```
-
-#### moon_manager
+
+If you configured the authentication in the Moon platform:
```bash
-docker container run -dti --net moon --hostname manager --name manager wukongsun/moon_manager:v4.1
+curl -i \
+ -H "Content-Type: application/json" \
+ -d '
+{ "auth": {
+ "identity": {
+ "methods": ["password"],
+ "password": {
+ "user": {
+ "name": "admin",
+ "domain": { "id": "default" },
+ "password": "<set_your_password_here>"
+ }
+ }
+ },
+ "scope": {
+ "project": {
+ "name": "admin",
+ "domain": { "id": "default" }
+ }
+ }
+ }
+}' \
+ "http://moon_hostname:30006/v3/auth/tokens" ; echo
+
+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
```
+
+3) Use a web browser to navigate to the GUI and enter the login and password of the keystone service:
+`firefox http://$MOON_HOST:30002`
-#### moon_interface
-```bash
-docker container run -dti --net moon --hostname interface --name interface wukongsun/moon_interface:v4.1
+4) Use tests Python Scripts
+check firstly the Consul service for *Components/Manager*, e.g.
+```json
+{
+ "port": 8082,
+ "bind": "0.0.0.0",
+ "hostname": "manager",
+ "container": "wukongsun/moon_manager:v4.3.1",
+ "external": {
+ "port": 30001,
+ "hostname": "$MOON_HOST"
+ }
+}
+```
+*OpenStack/Keystone*: e.g.
+```json
+{
+ "url": "http://keystone:5000/v3",
+ "user": "admin",
+ "password": "p4ssw0rd",
+ "domain": "default",
+ "project": "admin",
+ "check_token": false,
+ "certificate": false,
+ "external": {
+ "url": "http://$MOON_HOST:30006/v3"
+ }
+}
```
-#### moon_orchestrator
```bash
-docker container run -dti --net moon --hostname orchestrator --name orchestrator wukongsun/moon_orchestrator:v4.1
+python3 populate_default_values.py --consul-host=$MOON_HOST --consul-port=30005 -v scenario/rbac_large.py
+python3 send_authz.py --consul-host=$MOON_HOST --consul-port=30005 --authz-host=$MOON_HOST --authz-port=31002 -v scenario/rbac_large.py
```
+
+### GUI usage
+After authentication, you will see 4 tabs: Project, Models, Policies, PDP:
+* *Projects*: configure mapping between Keystone projects and PDP (Policy Decision Point)
+* *Models*: configure templates of policies (for example RBAC or MLS)
+* *Policies*: applied models or instantiated models ;
+on one policy, you map a authorisation model and set subject, objects and action that will
+rely on that model
+* *PDP*: Policy Decision Point, this is the link between Policies and Keystone Project
-### Tests
-```bash
-docker exec -ti interface /bin/bash
-pip3 install pytest
-cd /usr/local/lib/python3.5/dist-packages/moon_interface/tests/apitests
-pytest
-```
+In the following paragraphs, we will add a new user in OpenStack and allow her to list
+all VM on the OpenStack platform.
+
+First, add a new user and a new project in the OpenStack platform:
+
+ openstack user create --password-prompt demo_user
+ openstack project create demo
+ DEMO_USER=$(openstack user list | grep demo_user | cut -d " " -f 2)
+ DEMO_PROJECT=$(openstack project list | grep demo | cut -d " " -f 2)
+ openstack role add --user $DEMO_USER --project $DEMO_PROJECT admin
+
+You have to add the same user in the Moon interface:
+
+1. go to the `Projects` tab in the Moon interface
+1. go to the line corresponding to the new project and click to the `Map to a PDP` link
+1. select in the combobox the MLS PDP and click `OK`
+1. in the Moon interface, go to the `Policy` tab
+1. go to the line corresponding to the MLS policy and click on the `actions->edit` button
+1. scroll to the `Perimeters` line and click on the `show` link to show the perimeter configuration
+1. go to the `Add a subject` line and click on `Add a new perimeter`
+1. set the name of that subject to `demo_user` (*the name must be strictly identical*)
+1. in the combobox named `Policy list` select the `MLS` policy and click on the `+` button
+1. click on the yellow `Add Perimeter` button
+1. go to the `Assignment` line and click on the `show` button
+1. under the `Add a Assignments Subject` select the MLS policy,
+the new user (`demo_user`), the category `subject_category_level`
+1. in the `Select a Data` line, choose the `High` scope and click on the `+` link
+1. click on the yellow `Create Assignments` button
+1. if you go to the OpenStack platform, the `demo_user` is now allow to connect
+to the Nova component (test with `openstack server list` connected with the `demo_user`)
+
+
+## Annexes
+
+### connect to the OpenStack platform
+
+Here is a shell script to authenticate to the OpenStack platform as `admin`:
+
+ export OS_USERNAME=admin
+ export OS_PASSWORD=p4ssw0rd
+ export OS_REGION_NAME=Orange
+ export OS_TENANT_NAME=admin
+ export OS_AUTH_URL=http://moon_hostname:30006/v3
+ export OS_DOMAIN_NAME=Default
+ export OS_IDENTITY_API_VERSION=3
+
+For the `demo_user`, use:
+
+ export OS_USERNAME=demo_user
+ export OS_PASSWORD=your_secret_password
+ export OS_REGION_NAME=Orange
+ export OS_TENANT_NAME=demo
+ export OS_AUTH_URL=http://moon_hostname:30006/v3
+ export OS_DOMAIN_NAME=Default
+ export OS_IDENTITY_API_VERSION=3
-## Log
-### Get some logs
-```bash
-docker container ps
-docker logs db
-docker logs messenger
-docker logs keystone
-docker logs router
-docker logs manager
-docker logs interface
-```
diff --git a/moonv4/TODO b/moonv4/TODO
index 6d0ca9fc..afdadf3c 100644
--- a/moonv4/TODO
+++ b/moonv4/TODO
@@ -3,30 +3,24 @@ Here is a list of what must be done to have complete version of the Moon platfor
Architecture
- Add a complete logging system
-- Replace moon_orchestrator with Kubernetes ?
-- Add a load balancer (HAProxy ?)
-- Update Consul with Consul-Template ?
-- Develop the Moon hook in Oslo_Policy
+- Replace moon_orchestrator with Kubernetes
Actions that must be done before the next version:
- manage a token/uuid (ie session ID) in the moon_interface component
-- update RabbitMQ connections in security_function to have work queues instead of RPC
- add a timestamps in moon_router to know if the database has been modified
- rename moon_db and moon_utilities because they are not container but just libraries
- work on moonclient because it doesn't work with the new data model
- check all input from moon_interface (check that input data are correct and safe)
- Move @enforce from moon_db to API in Moon_Manager
- Need to work on unit tests with the new data model
-- Allow to have multiple moon_interface in parallel (needed for load balancing)
Bugs to fix:
- Connect the authz functionality with the enforce decorator
-- The intra_extension ID parameter must be given when the container is ran and not when it is build
- (security_function)
-- When a container is deleted, the reference is not deleted from CONTAINERS in orchestrator
-- All request to moon_interface generally end with a 200 HTTP code even if there is an error
+- When adding user or VM in GUI, there is a bug in the backend (manager ?)
+- GUI: in the "Projects" tab, move the "Map" link in the "Action" button
+- GUI: move tabs in this order : "Models, Policy, PDP, Projects"
Other actions:
@@ -35,5 +29,5 @@ Other actions:
- Write User and administrator documentation
- Run unit tests
- Add and run integration tests
-- moon_orchestrator in a docker
-- Add security on RabbitMQ transactions (auth+crypt)
+- Need to check if the Moon platform still can retrieve users and roles from Keystone
+- Need to retrieve VM from Nova
diff --git a/moonv4/bin/README.md b/moonv4/bin/README.md
new file mode 100644
index 00000000..3125c468
--- /dev/null
+++ b/moonv4/bin/README.md
@@ -0,0 +1,5 @@
+# Automated Tools/Scripts
+
+## moon_utilities_update
+- update moon_utilities to PIP: `./moon_utilities_update.sh upload`
+- locally update moon_utilities for each moon Python package: `./moon_utilities_update.sh copy` \ No newline at end of file
diff --git a/moonv4/bin/bootstrap.py b/moonv4/bin/bootstrap.py
index 85b3adfb..6f2a5e03 100644
--- a/moonv4/bin/bootstrap.py
+++ b/moonv4/bin/bootstrap.py
@@ -9,18 +9,12 @@ import base64
import mysql.connector
import re
import subprocess
-# import pika
-# import pika.credentials
-# import pika.exceptions
logging.basicConfig(level=logging.INFO)
log = logging.getLogger("moon.bootstrap")
requests_log = logging.getLogger("requests.packages.urllib3")
requests_log.setLevel(logging.WARNING)
requests_log.propagate = True
-pika_log = logging.getLogger("pika")
-pika_log.setLevel(logging.ERROR)
-pika_log.propagate = True
if len(sys.argv) == 2:
if os.path.isfile(sys.argv[1]):
@@ -85,7 +79,9 @@ def get(key):
def start_consul(data_config):
cmd = ["docker", "run", "-d", "--net=moon", "--name=consul", "--hostname=consul", "-p", "8500:8500", "consul"]
- output = subprocess.run(cmd)
+ output = subprocess.run(cmd,
+ stdout=subprocess.PIPE,
+ stderr=subprocess.PIPE)
if output.returncode != 0:
log.info(" ".join(cmd))
log.info(output.returncode)
@@ -134,13 +130,14 @@ def start_database():
cmd = ["docker", "run", "-dti", "--net=moon", "--hostname=db", "--name=db",
"-e", "MYSQL_ROOT_PASSWORD=p4sswOrd1", "-e", "MYSQL_DATABASE=moon", "-e", "MYSQL_USER=moon",
"-e", "MYSQL_PASSWORD=p4sswOrd1", "-p", "3306:3306", "mysql:latest"]
- output = subprocess.run(cmd)
+ output = subprocess.run(cmd,
+ stdout=subprocess.PIPE,
+ stderr=subprocess.PIPE)
if output.returncode != 0:
log.info(cmd)
log.error(output.stderr)
log.error(output.stdout)
raise Exception("Error starting DB container!")
- log.info(get("database"))
for database in get("database"):
database_url = database['url']
match = re.search("(?P<proto>^[\\w+]+):\/\/(?P<user>\\w+):(?P<password>.+)@(?P<host>\\w+):*(?P<port>\\d*)",
@@ -161,50 +158,20 @@ def start_database():
continue
else:
log.info("Database is up, populating it...")
- output = subprocess.run(["moon_db_manager", "upgrade"])
+ output = subprocess.run(["moon_db_manager", "upgrade"],
+ stdout=subprocess.PIPE,
+ stderr=subprocess.PIPE)
if output.returncode != 0:
raise Exception("Error populating the database!")
break
-def wait_for_message_queue():
- for messenger in get("messenger"):
- url = messenger['url']
- match = re.search("(?P<proto>^[\\w+]+):\/\/(?P<user>\\w+):(?P<password>.+)@(?P<host>\\w+):?(?P<port>\\d*)/?(?P<virtual_host>\\w+)",
- url)
- config = match.groupdict()
- while True:
- try:
- connection = pika.BlockingConnection(
- pika.ConnectionParameters(
- host=config['host'],
- port=int(config['port']),
- virtual_host=config['virtual_host'],
- credentials=pika.credentials.PlainCredentials(
- config['user'],
- config['password']
- )
- )
- )
- connection.close()
- except (
- pika.exceptions.ProbableAuthenticationError,
- pika.exceptions.ConnectionClosed,
- ConnectionResetError,
- pika.exceptions.IncompatibleProtocolError
- ):
- log.info("Waiting for MessageQueue ({})".format(config["host"]))
- time.sleep(1)
- continue
- else:
- log.info("MessageQueue is up")
- break
-
-
def start_keystone():
output = subprocess.run(["docker", "run", "-dti", "--net=moon", "--hostname=keystone", "--name=keystone",
"-e", "DB_HOST=db", "-e", "DB_PASSWORD_ROOT=p4sswOrd1", "-p", "35357:35357",
- "-p", "5000:5000", "keystone:mitaka"])
+ "-p", "5000:5000", "keystone:mitaka"],
+ stdout=subprocess.PIPE,
+ stderr=subprocess.PIPE)
if output.returncode != 0:
raise Exception("Error starting Keystone container!")
# TODO: Keystone answers request too quickly
@@ -214,6 +181,7 @@ def start_keystone():
for config in get("openstack/keystone"):
while True:
try:
+ time.sleep(1)
req = requests.get(config["url"])
except requests.exceptions.ConnectionError:
log.info("Waiting for Keystone ({})".format(config["url"]))
@@ -226,40 +194,42 @@ def start_keystone():
def start_moon(data_config):
cmds = [
- ["docker", "run", "-dti", "--net=moon", "--name=wrapper", "--hostname=wrapper", "-p",
- "{0}:{0}".format(data_config['components']['wrapper']['port']),
- data_config['components']['wrapper']['container']],
- ["docker", "run", "-dti", "--net=moon", "--name=interface", "--hostname=interface", "-p",
- "{0}:{0}".format(data_config['components']['interface']['port']),
- data_config['components']['interface']['container']],
- ["docker", "run", "-dti", "--net=moon", "--name=manager", "--hostname=manager", "-p",
+ # ["docker", "run", "-dti", "--net=moon", "--name=wrapper", "--hostname=wrapper", "-p",
+ # "{0}:{0}".format(data_config['components']['wrapper']['port']),
+ # data_config['components']['wrapper']['container']],
+ ["docker", "run", "-dti", "--net=moon", "--name=manager",
+ "--hostname=manager", "-p",
"{0}:{0}".format(data_config['components']['manager']['port']),
data_config['components']['manager']['container']],
+ ["docker", "run", "-dti", "--net=moon", "--name=interface",
+ "--hostname=interface", "-p",
+ "{0}:{0}".format(data_config['components']['interface']['port']),
+ data_config['components']['interface']['container']],
]
for cmd in cmds:
- log.warning("Start {} ?".format(cmd[-1]))
- answer = input()
- if answer.lower() in ("y", "yes", "o", "oui"):
- output = subprocess.run(cmd)
- if output.returncode != 0:
- log.info(" ".join(cmd))
- log.info(output.returncode)
- log.error(output.stderr)
- log.error(output.stdout)
- raise Exception("Error starting {} container!".format(cmd[-1]))
+ log.warning("Start {}".format(cmd[-1]))
+ # answer = input()
+ # if answer.lower() in ("y", "yes", "o", "oui"):
+ output = subprocess.run(cmd,
+ stdout=subprocess.PIPE,
+ stderr=subprocess.PIPE)
+ time.sleep(3)
+ if output.returncode != 0:
+ log.info(" ".join(cmd))
+ log.info(output.returncode)
+ log.error(output.stderr)
+ log.error(output.stdout)
+ raise Exception("Error starting {} container!".format(cmd[-1]))
subprocess.run(["docker", "ps"])
def main():
data_config = search_config_file()
- subprocess.run(["docker", "rm", "-f", "consul", "db", "manager", "wrapper", "interface", "authz*"])
+ subprocess.run(["docker", "rm", "-f", "consul", "db", "manager", "wrapper", "interface", "authz*", "keystone"])
start_consul(data_config)
start_database()
start_keystone()
start_moon(data_config)
- # wait_for_message_queue()
- # import moon_orchestrator.server
- # moon_orchestrator.server.main()
main()
diff --git a/moonv4/bin/delete_orchestrator.sh b/moonv4/bin/delete_orchestrator.sh
new file mode 100644
index 00000000..95fcfddd
--- /dev/null
+++ b/moonv4/bin/delete_orchestrator.sh
@@ -0,0 +1,63 @@
+#!/usr/bin/env bash
+
+set +x
+
+kubectl delete -n moon -f kubernetes/templates/moon_orchestrator.yaml
+for i in $(kubectl get deployments -n moon | grep wrapper | cut -d " " -f 1 | xargs); do
+ kubectl delete deployments/$i -n moon;
+done
+for i in $(kubectl get deployments -n moon | grep interface | cut -d " " -f 1 | xargs); do
+ kubectl delete deployments/$i -n moon;
+done
+for i in $(kubectl get deployments -n moon | grep authz | cut -d " " -f 1 | xargs); do
+ kubectl delete deployments/$i -n moon;
+done
+for i in $(kubectl get services -n moon | grep wrapper | cut -d " " -f 1 | xargs); do
+ kubectl delete services/$i -n moon;
+done
+for i in $(kubectl get services -n moon | grep interface | cut -d " " -f 1 | xargs); do
+ kubectl delete services/$i -n moon;
+done
+for i in $(kubectl get services -n moon | grep authz | cut -d " " -f 1 | xargs); do
+ kubectl delete services/$i -n moon;
+done
+
+if [ "$1" = "build" ]; then
+
+ DOCKER_ARGS=""
+
+ cd moon_manager
+ docker build -t wukongsun/moon_manager:v4.3.1 . ${DOCKER_ARGS}
+ if [ "$2" = "push" ]; then
+ docker push wukongsun/moon_manager:v4.3.1
+ fi
+ cd -
+
+ cd moon_orchestrator
+ docker build -t wukongsun/moon_orchestrator:v4.3 . ${DOCKER_ARGS}
+ if [ "$2" = "push" ]; then
+ docker push wukongsun/moon_orchestrator:v4.3
+ fi
+ cd -
+
+ cd moon_interface
+ docker build -t wukongsun/moon_interface:v4.3 . ${DOCKER_ARGS}
+ if [ "$2" = "push" ]; then
+ docker push wukongsun/moon_interface:v4.3
+ fi
+ cd -
+
+ cd moon_authz
+ docker build -t wukongsun/moon_authz:v4.3 . ${DOCKER_ARGS}
+ if [ "$2" = "push" ]; then
+ docker push wukongsun/moon_authz:v4.3
+ fi
+ cd -
+
+ cd moon_wrapper
+ docker build -t wukongsun/moon_wrapper:v4.3 . ${DOCKER_ARGS}
+ if [ "$2" = "push" ]; then
+ docker push wukongsun/moon_wrapper:v4.3
+ fi
+ cd -
+fi
diff --git a/moonv4/bin/moon_lib_update.sh b/moonv4/bin/moon_lib_update.sh
new file mode 100644
index 00000000..1d9d4cb3
--- /dev/null
+++ b/moonv4/bin/moon_lib_update.sh
@@ -0,0 +1,43 @@
+#!/usr/bin/env bash
+
+# usage: moon_update.sh {build,upload,copy} {db,utilities} <GPG_ID>
+
+CMD=$1
+COMPONENT=$2
+GPG_ID=$3
+
+VERSION=moon_${COMPONENT}-$(grep __version__ moon_${COMPONENT}/moon_${COMPONENT}/__init__.py | cut -d "\"" -f 2)
+
+cd moon_${COMPONENT}
+
+python3 setup.py sdist bdist_wheel
+
+if [ "$CMD" = "upload" ]; then
+ # Instead of "A0A96E75", use your own GPG ID
+ rm dist/*.asc 2>/dev/null
+ gpg --detach-sign -u "${GPG_ID}" -a dist/${VERSION}-py3-none-any.whl
+ gpg --detach-sign -u "${GPG_ID}" -a dist/${VERSION}.tar.gz
+ twine upload dist/${VERSION}-py3-none-any.whl dist/${VERSION}-py3-none-any.whl.asc
+ twine upload dist/${VERSION}.tar.gz dist/${VERSION}.tar.gz.asc
+fi
+
+rm -f ../moon_manager/dist/moon_${COMPONENT}*
+rm -f ../moon_orchestrator/dist/moon_${COMPONENT}*
+rm -f ../moon_wrapper/dist/moon_${COMPONENT}*
+rm -f ../moon_interface/dist/moon_${COMPONENT}*
+rm -f ../moon_authz/dist/moon_${COMPONENT}*
+
+
+if [ "$CMD" = "copy" ]; then
+ mkdir -p ../moon_manager/dist/ 2>/dev/null
+ cp -v dist/${VERSION}-py3-none-any.whl ../moon_manager/dist/
+ mkdir -p ../moon_orchestrator/dist/ 2>/dev/null
+ cp -v dist/${VERSION}-py3-none-any.whl ../moon_orchestrator/dist/
+ mkdir -p ../moon_wrapper/dist/ 2>/dev/null
+ cp -v dist/${VERSION}-py3-none-any.whl ../moon_wrapper/dist/
+ mkdir -p ../moon_interface/dist/ 2>/dev/null
+ cp -v dist/${VERSION}-py3-none-any.whl ../moon_interface/dist/
+ mkdir -p ../moon_authz/dist/ 2>/dev/null
+ cp -v dist/${VERSION}-py3-none-any.whl ../moon_authz/dist/
+fi
+
diff --git a/moonv4/conf/moon.conf b/moonv4/conf/moon.conf
index 27213f04..a5a40ad2 100644
--- a/moonv4/conf/moon.conf
+++ b/moonv4/conf/moon.conf
@@ -2,20 +2,6 @@ database:
url: mysql+pymysql://moon:p4sswOrd1@db/moon
driver: sql
-messenger:
- url: rabbit://moon:p4sswOrd1@messenger:5672/moon
-
-docker:
- url: tcp://172.88.88.1:2376
- network: moon
-
-slave:
- name:
- master:
- url:
- login:
- password:
-
openstack:
keystone:
url: http://keystone:5000/v3
@@ -25,31 +11,46 @@ openstack:
project: admin
check_token: false
certificate: false
+ external:
+ url: http://keystone:30006/v3
plugins:
authz:
- container: wukongsun/moon_authz:v4.1
+ container: wukongsun/moon_authz:v4.3
+ port: 8081
session:
container: asteroide/session:latest
+ port: 8082
components:
interface:
- port: 8081
+ port: 8080
bind: 0.0.0.0
hostname: interface
- container: wukongsun/moon_interface:v4.1
+ container: wukongsun/moon_interface:v4.3
+ orchestrator:
+ port: 8083
+ bind: 0.0.0.0
+ hostname: orchestrator
+ container: wukongsun/moon_orchestrator:v4.3
+ external:
+ port: 30003
+ hostname: orchestrator
wrapper:
port: 8080
bind: 0.0.0.0
hostname: wrapper
- container: wukongsun/moon_wrapper:v4.1
+ container: wukongsun/moon_wrapper:v4.3.1
timeout: 5
manager:
port: 8082
bind: 0.0.0.0
hostname: manager
- container: wukongsun/moon_manager:v4.1
- port_start: 38001
+ container: wukongsun/moon_manager:v4.3.1
+ external:
+ port: 30001
+ hostname: manager
+ port_start: 31001
logging:
version: 1
diff --git a/moonv4/kubernetes/README.md b/moonv4/kubernetes/README.md
new file mode 100644
index 00000000..04d54924
--- /dev/null
+++ b/moonv4/kubernetes/README.md
@@ -0,0 +1,50 @@
+
+# Installation
+
+Choose the right deployment:
+
+## Minikube installation
+
+```bash
+curl -LO https://storage.googleapis.com/kubernetes-release/release/$(curl -s https://storage.googleapis.com/kubernetes-release/release/stable.txt)/bin/linux/amd64/kubectl
+chmod +x ./kubectl
+sudo mv ./kubectl /usr/local/bin/kubectl
+curl -Lo minikube https://storage.googleapis.com/minikube/releases/v0.21.0/minikube-linux-amd64 && chmod +x minikube && sudo mv minikube /usr/local/bin/
+```
+
+## Kubeadm installation
+
+see: https://kubernetes.io/docs/setup/independent/install-kubeadm/
+
+```bash
+apt-get update && apt-get install -y apt-transport-https
+curl -s https://packages.cloud.google.com/apt/doc/apt-key.gpg | apt-key add -
+cat <<EOF >/etc/apt/sources.list.d/kubernetes.list
+deb http://apt.kubernetes.io/ kubernetes-xenial main
+EOF
+apt-get update
+apt-get install -y kubelet kubeadm kubectl
+```
+
+# Platform
+
+## Creation
+
+Execute the script : init_k8s.sh
+
+```bash
+sudo bash init_k8s.sh
+watch kubectl get po --namespace=kube-system
+```
+
+Wait until all pods are in "Running" state (crtl-c to stop the watch command)
+
+## Execution
+
+Execute the script : start_moon.sh
+
+```bash
+sudo bash start_moon.sh
+watch kubectl get po --namespace=moon
+```
+
diff --git a/moonv4/kubernetes/conf/password_moon.txt b/moonv4/kubernetes/conf/password_moon.txt
new file mode 100644
index 00000000..bb9bcf7d
--- /dev/null
+++ b/moonv4/kubernetes/conf/password_moon.txt
@@ -0,0 +1 @@
+p4sswOrd1 \ No newline at end of file
diff --git a/moonv4/kubernetes/conf/password_root.txt b/moonv4/kubernetes/conf/password_root.txt
new file mode 100644
index 00000000..bb9bcf7d
--- /dev/null
+++ b/moonv4/kubernetes/conf/password_root.txt
@@ -0,0 +1 @@
+p4sswOrd1 \ No newline at end of file
diff --git a/moonv4/kubernetes/conf/ports.conf b/moonv4/kubernetes/conf/ports.conf
new file mode 100644
index 00000000..487945c0
--- /dev/null
+++ b/moonv4/kubernetes/conf/ports.conf
@@ -0,0 +1,24 @@
+manager:
+ port: 8082
+ kport: 30001
+gui:
+ port: 3000
+ kport: 30002
+orchestrator:
+ port: 8083
+ kport: 30003
+
+consul:
+ port: 8500
+ kport: 30005
+keystone:
+ port: 5000
+ kport: 30006
+
+wrapper:
+ port: 8080
+ kport: 30010
+interface:
+ port: 8080
+authz:
+ port: 8081
diff --git a/moonv4/kubernetes/init_k8s.sh b/moonv4/kubernetes/init_k8s.sh
new file mode 100644
index 00000000..6eb94e78
--- /dev/null
+++ b/moonv4/kubernetes/init_k8s.sh
@@ -0,0 +1,33 @@
+#!/usr/bin/env bash
+
+set -x
+
+sudo kubeadm reset
+
+sudo swapoff -a
+
+sudo kubeadm init --pod-network-cidr=192.168.0.0/16
+#sudo kubeadm init --pod-network-cidr=10.244.0.0/16
+
+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 kubernetes/templates/kube-dns.yaml
+
+kubectl taint nodes --all node-role.kubernetes.io/master-
+
+kubectl proxy&
+sleep 5
+echo =========================================
+kubectl get po --namespace=kube-system
+echo =========================================
+
+
diff --git a/moonv4/kubernetes/start_moon.sh b/moonv4/kubernetes/start_moon.sh
new file mode 100644
index 00000000..8121e319
--- /dev/null
+++ b/moonv4/kubernetes/start_moon.sh
@@ -0,0 +1,37 @@
+#!/usr/bin/env bash
+
+set -x
+
+kubectl create namespace moon
+kubectl create configmap moon-config --from-file conf/moon.conf -n moon
+kubectl create configmap config --from-file ~/.kube/config -n moon
+kubectl create secret generic mysql-root-pass --from-file=kubernetes/conf/password_root.txt -n moon
+kubectl create secret generic mysql-pass --from-file=kubernetes/conf/password_moon.txt -n moon
+
+kubectl create -n moon -f kubernetes/templates/consul.yaml
+kubectl create -n moon -f kubernetes/templates/db.yaml
+kubectl create -n moon -f kubernetes/templates/keystone.yaml
+
+echo =========================================
+kubectl get pods -n moon
+echo =========================================
+
+sleep 10
+kubectl create -n moon -f kubernetes/templates/moon_configuration.yaml
+
+echo Waiting for jobs moonforming
+sleep 5
+kubectl get jobs -n moon
+kubectl logs -n moon jobs/moonforming
+
+sleep 5
+
+kubectl create -n moon -f kubernetes/templates/moon_manager.yaml
+
+sleep 2
+
+kubectl create -n moon -f kubernetes/templates/moon_orchestrator.yaml
+
+kubectl create -n moon -f kubernetes/templates/moon_gui.yaml
+
+
diff --git a/moonv4/kubernetes/templates/consul.yaml b/moonv4/kubernetes/templates/consul.yaml
new file mode 100644
index 00000000..f0fb764e
--- /dev/null
+++ b/moonv4/kubernetes/templates/consul.yaml
@@ -0,0 +1,33 @@
+apiVersion: apps/v1beta1
+kind: Deployment
+metadata:
+ namespace: moon
+ name: consul
+spec:
+ replicas: 1
+ template:
+ metadata:
+ labels:
+ app: consul
+ spec:
+ hostname: consul
+ containers:
+ - name: consul
+ image: consul:latest
+ ports:
+ - containerPort: 8500
+---
+
+apiVersion: v1
+kind: Service
+metadata:
+ name: consul
+ namespace: moon
+spec:
+ ports:
+ - port: 8500
+ targetPort: 8500
+ nodePort: 30005
+ selector:
+ app: consul
+ type: NodePort
diff --git a/moonv4/kubernetes/templates/db.yaml b/moonv4/kubernetes/templates/db.yaml
new file mode 100644
index 00000000..38418643
--- /dev/null
+++ b/moonv4/kubernetes/templates/db.yaml
@@ -0,0 +1,84 @@
+#apiVersion: v1
+#kind: PersistentVolume
+#metadata:
+# name: local-pv-1
+# labels:
+# type: local
+#spec:
+# capacity:
+# storage: 5Gi
+# accessModes:
+# - ReadWriteOnce
+# hostPath:
+# path: /tmp/data/pv-1
+#---
+#
+#apiVersion: v1
+#kind: PersistentVolumeClaim
+#metadata:
+# name: mysql-pv-claim
+# labels:
+# platform: moon
+# app: db
+#spec:
+# accessModes:
+# - ReadWriteOnce
+# resources:
+# requests:
+# storage: 5Gi
+#---
+
+apiVersion: apps/v1beta1
+kind: Deployment
+metadata:
+ namespace: moon
+ name: db
+spec:
+ replicas: 1
+ strategy:
+ type: Recreate
+ template:
+ metadata:
+ labels:
+ app: db
+ spec:
+ containers:
+ - name: db
+ image: mysql:latest
+ env:
+ - name: MYSQL_DATABASE
+ value: "moon"
+ - name: MYSQL_USER
+ value: "moon"
+ - name: MYSQL_PASSWORD
+ valueFrom:
+ secretKeyRef:
+ name: mysql-pass
+ key: password_moon.txt
+ - name: MYSQL_ROOT_PASSWORD
+ valueFrom:
+ secretKeyRef:
+ name: mysql-root-pass
+ key: password_root.txt
+ ports:
+ - containerPort: 3306
+ name: mysql
+# volumeMounts:
+# - name: mysql-persistent-storage
+# mountPath: /var/lib/mysql
+# volumes:
+# - name: mysql-persistent-storage
+# persistentVolumeClaim:
+# claimName: mysql-pv-claim
+---
+apiVersion: v1
+kind: Service
+metadata:
+ namespace: moon
+ name: db
+spec:
+ ports:
+ - port: 3306
+ selector:
+ app: db
+--- \ No newline at end of file
diff --git a/moonv4/kubernetes/templates/keystone.yaml b/moonv4/kubernetes/templates/keystone.yaml
new file mode 100644
index 00000000..9d188758
--- /dev/null
+++ b/moonv4/kubernetes/templates/keystone.yaml
@@ -0,0 +1,39 @@
+apiVersion: apps/v1beta1
+kind: Deployment
+metadata:
+ namespace: moon
+ name: keystone
+spec:
+ replicas: 1
+ template:
+ metadata:
+ labels:
+ app: keystone
+ spec:
+ hostname: keystone
+ containers:
+ - name: keystone
+ image: asteroide/keystone:pike
+ env:
+ - name: KEYSTONE_HOSTNAME
+ value: "127.0.0.1"
+ - name: KEYSTONE_PORT
+ value: "30006"
+ ports:
+ - containerPort: 35357
+ containerPort: 5000
+---
+
+apiVersion: v1
+kind: Service
+metadata:
+ name: keystone
+ namespace: moon
+spec:
+ ports:
+ - port: 5000
+ targetPort: 5000
+ nodePort: 30006
+ selector:
+ app: keystone
+ type: NodePort
diff --git a/moonv4/kubernetes/templates/kube-dns.yaml b/moonv4/kubernetes/templates/kube-dns.yaml
new file mode 100644
index 00000000..c8f18fd8
--- /dev/null
+++ b/moonv4/kubernetes/templates/kube-dns.yaml
@@ -0,0 +1,183 @@
+apiVersion: extensions/v1beta1
+kind: Deployment
+metadata:
+ annotations:
+ deployment.kubernetes.io/revision: "2"
+ kubectl.kubernetes.io/last-applied-configuration: |
+ {"apiVersion":"extensions/v1beta1","kind":"Deployment","metadata":{"annotations":{"deployment.kubernetes.io/revision":"1"},"creationTimestamp":"2017-10-30T09:03:59Z","generation":1,"labels":{"k8s-app":"kube-dns"},"name":"kube-dns","namespace":"kube-system","resourceVersion":"556","selfLink":"/apis/extensions/v1beta1/namespaces/kube-system/deployments/kube-dns","uid":"4433b709-bd51-11e7-a055-80fa5b15034a"},"spec":{"replicas":1,"selector":{"matchLabels":{"k8s-app":"kube-dns"}},"strategy":{"rollingUpdate":{"maxSurge":"10%","maxUnavailable":0},"type":"RollingUpdate"},"template":{"metadata":{"creationTimestamp":null,"labels":{"k8s-app":"kube-dns"}},"spec":{"affinity":{"nodeAffinity":{"requiredDuringSchedulingIgnoredDuringExecution":{"nodeSelectorTerms":[{"matchExpressions":[{"key":"beta.kubernetes.io/arch","operator":"In","values":["amd64"]}]}]}}},"containers":[{"args":["--domain=cluster.local.","--dns-port=10053","--config-dir=/kube-dns-config","--v=2"],"env":[{"name":"PROMETHEUS_PORT","value":"10055"}],"image":"gcr.io/google_containers/k8s-dns-kube-dns-amd64:1.14.5","imagePullPolicy":"IfNotPresent","livenessProbe":{"failureThreshold":5,"httpGet":{"path":"/healthcheck/kubedns","port":10054,"scheme":"HTTP"},"initialDelaySeconds":60,"periodSeconds":10,"successThreshold":1,"timeoutSeconds":5},"name":"kubedns","ports":[{"containerPort":10053,"name":"dns-local","protocol":"UDP"},{"containerPort":10053,"name":"dns-tcp-local","protocol":"TCP"},{"containerPort":10055,"name":"metrics","protocol":"TCP"}],"readinessProbe":{"failureThreshold":3,"httpGet":{"path":"/readiness","port":8081,"scheme":"HTTP"},"initialDelaySeconds":3,"periodSeconds":10,"successThreshold":1,"timeoutSeconds":5},"resources":{"limits":{"memory":"170Mi"},"requests":{"cpu":"100m","memory":"70Mi"}},"terminationMessagePath":"/dev/termination-log","terminationMessagePolicy":"File","volumeMounts":[{"mountPath":"/kube-dns-config","name":"kube-dns-config"}]},{"args":["-v=2","-logtostderr","-configDir=/etc/k8s/dns/dnsmasq-nanny","-restartDnsmasq=true","--","-k","--cache-size=1000","--log-facility=-","--server=/cluster.local/127.0.0.1#10053","--server=/in-addr.arpa/127.0.0.1#10053","--server=/ip6.arpa/127.0.0.1#10053","--server=8.8.8.8"],"image":"gcr.io/google_containers/k8s-dns-dnsmasq-nanny-amd64:1.14.5","imagePullPolicy":"IfNotPresent","livenessProbe":{"failureThreshold":5,"httpGet":{"path":"/healthcheck/dnsmasq","port":10054,"scheme":"HTTP"},"initialDelaySeconds":60,"periodSeconds":10,"successThreshold":1,"timeoutSeconds":5},"name":"dnsmasq","ports":[{"containerPort":53,"name":"dns","protocol":"UDP"},{"containerPort":53,"name":"dns-tcp","protocol":"TCP"}],"resources":{"requests":{"cpu":"150m","memory":"20Mi"}},"terminationMessagePath":"/dev/termination-log","terminationMessagePolicy":"File","volumeMounts":[{"mountPath":"/etc/k8s/dns/dnsmasq-nanny","name":"kube-dns-config"}]},{"args":["--v=2","--logtostderr","--probe=kubedns,127.0.0.1:10053,kubernetes.default.svc.cluster.local,5,A","--probe=dnsmasq,127.0.0.1:53,kubernetes.default.svc.cluster.local,5,A"],"image":"gcr.io/google_containers/k8s-dns-sidecar-amd64:1.14.5","imagePullPolicy":"IfNotPresent","livenessProbe":{"failureThreshold":5,"httpGet":{"path":"/metrics","port":10054,"scheme":"HTTP"},"initialDelaySeconds":60,"periodSeconds":10,"successThreshold":1,"timeoutSeconds":5},"name":"sidecar","ports":[{"containerPort":10054,"name":"metrics","protocol":"TCP"}],"resources":{"requests":{"cpu":"10m","memory":"20Mi"}},"terminationMessagePath":"/dev/termination-log","terminationMessagePolicy":"File"}],"dnsPolicy":"Default","restartPolicy":"Always","schedulerName":"default-scheduler","securityContext":{},"serviceAccount":"kube-dns","serviceAccountName":"kube-dns","terminationGracePeriodSeconds":30,"tolerations":[{"key":"CriticalAddonsOnly","operator":"Exists"},{"effect":"NoSchedule","key":"node-role.kubernetes.io/master"}],"volumes":[{"configMap":{"defaultMode":420,"name":"kube-dns","optional":true},"name":"kube-dns-config"}]}}},"status":{"availableReplicas":1,"conditions":[{"lastTransitionTime":"2017-10-30T09:05:11Z","lastUpdateTime":"2017-10-30T09:05:11Z","message":"Deployment has minimum availability.","reason":"MinimumReplicasAvailable","status":"True","type":"Available"}],"observedGeneration":1,"readyReplicas":1,"replicas":1,"updatedReplicas":1}}
+ creationTimestamp: 2017-10-30T09:03:59Z
+ generation: 2
+ labels:
+ k8s-app: kube-dns
+ name: kube-dns
+ namespace: kube-system
+ resourceVersion: "300076"
+ selfLink: /apis/extensions/v1beta1/namespaces/kube-system/deployments/kube-dns
+ uid: 4433b709-bd51-11e7-a055-80fa5b15034a
+spec:
+ replicas: 1
+ selector:
+ matchLabels:
+ k8s-app: kube-dns
+ strategy:
+ rollingUpdate:
+ maxSurge: 10%
+ maxUnavailable: 0
+ type: RollingUpdate
+ template:
+ metadata:
+ creationTimestamp: null
+ labels:
+ k8s-app: kube-dns
+ spec:
+ affinity:
+ nodeAffinity:
+ requiredDuringSchedulingIgnoredDuringExecution:
+ nodeSelectorTerms:
+ - matchExpressions:
+ - key: beta.kubernetes.io/arch
+ operator: In
+ values:
+ - amd64
+ containers:
+ - args:
+ - --domain=cluster.local.
+ - --dns-port=10053
+ - --config-dir=/kube-dns-config
+ - --v=2
+ env:
+ - name: PROMETHEUS_PORT
+ value: "10055"
+ image: gcr.io/google_containers/k8s-dns-kube-dns-amd64:1.14.5
+ imagePullPolicy: IfNotPresent
+ livenessProbe:
+ failureThreshold: 5
+ httpGet:
+ path: /healthcheck/kubedns
+ port: 10054
+ scheme: HTTP
+ initialDelaySeconds: 60
+ periodSeconds: 10
+ successThreshold: 1
+ timeoutSeconds: 5
+ name: kubedns
+ ports:
+ - containerPort: 10053
+ name: dns-local
+ protocol: UDP
+ - containerPort: 10053
+ name: dns-tcp-local
+ protocol: TCP
+ - containerPort: 10055
+ name: metrics
+ protocol: TCP
+ readinessProbe:
+ failureThreshold: 3
+ httpGet:
+ path: /readiness
+ port: 8081
+ scheme: HTTP
+ initialDelaySeconds: 3
+ periodSeconds: 10
+ successThreshold: 1
+ timeoutSeconds: 5
+ resources:
+ limits:
+ memory: 340Mi
+ requests:
+ cpu: 200m
+ memory: 140Mi
+ terminationMessagePath: /dev/termination-log
+ terminationMessagePolicy: File
+ volumeMounts:
+ - mountPath: /kube-dns-config
+ name: kube-dns-config
+ - args:
+ - -v=2
+ - -logtostderr
+ - -configDir=/etc/k8s/dns/dnsmasq-nanny
+ - -restartDnsmasq=true
+ - --
+ - -k
+ - --dns-forward-max=300
+ - --cache-size=1000
+ - --log-facility=-
+ - --server=/cluster.local/127.0.0.1#10053
+ - --server=/in-addr.arpa/127.0.0.1#10053
+ - --server=/ip6.arpa/127.0.0.1#10053
+ - --server=8.8.8.8
+ image: gcr.io/google_containers/k8s-dns-dnsmasq-nanny-amd64:1.14.5
+ imagePullPolicy: IfNotPresent
+ livenessProbe:
+ failureThreshold: 5
+ httpGet:
+ path: /healthcheck/dnsmasq
+ port: 10054
+ scheme: HTTP
+ initialDelaySeconds: 60
+ periodSeconds: 10
+ successThreshold: 1
+ timeoutSeconds: 5
+ name: dnsmasq
+ ports:
+ - containerPort: 53
+ name: dns
+ protocol: UDP
+ - containerPort: 53
+ name: dns-tcp
+ protocol: TCP
+ resources:
+ requests:
+ cpu: 150m
+ memory: 20Mi
+ terminationMessagePath: /dev/termination-log
+ terminationMessagePolicy: File
+ volumeMounts:
+ - mountPath: /etc/k8s/dns/dnsmasq-nanny
+ name: kube-dns-config
+ - args:
+ - --v=2
+ - --logtostderr
+ - --probe=kubedns,127.0.0.1:10053,kubernetes.default.svc.cluster.local,5,A
+ - --probe=dnsmasq,127.0.0.1:53,kubernetes.default.svc.cluster.local,5,A
+ image: gcr.io/google_containers/k8s-dns-sidecar-amd64:1.14.5
+ imagePullPolicy: IfNotPresent
+ livenessProbe:
+ failureThreshold: 5
+ httpGet:
+ path: /metrics
+ port: 10054
+ scheme: HTTP
+ initialDelaySeconds: 60
+ periodSeconds: 10
+ successThreshold: 1
+ timeoutSeconds: 5
+ name: sidecar
+ ports:
+ - containerPort: 10054
+ name: metrics
+ protocol: TCP
+ resources:
+ requests:
+ cpu: 10m
+ memory: 20Mi
+ terminationMessagePath: /dev/termination-log
+ terminationMessagePolicy: File
+ dnsPolicy: Default
+ restartPolicy: Always
+ schedulerName: default-scheduler
+ securityContext: {}
+ serviceAccount: kube-dns
+ serviceAccountName: kube-dns
+ terminationGracePeriodSeconds: 30
+ tolerations:
+ - key: CriticalAddonsOnly
+ operator: Exists
+ - effect: NoSchedule
+ key: node-role.kubernetes.io/master
+ volumes:
+ - configMap:
+ defaultMode: 420
+ name: kube-dns
+ optional: true
+ name: kube-dns-config
diff --git a/moonv4/kubernetes/templates/moon_configuration.yaml b/moonv4/kubernetes/templates/moon_configuration.yaml
new file mode 100644
index 00000000..3bcaa533
--- /dev/null
+++ b/moonv4/kubernetes/templates/moon_configuration.yaml
@@ -0,0 +1,25 @@
+apiVersion: batch/v1
+kind: Job
+metadata:
+ name: moonforming
+ namespace: moon
+spec:
+ template:
+ metadata:
+ name: moonforming
+ spec:
+ containers:
+ - name: moonforming
+ image: asteroide/moonforming:v1.3
+ env:
+ - name: POPULATE_ARGS
+ value: "--verbose" # debug mode: --debug
+ volumeMounts:
+ - name: config-volume
+ mountPath: /etc/moon
+ volumes:
+ - name: config-volume
+ configMap:
+ name: moon-config
+ restartPolicy: Never
+ #backoffLimit: 4 \ No newline at end of file
diff --git a/moonv4/kubernetes/templates/moon_gui.yaml b/moonv4/kubernetes/templates/moon_gui.yaml
new file mode 100644
index 00000000..2d355216
--- /dev/null
+++ b/moonv4/kubernetes/templates/moon_gui.yaml
@@ -0,0 +1,42 @@
+apiVersion: apps/v1beta1
+kind: Deployment
+metadata:
+ namespace: moon
+ name: gui
+spec:
+ replicas: 1
+ template:
+ metadata:
+ labels:
+ app: gui
+ spec:
+ hostname: gui
+ containers:
+ - name: gui
+ image: wukongsun/moon_gui:v4.3.1
+ env:
+ - name: MANAGER_HOST
+ value: "127.0.0.1"
+ - name: MANAGER_PORT
+ value: "30001"
+ - name: KEYSTONE_HOST
+ value: "127.0.0.1"
+ - name: KEYSTONE_PORT
+ value: "30006"
+ ports:
+ - containerPort: 80
+---
+
+apiVersion: v1
+kind: Service
+metadata:
+ name: gui
+ namespace: moon
+spec:
+ ports:
+ - port: 80
+ targetPort: 80
+ nodePort: 30002
+ selector:
+ app: gui
+ type: NodePort
diff --git a/moonv4/kubernetes/templates/moon_manager.yaml b/moonv4/kubernetes/templates/moon_manager.yaml
new file mode 100644
index 00000000..9d4a09a8
--- /dev/null
+++ b/moonv4/kubernetes/templates/moon_manager.yaml
@@ -0,0 +1,33 @@
+apiVersion: apps/v1beta1
+kind: Deployment
+metadata:
+ name: manager
+ namespace: moon
+spec:
+ replicas: 3
+ template:
+ metadata:
+ labels:
+ app: manager
+ spec:
+ hostname: manager
+ containers:
+ - name: manager
+ image: wukongsun/moon_manager:v4.3.1
+ ports:
+ - containerPort: 8082
+---
+
+apiVersion: v1
+kind: Service
+metadata:
+ name: manager
+ namespace: moon
+spec:
+ ports:
+ - port: 8082
+ targetPort: 8082
+ nodePort: 30001
+ selector:
+ app: manager
+ type: NodePort
diff --git a/moonv4/kubernetes/templates/moon_orchestrator.yaml b/moonv4/kubernetes/templates/moon_orchestrator.yaml
new file mode 100644
index 00000000..419f2d52
--- /dev/null
+++ b/moonv4/kubernetes/templates/moon_orchestrator.yaml
@@ -0,0 +1,40 @@
+apiVersion: apps/v1beta1
+kind: Deployment
+metadata:
+ namespace: moon
+ name: orchestrator
+spec:
+ replicas: 1
+ template:
+ metadata:
+ labels:
+ app: orchestrator
+ spec:
+ hostname: orchestrator
+ containers:
+ - name: orchestrator
+ image: wukongsun/moon_orchestrator:v4.3
+ ports:
+ - containerPort: 8083
+ volumeMounts:
+ - name: config-volume
+ mountPath: /root/.kube
+ volumes:
+ - name: config-volume
+ configMap:
+ name: config
+---
+
+apiVersion: v1
+kind: Service
+metadata:
+ name: orchestrator
+ namespace: moon
+spec:
+ ports:
+ - port: 8083
+ targetPort: 8083
+ nodePort: 30003
+ selector:
+ app: orchestrator
+ type: NodePort
diff --git a/moonv4/moon_authz/Dockerfile b/moonv4/moon_authz/Dockerfile
index 6ecc8f2d..4189c333 100644
--- a/moonv4/moon_authz/Dockerfile
+++ b/moonv4/moon_authz/Dockerfile
@@ -1,13 +1,12 @@
FROM ubuntu:latest
-ENV UUID=null
-
RUN apt update && apt install python3.5 python3-pip -y
-RUN pip3 install moon_utilities moon_db pip --upgrade
+RUN pip3 install pip --upgrade
ADD . /root
WORKDIR /root/
-RUN pip3 install -r requirements.txt
+RUN pip3 install -r requirements.txt --upgrade
+#RUN pip3 install /root/dist/* --upgrade
RUN pip3 install .
CMD ["python3", "-m", "moon_authz"] \ No newline at end of file
diff --git a/moonv4/moon_authz/LICENSE b/moonv4/moon_authz/LICENSE
index 4143aac2..d6456956 100644
--- a/moonv4/moon_authz/LICENSE
+++ b/moonv4/moon_authz/LICENSE
@@ -174,31 +174,29 @@
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
---- License for python-keystoneclient versions prior to 2.1 ---
-
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
-
- 1. Redistributions of source code must retain the above copyright notice,
- this list of conditions and the following disclaimer.
-
- 2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-
- 3. Neither the name of this project nor the names of its contributors may
- be used to endorse or promote products derived from this software without
- specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
-FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
-SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
-CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
-OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ END OF TERMS AND CONDITIONS
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright [yyyy] [name of copyright owner]
+
+ 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.
diff --git a/moonv4/moon_authz/moon_authz/__main__.py b/moonv4/moon_authz/moon_authz/__main__.py
index be483962..699c008c 100644
--- a/moonv4/moon_authz/moon_authz/__main__.py
+++ b/moonv4/moon_authz/moon_authz/__main__.py
@@ -1,3 +1,4 @@
from moon_authz.server import main
-main()
+server = main()
+server.run()
diff --git a/moonv4/moon_authz/moon_authz/api/authorization.py b/moonv4/moon_authz/moon_authz/api/authorization.py
index 94f1e13d..caa41082 100644
--- a/moonv4/moon_authz/moon_authz/api/authorization.py
+++ b/moonv4/moon_authz/moon_authz/api/authorization.py
@@ -3,17 +3,15 @@
# license which can be found in the file 'LICENSE' in this package distribution
# or at 'http://www.apache.org/licenses/LICENSE-2.0'.
-import hashlib
+import binascii
import itertools
-from oslo_log import log as logging
-from oslo_config import cfg
-import oslo_messaging
-from moon_utilities.security_functions import call, Context, notify
-from moon_utilities.misc import get_uuid_from_name
+import pickle
+from uuid import uuid4
+import logging
from moon_utilities import exceptions
-from moon_db.core import PDPManager
-from moon_db.core import ModelManager
-from moon_db.core import PolicyManager
+import flask
+from flask import request
+from flask_restful import Resource
# TODO (asteroide):
# - end the dev of the context
@@ -21,43 +19,85 @@ from moon_db.core import PolicyManager
# - call the next security function
# - call the master if an element is absent
-LOG = logging.getLogger(__name__)
-CONF = cfg.CONF
+LOG = logging.getLogger("moon.api." + __name__)
-class Authorization(object):
+class Authz(Resource):
"""
- Retrieve the current status of all components.
+ Endpoint for authz requests
"""
+ __urls__ = (
+ "/authz",
+ "/authz/",
+ "/authz/<string:uuid>/<string:subject_name>/<string:object_name>/<string:action_name>",
+ )
__version__ = "0.1.0"
pdp_id = None
meta_rule_id = None
keystone_project_id = None
payload = None
- def __init__(self, component_desc):
- self.component_id = component_desc
- LOG.info("ext={}".format(component_desc))
- self.filter_rule = oslo_messaging.NotificationFilter(
- event_type='^authz$',
- context={'container_id': "\w+_"+hashlib.sha224(component_desc.encode("utf-8")).hexdigest()}
- )
+ def __init__(self, **kwargs):
+ component_data = kwargs.get("component_data", {})
+ self.component_id = component_data['component_id']
+ self.pdp_id = component_data['pdp_id']
+ self.meta_rule_id = component_data['meta_rule_id']
+ self.keystone_project_id = component_data['keystone_project_id']
+ self.cache = kwargs.get("cache")
+ self.context = None
- for _id_value in component_desc.split("_"):
- _type, _id = _id_value.split(":")
- if _type == "pdp":
- self.pdp_id = _id
- elif _type == "metarule":
- self.meta_rule_id = _id
- elif _type == "project":
- self.keystone_project_id = _id
+ def post(self, uuid=None, subject_name=None, object_name=None, action_name=None):
+ """Get a response on an authorization request
- def __check_rules(self, context):
+ :param uuid: uuid of a tenant or an intra_extension
+ :param subject_name: name of the subject or the request
+ :param object_name: name of the object
+ :param action_name: name of the action
+ :return: {
+ "args": {},
+ "ctx": {
+ "action_name": "4567",
+ "id": "123456",
+ "method": "authz",
+ "object_name": "234567",
+ "subject_name": "123456",
+ "user_id": "admin"
+ },
+ "error": {
+ "code": 500,
+ "description": "",
+ "title": "Moon Error"
+ },
+ "intra_extension_id": "123456",
+ "result": false
+ }
+ :internal_api: authz
+ """
+ self.context = pickle.loads(request.data)
+ self.context.set_cache(self.cache)
+ self.context.increment_index()
+ self.run()
+ self.context.delete_cache()
+ response = flask.make_response(pickle.dumps(self.context))
+ response.headers['content-type'] = 'application/octet-stream'
+ return response
+
+ def run(self):
+ LOG.info("self.context.pdp_set={}".format(self.context.pdp_set))
+ result, message = self.__check_rules()
+ if result:
+ return self.__exec_instructions(result)
+ else:
+ self.context.current_state = "deny"
+ # self.__exec_next_state(result)
+ return
+
+ def __check_rules(self):
scopes_list = list()
- current_header_id = context['headers'][context['index']]
- Context.update_target(context)
- current_pdp = context['pdp_set'][current_header_id]
+ current_header_id = self.context.headers[self.context.index]
+ # Context.update_target(context)
+ current_pdp = self.context.pdp_set[current_header_id]
category_list = list()
category_list.extend(current_pdp["meta_rules"]["subject_categories"])
category_list.extend(current_pdp["meta_rules"]["object_categories"])
@@ -65,13 +105,12 @@ class Authorization(object):
for category in category_list:
scope = list(current_pdp['target'][category])
scopes_list.append(scope)
- policy_id = PolicyManager.get_policy_from_meta_rules("admin", current_header_id)
- rules = PolicyManager.get_rules(user_id="admin",
- policy_id=policy_id,
- meta_rule_id=current_header_id)
+ # policy_id = self.cache.get_policy_from_meta_rules("admin", current_header_id)
+
for item in itertools.product(*scopes_list):
req = list(item)
- for rule in rules['rules']:
+ for rule in self.cache.rules[self.context.current_policy_id]["rules"]:
+ LOG.info("rule={}".format(rule))
if req == rule['rule']:
return rule['instructions'], ""
LOG.warning("No rule match the request...")
@@ -84,13 +123,12 @@ class Authorization(object):
except ValueError:
LOG.error("Cannot understand value in instruction ({})".format(target))
return False
- pdp_set = self.payload["authz_context"]['pdp_set']
- for meta_rule_id in self.payload["authz_context"]['pdp_set']:
- policy_id = PolicyManager.get_policy_from_meta_rules("admin", meta_rule_id)
+ # pdp_set = self.payload["authz_context"]['pdp_set']
+ for meta_rule_id in self.context.pdp_set:
if meta_rule_id == "effect":
continue
- if pdp_set[meta_rule_id]["meta_rules"]["name"] == policy_name:
- for category_id, category_value in ModelManager.get_subject_categories("admin").items():
+ if self.context.pdp_set[meta_rule_id]["meta_rules"]["name"] == policy_name:
+ for category_id, category_value in self.cache.subject_categories.items():
if category_value["name"] == "role":
subject_category_id = category_id
break
@@ -131,95 +169,96 @@ class Authorization(object):
return self.payload["container_chaining"][index]
def __update_headers(self, name):
- context = self.payload["authz_context"]
- for meta_rule_id, meta_rule_value in context["pdp_set"].items():
+ # context = self.payload["authz_context"]
+ for meta_rule_id, meta_rule_value in self.context.pdp_set.items():
if meta_rule_id == "effect":
continue
if meta_rule_value["meta_rules"]["name"] == name:
- self.payload["authz_context"]['headers'].append(meta_rule_id)
+ self.context.headers.append(meta_rule_id)
return True
return False
- def __exec_next_state(self, rule_found):
- index = self.payload["authz_context"]['index']
- current_meta_rule = self.payload["authz_context"]['headers'][index]
- current_container = self.__get_container_from_meta_rule(current_meta_rule)
- current_container_genre = current_container["genre"]
- try:
- next_meta_rule = self.payload["authz_context"]['headers'][index+1]
- except IndexError:
- next_meta_rule = None
- if current_container_genre == "authz":
- if rule_found:
- return self.__return_to_router()
- pass
- if next_meta_rule:
- # next will be session if current is deny and session is unset
- if self.payload["authz_context"]['pdp_set'][next_meta_rule]['effect'] == "unset":
- return notify(
- request_id=self.payload["authz_context"]["request_id"],
- container_id=self.__get_container_from_meta_rule(next_meta_rule)['container_id'],
- payload=self.payload)
- # next will be delegation if current is deny and session is passed or deny and delegation is unset
- else:
- LOG.error("Delegation is not developed!")
+ # def __exec_next_state(self, rule_found):
+ # index = self.context.index
+ # current_meta_rule = self.context.headers[index]
+ # current_container = self.__get_container_from_meta_rule(current_meta_rule)
+ # current_container_genre = current_container["genre"]
+ # try:
+ # next_meta_rule = self.context.headers[index + 1]
+ # except IndexError:
+ # next_meta_rule = None
+ # if current_container_genre == "authz":
+ # if rule_found:
+ # return True
+ # pass
+ # if next_meta_rule:
+ # # next will be session if current is deny and session is unset
+ # if self.payload["authz_context"]['pdp_set'][next_meta_rule]['effect'] == "unset":
+ # return notify(
+ # request_id=self.payload["authz_context"]["request_id"],
+ # container_id=self.__get_container_from_meta_rule(next_meta_rule)['container_id'],
+ # payload=self.payload)
+ # # next will be delegation if current is deny and session is passed or deny and delegation is unset
+ # else:
+ # LOG.error("Delegation is not developed!")
+ #
+ # else:
+ # # else next will be None and the request is sent to router
+ # return self.__return_to_router()
+ # elif current_container_genre == "session":
+ # pass
+ # # next will be next container in headers if current is passed
+ # if self.payload["authz_context"]['pdp_set'][current_meta_rule]['effect'] == "passed":
+ # return notify(
+ # request_id=self.payload["authz_context"]["request_id"],
+ # container_id=self.__get_container_from_meta_rule(next_meta_rule)['container_id'],
+ # payload=self.payload)
+ # # next will be None if current is grant and the request is sent to router
+ # else:
+ # return self.__return_to_router()
+ # elif current_container_genre == "delegation":
+ # LOG.error("Delegation is not developed!")
+ # # next will be authz if current is deny
+ # # next will be None if current is grant and the request is sent to router
- else:
- # else next will be None and the request is sent to router
- return self.__return_to_router()
- elif current_container_genre == "session":
- pass
- # next will be next container in headers if current is passed
- if self.payload["authz_context"]['pdp_set'][current_meta_rule]['effect'] == "passed":
- return notify(
- request_id=self.payload["authz_context"]["request_id"],
- container_id=self.__get_container_from_meta_rule(next_meta_rule)['container_id'],
- payload=self.payload)
- # next will be None if current is grant and the request is sent to router
- else:
- return self.__return_to_router()
- elif current_container_genre == "delegation":
- LOG.error("Delegation is not developed!")
- # next will be authz if current is deny
- # next will be None if current is grant and the request is sent to router
-
- def __return_to_router(self):
- call(endpoint="security_router",
- ctx={"id": self.component_id,
- "call_master": False,
- "method": "return_authz",
- "request_id": self.payload["authz_context"]["request_id"]},
- method="route",
- args=self.payload["authz_context"])
+ # def __return_to_router(self):
+ # call(endpoint="security_router",
+ # ctx={"id": self.component_id,
+ # "call_master": False,
+ # "method": "return_authz",
+ # "request_id": self.payload["authz_context"]["request_id"]},
+ # method="route",
+ # args=self.payload["authz_context"])
def __exec_instructions(self, instructions):
- current_header_id = self.payload["authz_context"]['headers'][self.payload["authz_context"]['index']]
for instruction in instructions:
for key in instruction:
if key == "decision":
if instruction["decision"] == "grant":
- self.payload["authz_context"]['pdp_set'][current_header_id]["effect"] = "grant"
- self.__return_to_router()
+ self.context.current_state = "grant"
+ LOG.info("__exec_instructions True {}".format(
+ self.context.current_state))
+ return True
else:
- self.payload["authz_context"]['pdp_set'][current_header_id]["effect"] = instruction["decision"]
+ self.context.current_state = instruction["decision"].lower()
elif key == "chain":
result = self.__update_headers(**instruction["chain"])
if not result:
- self.payload["authz_context"]['pdp_set'][current_header_id]["effect"] = "deny"
+ self.context.current_state = "deny"
else:
- self.payload["authz_context"]['pdp_set'][current_header_id]["effect"] = "passed"
+ self.context.current_state = "passed"
elif key == "update":
result = self.__update_subject_category_in_policy(**instruction["update"])
if not result:
- self.payload["authz_context"]['pdp_set'][current_header_id]["effect"] = "deny"
+ self.context.current_state = "deny"
else:
- self.payload["authz_context"]['pdp_set'][current_header_id]["effect"] = "passed"
- # LOG.info("__exec_instructions {}".format(self.payload["authz_context"]))
+ self.context.current_state = "passed"
+ LOG.info("__exec_instructions False {}".format(self.context.current_state))
def __update_current_request(self):
index = self.payload["authz_context"]["index"]
current_header_id = self.payload["authz_context"]['headers'][index]
- previous_header_id = self.payload["authz_context"]['headers'][index-1]
+ previous_header_id = self.payload["authz_context"]['headers'][index - 1]
current_policy_id = PolicyManager.get_policy_from_meta_rules("admin", current_header_id)
previous_policy_id = PolicyManager.get_policy_from_meta_rules("admin", previous_header_id)
# FIXME (asteroide): must change those lines to be ubiquitous against any type of policy
@@ -233,11 +272,11 @@ class Authorization(object):
break
for assignment_id, assignment_value in PolicyManager.get_subject_assignments(
"admin", previous_policy_id, subject, subject_category_id).items():
- for data_id in assignment_value["assignments"]:
- data = PolicyManager.get_subject_data("admin", previous_policy_id, data_id, subject_category_id)
- for _data in data:
- for key, value in _data["data"].items():
- role_names.append(value["name"])
+ for data_id in assignment_value["assignments"]:
+ data = PolicyManager.get_subject_data("admin", previous_policy_id, data_id, subject_category_id)
+ for _data in data:
+ for key, value in _data["data"].items():
+ role_names.append(value["name"])
new_role_ids = []
for perimeter_id, perimeter_value in PolicyManager.get_objects("admin", current_policy_id).items():
if perimeter_value["name"] in role_names:
@@ -251,72 +290,65 @@ class Authorization(object):
self.payload["authz_context"]['current_request']['object'] = new_role_ids[0]
self.payload["authz_context"]['current_request']['action'] = perimeter_id
elif self.payload["authz_context"]['pdp_set'][current_header_id]['meta_rules']['name'] == "rbac":
- self.payload["authz_context"]['current_request']['subject'] = self.payload["authz_context"]['initial_request']['subject']
- self.payload["authz_context"]['current_request']['object'] = self.payload["authz_context"]['initial_request']['object']
- self.payload["authz_context"]['current_request']['action'] = self.payload["authz_context"]['initial_request']['action']
+ self.payload["authz_context"]['current_request']['subject'] = \
+ self.payload["authz_context"]['initial_request']['subject']
+ self.payload["authz_context"]['current_request']['object'] = \
+ self.payload["authz_context"]['initial_request']['object']
+ self.payload["authz_context"]['current_request']['action'] = \
+ self.payload["authz_context"]['initial_request']['action']
- def critical(self, ctxt, publisher_id, event_type, payload, metadata):
- """This is the authz endpoint
- but due to the oslo_messaging notification architecture, we must call it "critical"
-
- :param ctxt: context of the request
- :param publisher_id: ID of the publisher
- :param event_type: type of event ("authz" here)
- :param payload: content of the authz request
- :param metadata: metadata of the notification
- :return: result of the authorization for the current component
- """
- LOG.info("calling authz {} {}".format(ctxt, payload))
- self.keystone_project_id = payload["id"]
- self.payload = payload
+ def get_authz(self):
+ # self.keystone_project_id = payload["id"]
+ # LOG.info("get_authz {}".format(payload))
+ # self.payload = payload
try:
- if "authz_context" not in payload:
- try:
- self.payload["authz_context"] = Context(self.keystone_project_id,
- self.payload["subject_name"],
- self.payload["object_name"],
- self.payload["action_name"],
- self.payload["request_id"]).to_dict()
- except exceptions.SubjectUnknown:
- ctx = {
- "subject_name": self.payload["subject_name"],
- "object_name": self.payload["object_name"],
- "action_name": self.payload["action_name"],
- }
- call("moon_manager", method="update_from_master", ctx=ctx, args={})
- self.payload["authz_context"] = Context(self.keystone_project_id,
- self.payload["subject_name"],
- self.payload["object_name"],
- self.payload["action_name"],
- self.payload["request_id"]).to_dict()
- except exceptions.ObjectUnknown:
- ctx = {
- "subject_name": self.payload["subject_name"],
- "object_name": self.payload["object_name"],
- "action_name": self.payload["action_name"],
- }
- call("moon_manager", method="update_from_master", ctx=ctx, args={})
- self.payload["authz_context"] = Context(self.keystone_project_id,
- self.payload["subject_name"],
- self.payload["object_name"],
- self.payload["action_name"],
- self.payload["request_id"]).to_dict()
- except exceptions.ActionUnknown:
- ctx = {
- "subject_name": self.payload["subject_name"],
- "object_name": self.payload["object_name"],
- "action_name": self.payload["action_name"],
- }
- call("moon_manager", method="update_from_master", ctx=ctx, args={})
- self.payload["authz_context"] = Context(self.keystone_project_id,
- self.payload["subject_name"],
- self.payload["object_name"],
- self.payload["action_name"],
- self.payload["request_id"]).to_dict()
- self.__update_container_chaining()
- else:
- self.payload["authz_context"]["index"] += 1
- self.__update_current_request()
+ # if "authz_context" not in payload:
+ # try:
+ # self.payload["authz_context"] = Context(self.keystone_project_id,
+ # self.payload["subject_name"],
+ # self.payload["object_name"],
+ # self.payload["action_name"],
+ # self.payload["request_id"]).to_dict()
+ # except exceptions.SubjectUnknown:
+ # ctx = {
+ # "subject_name": self.payload["subject_name"],
+ # "object_name": self.payload["object_name"],
+ # "action_name": self.payload["action_name"],
+ # }
+ # call("moon_manager", method="update_from_master", ctx=ctx, args={})
+ # self.payload["authz_context"] = Context(self.keystone_project_id,
+ # self.payload["subject_name"],
+ # self.payload["object_name"],
+ # self.payload["action_name"],
+ # self.payload["request_id"]).to_dict()
+ # except exceptions.ObjectUnknown:
+ # ctx = {
+ # "subject_name": self.payload["subject_name"],
+ # "object_name": self.payload["object_name"],
+ # "action_name": self.payload["action_name"],
+ # }
+ # call("moon_manager", method="update_from_master", ctx=ctx, args={})
+ # self.payload["authz_context"] = Context(self.keystone_project_id,
+ # self.payload["subject_name"],
+ # self.payload["object_name"],
+ # self.payload["action_name"],
+ # self.payload["request_id"]).to_dict()
+ # except exceptions.ActionUnknown:
+ # ctx = {
+ # "subject_name": self.payload["subject_name"],
+ # "object_name": self.payload["object_name"],
+ # "action_name": self.payload["action_name"],
+ # }
+ # call("moon_manager", method="update_from_master", ctx=ctx, args={})
+ # self.payload["authz_context"] = Context(self.keystone_project_id,
+ # self.payload["subject_name"],
+ # self.payload["object_name"],
+ # self.payload["action_name"],
+ # self.payload["request_id"]).to_dict()
+ # self.__update_container_chaining()
+ # else:
+ # self.payload["authz_context"]["index"] += 1
+ # self.__update_current_request()
result, message = self.__check_rules(self.payload["authz_context"])
current_header_id = self.payload["authz_context"]['headers'][self.payload["authz_context"]['index']]
if result:
@@ -327,7 +359,7 @@ class Authorization(object):
return {"authz": result,
"error": message,
"pdp_id": self.pdp_id,
- "ctx": ctxt, "args": self.payload}
+ "args": self.payload}
except Exception as e:
try:
LOG.error(self.payload["authz_context"])
@@ -337,5 +369,8 @@ class Authorization(object):
return {"authz": False,
"error": str(e),
"pdp_id": self.pdp_id,
- "ctx": ctxt, "args": self.payload}
+ "args": self.payload}
+ def head(self, uuid=None, subject_name=None, object_name=None, action_name=None):
+ LOG.info("HEAD request")
+ return "", 200 \ No newline at end of file
diff --git a/moonv4/moon_authz/moon_authz/api/generic.py b/moonv4/moon_authz/moon_authz/api/generic.py
index db61188b..66169b15 100644
--- a/moonv4/moon_authz/moon_authz/api/generic.py
+++ b/moonv4/moon_authz/moon_authz/api/generic.py
@@ -2,27 +2,130 @@
# 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'.
+"""
+Those API are helping API used to manage the Moon platform.
+"""
+from flask_restful import Resource, request
+from oslo_log import log as logging
+import moon_authz.api
+from moon_utilities.security_functions import check_auth
-class Status(object):
+__version__ = "0.1.0"
+
+LOG = logging.getLogger("moon.authz.api." + __name__)
+
+
+class Status(Resource):
"""
- Retrieve the current status of all components.
+ Endpoint for status requests
"""
- __version__ = "0.1.0"
+ __urls__ = ("/status", "/status/", "/status/<string:component_id>")
- def get_status(self, ctx, args):
- return {"status": "Running"}
+ def get(self, component_id=None):
+ """Retrieve status of all components
+ :return: {
+ "orchestrator": {
+ "status": "Running"
+ },
+ "security_router": {
+ "status": "Running"
+ }
+ }
+ """
+ raise NotImplemented
-class Logs(object):
+
+class Logs(Resource):
"""
- Retrieve the current status of all components.
+ Endpoint for logs requests
"""
- __version__ = "0.1.0"
+ __urls__ = ("/logs", "/logs/", "/logs/<string:component_id>")
+
+ def get(self, component_id=None):
+ """Get logs from the Moon platform
+
+ :param component_id: the ID of the component your are looking for (optional)
+ :return: [
+ "2015-04-15-13:45:20
+ "2015-04-15-13:45:21
+ "2015-04-15-13:45:22
+ "2015-04-15-13:45:23
+ ]
+ """
+ filter_str = request.args.get('filter', '')
+ from_str = request.args.get('from', '')
+ to_str = request.args.get('to', '')
+ event_number = request.args.get('event_number', '')
+ try:
+ event_number = int(event_number)
+ except ValueError:
+ event_number = None
+ args = dict()
+ args["filter"] = filter_str
+ args["from"] = from_str
+ args["to"] = to_str
+ args["event_number"] = event_number
+
+ raise NotImplemented
+
+
+class API(Resource):
+ """
+ Endpoint for API requests
+ """
- def get_logs(self, ctx, args):
- return {"error": "NotImplemented"}
+ __urls__ = (
+ "/api",
+ "/api/",
+ "/api/<string:group_id>",
+ "/api/<string:group_id>/",
+ "/api/<string:group_id>/<string:endpoint_id>")
+ @check_auth
+ def get(self, group_id="", endpoint_id="", user_id=""):
+ """Retrieve all API endpoints or a specific endpoint if endpoint_id is given
+ :param group_id: the name of one existing group (ie generic, ...)
+ :param endpoint_id: the name of one existing component (ie Logs, Status, ...)
+ :return: {
+ "group_name": {
+ "endpoint_name": {
+ "description": "a description",
+ "methods": {
+ "get": "description of the HTTP method"
+ },
+ "urls": ('/api', '/api/', '/api/<string:endpoint_id>')
+ }
+ }
+ """
+ __methods = ("get", "post", "put", "delete", "options", "patch")
+ api_list = filter(lambda x: "__" not in x, dir(moon_authz.api))
+ api_desc = dict()
+ for api_name in api_list:
+ api_desc[api_name] = {}
+ group_api_obj = eval("moon_interface.api.{}".format(api_name))
+ api_desc[api_name]["description"] = group_api_obj.__doc__
+ if "__version__" in dir(group_api_obj):
+ api_desc[api_name]["version"] = group_api_obj.__version__
+ object_list = list(filter(lambda x: "__" not in x, dir(group_api_obj)))
+ for obj in map(lambda x: eval("moon_interface.api.{}.{}".format(api_name, x)), object_list):
+ if "__urls__" in dir(obj):
+ api_desc[api_name][obj.__name__] = dict()
+ api_desc[api_name][obj.__name__]["urls"] = obj.__urls__
+ api_desc[api_name][obj.__name__]["methods"] = dict()
+ for _method in filter(lambda x: x in __methods, dir(obj)):
+ docstring = eval("moon_interface.api.{}.{}.{}.__doc__".format(api_name, obj.__name__, _method))
+ api_desc[api_name][obj.__name__]["methods"][_method] = docstring
+ api_desc[api_name][obj.__name__]["description"] = str(obj.__doc__)
+ if group_id in api_desc:
+ if endpoint_id in api_desc[group_id]:
+ return {group_id: {endpoint_id: api_desc[group_id][endpoint_id]}}
+ elif len(endpoint_id) > 0:
+ LOG.error("Unknown endpoint_id {}".format(endpoint_id))
+ return {"error": "Unknown endpoint_id {}".format(endpoint_id)}
+ return {group_id: api_desc[group_id]}
+ return api_desc
diff --git a/moonv4/moon_consul/moon_consul/http_server.py b/moonv4/moon_authz/moon_authz/http_server.py
index c3d13378..b6818a9f 100644
--- a/moonv4/moon_consul/moon_consul/http_server.py
+++ b/moonv4/moon_authz/moon_authz/http_server.py
@@ -4,19 +4,18 @@
# or at 'http://www.apache.org/licenses/LICENSE-2.0'.
from flask import Flask, request
-from flask_cors import CORS, cross_origin
+# from flask_cors import CORS, cross_origin
from flask_restful import Resource, Api, reqparse
import logging
-from moon_consul import __version__
-from moon_consul.api.generic import API
-from moon_consul.api.database import Database
-from moon_consul.api.messenger import Messenger
-from moon_consul.api.openstack import Keystone
-from moon_consul.api.slave import Slave
-from moon_consul.api.system import Docker, Components
from moon_utilities import exceptions
+from moon_authz import __version__
+from moon_authz.api.authorization import Authz
+from moon_utilities.cache import Cache
-logger = logging.getLogger(__name__)
+logger = logging.getLogger("moon." + __name__)
+
+CACHE = Cache()
+CACHE.update()
class Server:
@@ -63,8 +62,7 @@ class Server:
raise NotImplementedError()
__API__ = (
- API,
- Database, Docker, Messenger, Keystone, Slave, Components
+ Authz,
)
@@ -90,15 +88,24 @@ class Root(Resource):
"tree": tree
}
+ def head(self):
+ return "", 201
+
class HTTPServer(Server):
- def __init__(self, host="localhost", port=80, conf=None, **kwargs):
+ def __init__(self, host="0.0.0.0", 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))
self.app = Flask(__name__)
- self.conf = conf
+ self._port = port
+ self._host = host
# Todo : specify only few urls instead of *
# CORS(self.app)
+ self.component_id = kwargs.get("component_id")
+ self.keystone_project_id = kwargs.get("keystone_project_id")
+ self.container_chaining = kwargs.get("container_chaining")
self.api = Api(self.app)
self.__set_route()
# self.__hook_errors()
@@ -122,13 +129,12 @@ class HTTPServer(Server):
self.api.add_resource(Root, '/')
for api in __API__:
- self.api.add_resource(
- api, *api.__urls__,
- resource_class_kwargs={
- "conf": self.conf,
- }
- )
+ self.api.add_resource(api, *api.__urls__,
+ resource_class_kwargs={
+ "component_data": self.component_data,
+ "cache": CACHE
+ }
+ )
def run(self):
- self.app.run(debug=True, host=self._host, port=self._port) # nosec
-
+ self.app.run(host=self._host, port=self._port) # nosec
diff --git a/moonv4/moon_authz/moon_authz/messenger.py b/moonv4/moon_authz/moon_authz/messenger.py
deleted file mode 100644
index 6fa34770..00000000
--- a/moonv4/moon_authz/moon_authz/messenger.py
+++ /dev/null
@@ -1,50 +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'.
-
-from oslo_config import cfg
-import oslo_messaging
-import time
-from oslo_log import log as logging
-from moon_authz.api.generic import Status, Logs
-from moon_authz.api.authorization import Authorization
-from moon_utilities.api import APIList
-
-LOG = logging.getLogger(__name__)
-CONF = cfg.CONF
-
-
-class Server:
-
- def __init__(self, component_id, keystone_project_id):
- self.TOPIC = "authz-workers"
- transport = oslo_messaging.get_notification_transport(cfg.CONF)
- targets = [
- oslo_messaging.Target(topic=self.TOPIC),
- ]
- self.endpoints = [
- APIList((Status, Logs)),
- Status(),
- Logs(),
- Authorization(component_id)
- ]
- pool = "authz-workers"
- self.server = oslo_messaging.get_notification_listener(transport, targets,
- self.endpoints, executor='threading',
- pool=pool)
- LOG.info("Starting MQ notification server with topic: {}".format(self.TOPIC))
-
- def run(self):
- try:
- self.server.start()
- while True:
- time.sleep(0.1)
- except KeyboardInterrupt:
- print("Stopping server by crtl+c")
- except SystemExit:
- print("Stopping server")
-
- self.server.stop()
-
-
diff --git a/moonv4/moon_authz/moon_authz/server.py b/moonv4/moon_authz/moon_authz/server.py
index 0c2a36ff..40143ba9 100644
--- a/moonv4/moon_authz/moon_authz/server.py
+++ b/moonv4/moon_authz/moon_authz/server.py
@@ -4,32 +4,44 @@
# or at 'http://www.apache.org/licenses/LICENSE-2.0'.
import os
-from oslo_config import cfg
from oslo_log import log as logging
-# cfg.CONF.register_cli_opt(cfg.StrOpt('function_type', positional=True,
-# help="The type of function managed by this component (example 'authz')."))
-cfg.CONF.register_cli_opt(cfg.StrOpt('uuid', positional=True,
- help="The ID of the component managed here."))
-cfg.CONF.register_cli_opt(cfg.StrOpt('keystone_project_id', positional=True,
- help="The ID of the component managed here."))
-from moon_utilities import options # noqa
-from moon_authz.messenger import Server
-
-LOG = logging.getLogger(__name__)
-CONF = cfg.CONF
+from moon_authz.http_server import HTTPServer as Server
+from moon_utilities import configuration
+
+LOG = logging.getLogger("moon.server")
DOMAIN = "moon_authz"
__CWD__ = os.path.dirname(os.path.abspath(__file__))
def main():
- component_id = CONF.uuid
- keystone_project_id = CONF.keystone_project_id
- # function_type = CONF.intra_extension_id.replace(component_id, "").strip('_')
- LOG.info("Starting server with IP {} on component {}".format(
- CONF.security_router.host, component_id))
- server = Server(component_id=component_id, keystone_project_id=keystone_project_id)
- server.run()
+ component_id = os.getenv("UUID")
+ component_type = os.getenv("TYPE")
+ tcp_port = os.getenv("PORT")
+ pdp_id = os.getenv("PDP_ID")
+ meta_rule_id = os.getenv("META_RULE_ID")
+ keystone_project_id = os.getenv("KEYSTONE_PROJECT_ID")
+ configuration.init_logging()
+ LOG.info("component_type={}".format(component_type))
+ conf = configuration.get_configuration("plugins/{}".format(component_type))
+ conf["plugins/{}".format(component_type)]['id'] = component_id
+ hostname = conf["plugins/{}".format(component_type)].get('hostname', component_id)
+ port = conf["plugins/{}".format(component_type)].get('port', tcp_port)
+ bind = conf["plugins/{}".format(component_type)].get('bind', "0.0.0.0")
+
+ LOG.info("Starting server with IP {} on port {} bind to {}".format(hostname, port, bind))
+ server = Server(
+ host=bind,
+ port=int(port),
+ component_data={
+ 'component_id': component_id,
+ 'component_type': component_type,
+ 'pdp_id': pdp_id,
+ 'meta_rule_id': meta_rule_id,
+ 'keystone_project_id': keystone_project_id,
+ }
+ )
+ return server
if __name__ == '__main__':
diff --git a/moonv4/moon_authz/requirements.txt b/moonv4/moon_authz/requirements.txt
index 8faf9439..344bec52 100644
--- a/moonv4/moon_authz/requirements.txt
+++ b/moonv4/moon_authz/requirements.txt
@@ -1 +1,8 @@
-kombu !=4.0.1,!=4.0.0 \ No newline at end of file
+kombu !=4.0.1,!=4.0.0
+oslo.log
+flask
+oslo.config
+flask_restful
+flask_cors
+moon_db
+moon_utilities
diff --git a/moonv4/moon_authz/tests/unit_python/conftest.py b/moonv4/moon_authz/tests/unit_python/conftest.py
new file mode 100644
index 00000000..a6e62078
--- /dev/null
+++ b/moonv4/moon_authz/tests/unit_python/conftest.py
@@ -0,0 +1,29 @@
+import pytest
+import requests_mock
+import mock_pods
+import os
+from utilities import CONTEXT
+
+
+@pytest.fixture
+def context():
+ return CONTEXT
+
+
+def set_env_variables():
+ os.environ['UUID'] = "1111111111"
+ os.environ['TYPE'] = "authz"
+ os.environ['PORT'] = "8081"
+ os.environ['PDP_ID'] = "b3d3e18abf3340e8b635fd49e6634ccd"
+ os.environ['META_RULE_ID'] = "f8f49a779ceb47b3ac810f01ef71b4e0"
+ os.environ['KEYSTONE_PROJECT_ID'] = CONTEXT['project_id']
+
+
+@pytest.fixture(autouse=True)
+def no_requests(monkeypatch):
+ """ Modify the response from Requests module
+ """
+ set_env_variables()
+ with requests_mock.Mocker(real_http=True) as m:
+ mock_pods.register_pods(m)
+ yield m
diff --git a/moonv4/moon_authz/tests/unit_python/mock_pods.py b/moonv4/moon_authz/tests/unit_python/mock_pods.py
new file mode 100644
index 00000000..7488f4f3
--- /dev/null
+++ b/moonv4/moon_authz/tests/unit_python/mock_pods.py
@@ -0,0 +1,545 @@
+from utilities import CONF, get_b64_conf, COMPONENTS
+
+pdp_mock = {
+ "b3d3e18abf3340e8b635fd49e6634ccd": {
+ "description": "test",
+ "security_pipeline": [
+ "f8f49a779ceb47b3ac810f01ef71b4e0"
+ ],
+ "name": "pdp_rbac",
+ "keystone_project_id": "a64beb1cc224474fb4badd43173e7101"
+ },
+ "pdp_id1": {
+ "name": "...",
+ "security_pipeline": ["policy_id_1", "policy_id_2"],
+ "keystone_project_id": "keystone_project_id1",
+ "description": "...",
+ },
+ "pdp_id12": {
+ "name": "...",
+ "security_pipeline": ["policy_id_1", "policy_id_2"],
+ "keystone_project_id": "keystone_project_id1",
+ "description": "...",
+ }
+}
+
+meta_rules_mock = {
+ "f8f49a779ceb47b3ac810f01ef71b4e0": {
+ "subject_categories": [
+ "14e6ae0ba34d458b876c791b73aa17bd"
+ ],
+ "action_categories": [
+ "241a2a791554421a91c9f1bc564aa94d"
+ ],
+ "description": "",
+ "name": "rbac",
+ "object_categories": [
+ "6d48500f639d4c2cab2b1f33ef93a1e8"
+ ]
+ },
+ "meta_rule_id1": {
+ "name": "meta_rule1",
+ "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"]
+ },
+ "meta_rule_id2": {
+ "name": "name of the meta rules2",
+ "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"]
+ }
+}
+
+policies_mock = {
+ "f8f49a779ceb47b3ac810f01ef71b4e0": {
+ "name": "RBAC policy example",
+ "model_id": "cd923d8633ff4978ab0e99938f5153d6",
+ "description": "test",
+ "genre": "authz"
+ },
+ "policy_id_1": {
+ "name": "test_policy1",
+ "model_id": "model_id_1",
+ "genre": "authz",
+ "description": "test",
+ },
+ "policy_id_2": {
+ "name": "test_policy2",
+ "model_id": "model_id_2",
+ "genre": "authz",
+ "description": "test",
+ }
+}
+
+subject_mock = {
+ "f8f49a779ceb47b3ac810f01ef71b4e0": {
+ "89ba91c18dd54abfbfde7a66936c51a6": {
+ "description": "test",
+ "policy_list": [
+ "f8f49a779ceb47b3ac810f01ef71b4e0",
+ "636cd473324f4c0bbd9102cb5b62a16d"
+ ],
+ "name": "testuser",
+ "email": "mail",
+ "id": "89ba91c18dd54abfbfde7a66936c51a6",
+ "partner_id": ""
+ }
+ },
+ "policy_id_1": {
+ "subject_id": {
+ "name": "subject_name",
+ "keystone_id": "keystone_project_id1",
+ "description": "a description"
+ }
+ },
+ "policy_id_2": {
+ "subject_id": {
+ "name": "subject_name",
+ "keystone_id": "keystone_project_id1",
+ "description": "a description"
+ }
+ }
+}
+
+subject_assignment_mock = {
+ "826c1156d0284fc9b4b2ddb279f63c52": {
+ "category_id": "14e6ae0ba34d458b876c791b73aa17bd",
+ "assignments": [
+ "24ea95256c5f4c888c1bb30a187788df",
+ "6b227b77184c48b6a5e2f3ed1de0c02a",
+ "31928b17ec90438ba5a2e50ae7650e63",
+ "4e60f554dd3147af87595fb6b37dcb13",
+ "7a5541b63a024fa88170a6b59f99ccd7",
+ "dd2af27812f742029d289df9687d6126"
+ ],
+ "id": "826c1156d0284fc9b4b2ddb279f63c52",
+ "subject_id": "89ba91c18dd54abfbfde7a66936c51a6",
+ "policy_id": "f8f49a779ceb47b3ac810f01ef71b4e0"
+ },
+ "7407ffc1232944279b0cbcb0847c86f7": {
+ "category_id": "315072d40d774c43a89ff33937ed24eb",
+ "assignments": [
+ "6b227b77184c48b6a5e2f3ed1de0c02a",
+ "31928b17ec90438ba5a2e50ae7650e63",
+ "7a5541b63a024fa88170a6b59f99ccd7",
+ "dd2af27812f742029d289df9687d6126"
+ ],
+ "id": "7407ffc1232944279b0cbcb0847c86f7",
+ "subject_id": "89ba91c18dd54abfbfde7a66936c51a6",
+ "policy_id": "3e65256389b448cb9897917ea235f0bb"
+ }
+}
+
+object_mock = {
+ "f8f49a779ceb47b3ac810f01ef71b4e0": {
+ "9089b3d2ce5b4e929ffc7e35b55eba1a": {
+ "name": "vm1",
+ "description": "test",
+ "id": "9089b3d2ce5b4e929ffc7e35b55eba1a",
+ "partner_id": "",
+ "policy_list": [
+ "f8f49a779ceb47b3ac810f01ef71b4e0",
+ "636cd473324f4c0bbd9102cb5b62a16d"
+ ]
+ },
+ },
+ "policy_id_1": {
+ "object_id": {
+ "name": "object_name",
+ "description": "a description"
+ }
+ },
+ "policy_id_2": {
+ "object_id": {
+ "name": "object_name",
+ "description": "a description"
+ }
+ }
+}
+
+object_assignment_mock = {
+ "201ad05fd3f940948b769ab9214fe295": {
+ "object_id": "9089b3d2ce5b4e929ffc7e35b55eba1a",
+ "assignments": [
+ "030fbb34002e4236a7b74eeb5fd71e35",
+ "06bcb8655b9d46a9b90e67ef7c825b50",
+ "34eb45d7f46d4fb6bc4965349b8e4b83",
+ "4b7793dbae434c31a77da9d92de9fa8c"
+ ],
+ "id": "201ad05fd3f940948b769ab9214fe295",
+ "category_id": "6d48500f639d4c2cab2b1f33ef93a1e8",
+ "policy_id": "f8f49a779ceb47b3ac810f01ef71b4e0"
+ },
+ "90c5e86f8be34c0298fbd1973e4fb043": {
+ "object_id": "67b8008a3f8d4f8e847eb628f0f7ca0e",
+ "assignments": [
+ "a098918e915b4b12bccb89f9a3f3b4e4",
+ "06bcb8655b9d46a9b90e67ef7c825b50",
+ "7dc76c6142af47c88b60cc2b0df650ba",
+ "4b7793dbae434c31a77da9d92de9fa8c"
+ ],
+ "id": "90c5e86f8be34c0298fbd1973e4fb043",
+ "category_id": "33aece52d45b4474a20dc48a76800daf",
+ "policy_id": "3e65256389b448cb9897917ea235f0bb"
+ }
+}
+
+action_mock = {
+ "f8f49a779ceb47b3ac810f01ef71b4e0": {
+ "cdb3df220dc05a6ea3334b994827b068": {
+ "name": "boot",
+ "description": "test",
+ "id": "cdb3df220dc04a6ea3334b994827b068",
+ "partner_id": "",
+ "policy_list": [
+ "f8f49a779ceb47b3ac810f01ef71b4e0",
+ "636cd473324f4c0bbd9102cb5b62a16d"
+ ]
+ },
+ "cdb3df220dc04a6ea3334b994827b068": {
+ "name": "stop",
+ "description": "test",
+ "id": "cdb3df220dc04a6ea3334b994827b068",
+ "partner_id": "",
+ "policy_list": [
+ "f8f49a779ceb47b3ac810f01ef71b4e0",
+ "636cd473324f4c0bbd9102cb5b62a16d"
+ ]
+ },
+ "9f5112afe9b34a6c894eb87246ccb7aa": {
+ "name": "start",
+ "description": "test",
+ "id": "9f5112afe9b34a6c894eb87246ccb7aa",
+ "partner_id": "",
+ "policy_list": [
+ "f8f49a779ceb47b3ac810f01ef71b4e0",
+ "636cd473324f4c0bbd9102cb5b62a16d"
+ ]
+ }
+ },
+ "policy_id_1": {
+ "action_id": {
+ "name": "action_name",
+ "description": "a description"
+ }
+ },
+ "policy_id_2": {
+ "action_id": {
+ "name": "action_name",
+ "description": "a description"
+ }
+ }
+}
+
+action_assignment_mock = {
+ "2128e3ffbd1c4ef5be515d625745c2d4": {
+ "category_id": "241a2a791554421a91c9f1bc564aa94d",
+ "action_id": "cdb3df220dc05a6ea3334b994827b068",
+ "policy_id": "f8f49a779ceb47b3ac810f01ef71b4e0",
+ "id": "2128e3ffbd1c4ef5be515d625745c2d4",
+ "assignments": [
+ "570c036781e540dc9395b83098c40ba7",
+ "7fe17d7a2e3542719f8349c3f2273182",
+ "015ca6f40338422ba3f692260377d638",
+ "23d44c17bf88480f83e8d57d2aa1ea79"
+ ]
+ },
+ "cffb98852f3a4110af7a0ddfc4e19201": {
+ "category_id": "4a2c5abaeaf644fcaf3ca8df64000d53",
+ "action_id": "cdb3df220dc04a6ea3334b994827b068",
+ "policy_id": "3e65256389b448cb9897917ea235f0bb",
+ "id": "cffb98852f3a4110af7a0ddfc4e19201",
+ "assignments": [
+ "570c036781e540dc9395b83098c40ba7",
+ "7fe17d7a2e3542719f8349c3f2273182",
+ "015ca6f40338422ba3f692260377d638",
+ "23d44c17bf88480f83e8d57d2aa1ea79"
+ ]
+ }
+}
+
+models_mock = {
+ "cd923d8633ff4978ab0e99938f5153d6": {
+ "name": "RBAC",
+ "meta_rules": [
+ "f8f49a779ceb47b3ac810f01ef71b4e0"
+ ],
+ "description": "test"
+ },
+ "model_id_1": {
+ "name": "test_model",
+ "description": "test",
+ "meta_rules": ["meta_rule_id1"]
+ },
+ "model_id_2": {
+ "name": "test_model",
+ "description": "test",
+ "meta_rules": ["meta_rule_id2"]
+ },
+}
+
+rules_mock = {
+ "policy_id": "f8f49a779ceb47b3ac810f01ef71b4e0",
+ "rules": [
+ {
+ "policy_id": "f8f49a779ceb47b3ac810f01ef71b4e0",
+ "rule": [
+ "24ea95256c5f4c888c1bb30a187788df",
+ "030fbb34002e4236a7b74eeb5fd71e35",
+ "570c036781e540dc9395b83098c40ba7"
+ ],
+ "enabled": True,
+ "id": "0201a2bcf56943c1904dbac016289b71",
+ "instructions": [
+ {
+ "decision": "grant"
+ }
+ ],
+ "meta_rule_id": "f8f49a779ceb47b3ac810f01ef71b4e0"
+ },
+ {
+ "policy_id": "ecc2451c494e47b5bca7250cd324a360",
+ "rule": [
+ "54f574cd2043468da5d65e4f6ed6e3c9",
+ "6559686961a3490a978f246ac9f85fbf",
+ "ac0d1f600bf447e8bd2f37b7cc47f2dc"
+ ],
+ "enabled": True,
+ "id": "a83fed666af8436192dfd8b3c83a6fde",
+ "instructions": [
+ {
+ "decision": "grant"
+ }
+ ],
+ "meta_rule_id": "f8f49a779ceb47b3ac810f01ef71b4e0"
+ }
+ ]
+}
+
+
+def register_pods(m):
+ """ Modify the response from Requests module
+ """
+ register_consul(m)
+ register_pdp(m)
+ register_meta_rules(m)
+ register_policies(m)
+ register_models(m)
+ register_orchestrator(m)
+ register_policy_subject(m, "f8f49a779ceb47b3ac810f01ef71b4e0")
+ # register_policy_subject(m, "policy_id_2")
+ register_policy_object(m, "f8f49a779ceb47b3ac810f01ef71b4e0")
+ # register_policy_object(m, "policy_id_2")
+ register_policy_action(m, "f8f49a779ceb47b3ac810f01ef71b4e0")
+ # register_policy_action(m, "policy_id_2")
+ register_policy_subject_assignment(m, "f8f49a779ceb47b3ac810f01ef71b4e0", "89ba91c18dd54abfbfde7a66936c51a6")
+ # register_policy_subject_assignment_list(m, "f8f49a779ceb47b3ac810f01ef71b4e0")
+ # register_policy_subject_assignment(m, "policy_id_2", "subject_id")
+ # register_policy_subject_assignment_list(m1, "policy_id_2")
+ register_policy_object_assignment(m, "f8f49a779ceb47b3ac810f01ef71b4e0", "9089b3d2ce5b4e929ffc7e35b55eba1a")
+ # register_policy_object_assignment_list(m, "f8f49a779ceb47b3ac810f01ef71b4e0")
+ # register_policy_object_assignment(m, "policy_id_2", "object_id")
+ # register_policy_object_assignment_list(m1, "policy_id_2")
+ register_policy_action_assignment(m, "f8f49a779ceb47b3ac810f01ef71b4e0", "cdb3df220dc05a6ea3334b994827b068")
+ # register_policy_action_assignment_list(m, "f8f49a779ceb47b3ac810f01ef71b4e0")
+ # register_policy_action_assignment(m, "policy_id_2", "action_id")
+ # register_policy_action_assignment_list(m1, "policy_id_2")
+ register_rules(m, "f8f49a779ceb47b3ac810f01ef71b4e0")
+ register_rules(m, "policy_id_1")
+ register_rules(m, "policy_id_2")
+
+
+def register_consul(m):
+ for component in COMPONENTS:
+ m.register_uri(
+ 'GET', 'http://consul:8500/v1/kv/{}'.format(component),
+ json=[{'Key': component, 'Value': get_b64_conf(component)}]
+ )
+ m.register_uri(
+ 'GET', 'http://consul:8500/v1/kv/components_port_start',
+ json=[
+ {
+ "LockIndex": 0,
+ "Key": "components_port_start",
+ "Flags": 0,
+ "Value": "MzEwMDE=",
+ "CreateIndex": 9,
+ "ModifyIndex": 9
+ }
+ ],
+ )
+ m.register_uri(
+ 'PUT', 'http://consul:8500/v1/kv/components_port_start',
+ json=[],
+ )
+ m.register_uri(
+ 'GET', 'http://consul:8500/v1/kv/plugins?recurse=true',
+ json=[
+ {
+ "LockIndex": 0,
+ "Key": "plugins/authz",
+ "Flags": 0,
+ "Value": "eyJjb250YWluZXIiOiAid3Vrb25nc3VuL21vb25fYXV0aHo6djQuMyIsICJwb3J0IjogODA4MX0=",
+ "CreateIndex": 14,
+ "ModifyIndex": 656
+ }
+ ],
+ )
+ m.register_uri(
+ 'GET', 'http://consul:8500/v1/kv/components?recurse=true',
+ json=[
+ {"Key": key, "Value": get_b64_conf(key)} for key in COMPONENTS
+ ],
+ )
+ m.register_uri(
+ 'GET', 'http://consul:8500/v1/kv/plugins/authz',
+ json=[
+ {
+ "LockIndex": 0,
+ "Key": "plugins/authz",
+ "Flags": 0,
+ "Value": "eyJjb250YWluZXIiOiAid3Vrb25nc3VuL21vb25fYXV0aHo6djQuMyIsICJwb3J0IjogODA4MX0=",
+ "CreateIndex": 14,
+ "ModifyIndex": 656
+ }
+ ],
+ )
+
+
+def register_orchestrator(m):
+ m.register_uri(
+ 'GET', 'http://orchestrator:8083/pods',
+ json={
+ "pods": {
+ "1234567890": [
+ {"name": "wrapper-quiet", "port": 8080,
+ "container": "wukongsun/moon_wrapper:v4.3.1",
+ "namespace": "moon"}]}}
+ )
+
+
+def register_pdp(m):
+ m.register_uri(
+ 'GET', 'http://{}:{}/{}'.format(CONF['components']['manager']['hostname'],
+ CONF['components']['manager']['port'], 'pdp'),
+ json={'pdps': pdp_mock}
+ )
+
+
+def register_meta_rules(m):
+ m.register_uri(
+ 'GET', 'http://{}:{}/{}'.format(CONF['components']['manager']['hostname'],
+ CONF['components']['manager']['port'], 'meta_rules'),
+ json={'meta_rules': meta_rules_mock}
+ )
+
+
+def register_policies(m):
+ m.register_uri(
+ 'GET', 'http://{}:{}/{}'.format(CONF['components']['manager']['hostname'],
+ CONF['components']['manager']['port'], 'policies'),
+ json={'policies': policies_mock}
+ )
+
+
+def register_models(m):
+ m.register_uri(
+ 'GET', 'http://{}:{}/{}'.format(CONF['components']['manager']['hostname'],
+ CONF['components']['manager']['port'], 'models'),
+ json={'models': models_mock}
+ )
+
+
+def register_policy_subject(m, policy_id):
+ m.register_uri(
+ 'GET', 'http://{}:{}/{}/{}/subjects'.format(CONF['components']['manager']['hostname'],
+ CONF['components']['manager']['port'], 'policies', policy_id),
+ json={'subjects': subject_mock[policy_id]}
+ )
+
+
+def register_policy_object(m, policy_id):
+ m.register_uri(
+ 'GET', 'http://{}:{}/{}/{}/objects'.format(CONF['components']['manager']['hostname'],
+ CONF['components']['manager']['port'], 'policies', policy_id),
+ json={'objects': object_mock[policy_id]}
+ )
+
+
+def register_policy_action(m, policy_id):
+ m.register_uri(
+ 'GET', 'http://{}:{}/{}/{}/actions'.format(CONF['components']['manager']['hostname'],
+ CONF['components']['manager']['port'], 'policies', policy_id),
+ json={'actions': action_mock[policy_id]}
+ )
+
+
+def register_policy_subject_assignment(m, policy_id, subj_id):
+ m.register_uri(
+ 'GET', 'http://{}:{}/{}/{}/subject_assignments/{}'.format(CONF['components']['manager']['hostname'],
+ CONF['components']['manager']['port'], 'policies',
+ policy_id,
+ subj_id),
+ json={'subject_assignments': subject_assignment_mock}
+ )
+
+
+def register_policy_subject_assignment_list(m, policy_id):
+ m.register_uri(
+ 'GET', 'http://{}:{}/{}/{}/subject_assignments'.format(CONF['components']['manager']['hostname'],
+ CONF['components']['manager']['port'], 'policies',
+ policy_id),
+ json={'subject_assignments': subject_assignment_mock}
+ )
+
+
+def register_policy_object_assignment(m, policy_id, obj_id):
+ m.register_uri(
+ 'GET', 'http://{}:{}/{}/{}/object_assignments/{}'.format(CONF['components']['manager']['hostname'],
+ CONF['components']['manager']['port'], 'policies',
+ policy_id,
+ obj_id),
+ json={'object_assignments': object_assignment_mock}
+ )
+
+
+def register_policy_object_assignment_list(m, policy_id):
+ m.register_uri(
+ 'GET', 'http://{}:{}/{}/{}/object_assignments'.format(CONF['components']['manager']['hostname'],
+ CONF['components']['manager']['port'], 'policies',
+ policy_id),
+ json={'object_assignments': object_assignment_mock}
+ )
+
+
+def register_policy_action_assignment(m, policy_id, action_id):
+ m.register_uri(
+ 'GET', 'http://{}:{}/{}/{}/action_assignments/{}'.format(CONF['components']['manager']['hostname'],
+ CONF['components']['manager']['port'], 'policies',
+ policy_id,
+ action_id),
+ json={'action_assignments': action_assignment_mock}
+ )
+
+
+def register_policy_action_assignment_list(m, policy_id):
+ m.register_uri(
+ 'GET', 'http://{}:{}/{}/{}/action_assignments'.format(CONF['components']['manager']['hostname'],
+ CONF['components']['manager']['port'], 'policies',
+ policy_id),
+ json={'action_assignments': action_assignment_mock}
+ )
+
+
+def register_rules(m, policy_id):
+ m.register_uri(
+ 'GET', 'http://{}:{}/{}/{}/{}'.format(CONF['components']['manager']['hostname'],
+ CONF['components']['manager']['port'], 'policies',
+ policy_id, 'rules'),
+ json={'rules': rules_mock}
+ ) \ No newline at end of file
diff --git a/moonv4/moon_consul/requirements.txt b/moonv4/moon_authz/tests/unit_python/requirements.txt
index ab99edaa..8bd8449f 100644
--- a/moonv4/moon_consul/requirements.txt
+++ b/moonv4/moon_authz/tests/unit_python/requirements.txt
@@ -1,5 +1,5 @@
-oslo.messaging
flask
-flask_restful
flask_cors
+flask_restful
+moon_db
moon_utilities \ No newline at end of file
diff --git a/moonv4/moon_authz/tests/unit_python/test_authz.py b/moonv4/moon_authz/tests/unit_python/test_authz.py
new file mode 100644
index 00000000..147f7c5d
--- /dev/null
+++ b/moonv4/moon_authz/tests/unit_python/test_authz.py
@@ -0,0 +1,50 @@
+import json
+import pickle
+
+
+def get_data(data):
+ return pickle.loads(data)
+
+
+def get_json(data):
+ return json.loads(data.decode("utf-8"))
+
+
+def test_authz_true(context):
+ import moon_authz.server
+ from moon_utilities.security_functions import Context
+ from moon_utilities.cache import Cache
+ server = moon_authz.server.main()
+ client = server.app.test_client()
+ CACHE = Cache()
+ CACHE.update()
+ print(CACHE.pdp)
+ _context = Context(context, CACHE)
+ req = client.post("/authz", data=pickle.dumps(_context))
+ assert req.status_code == 200
+ data = get_data(req.data)
+ assert data
+ assert isinstance(data, Context)
+ policy_id = data.headers[0]
+ assert policy_id
+ assert "effect" in data.pdp_set[policy_id]
+ assert data.pdp_set[policy_id]['effect'] == "grant"
+
+
+def test_user_not_allowed(context):
+ import moon_authz.server
+ from moon_utilities.security_functions import Context
+ from moon_utilities.cache import Cache
+ server = moon_authz.server.main()
+ client = server.app.test_client()
+ CACHE = Cache()
+ CACHE.update()
+ context['subject_name'] = "user_not_allowed"
+ _context = Context(context, CACHE)
+ req = client.post("/authz", data=pickle.dumps(_context))
+ assert req.status_code == 400
+ data = get_json(req.data)
+ assert data
+ assert isinstance(data, dict)
+ assert "message" in data
+ assert data["message"] == "Cannot find subject user_not_allowed"
diff --git a/moonv4/moon_authz/tests/unit_python/utilities.py b/moonv4/moon_authz/tests/unit_python/utilities.py
new file mode 100644
index 00000000..19b9354c
--- /dev/null
+++ b/moonv4/moon_authz/tests/unit_python/utilities.py
@@ -0,0 +1,173 @@
+import base64
+import json
+import pytest
+from uuid import uuid4
+
+
+CONF = {
+ "openstack": {
+ "keystone": {
+ "url": "http://keystone:5000/v3",
+ "user": "admin",
+ "check_token": False,
+ "password": "p4ssw0rd",
+ "domain": "default",
+ "certificate": False,
+ "project": "admin"
+ }
+ },
+ "components": {
+ "wrapper": {
+ "bind": "0.0.0.0",
+ "port": 8080,
+ "container": "wukongsun/moon_wrapper:v4.3",
+ "timeout": 5,
+ "hostname": "wrapper"
+ },
+ "manager": {
+ "bind": "0.0.0.0",
+ "port": 8082,
+ "container": "wukongsun/moon_manager:v4.3",
+ "hostname": "manager"
+ },
+ "port_start": 31001,
+ "orchestrator": {
+ "bind": "0.0.0.0",
+ "port": 8083,
+ "container": "wukongsun/moon_orchestrator:v4.3",
+ "hostname": "orchestrator"
+ },
+ "interface": {
+ "bind": "0.0.0.0",
+ "port": 8080,
+ "container": "wukongsun/moon_interface:v4.3",
+ "hostname": "interface"
+ }
+ },
+ "plugins": {
+ "session": {
+ "port": 8082,
+ "container": "asteroide/session:latest"
+ },
+ "authz": {
+ "port": 8081,
+ "container": "wukongsun/moon_authz:v4.3"
+ }
+ },
+ "logging": {
+ "handlers": {
+ "file": {
+ "filename": "/tmp/moon.log",
+ "class": "logging.handlers.RotatingFileHandler",
+ "level": "DEBUG",
+ "formatter": "custom",
+ "backupCount": 3,
+ "maxBytes": 1048576
+ },
+ "console": {
+ "class": "logging.StreamHandler",
+ "formatter": "brief",
+ "level": "INFO",
+ "stream": "ext://sys.stdout"
+ }
+ },
+ "formatters": {
+ "brief": {
+ "format": "%(levelname)s %(name)s %(message)-30s"
+ },
+ "custom": {
+ "format": "%(asctime)-15s %(levelname)s %(name)s %(message)s"
+ }
+ },
+ "root": {
+ "handlers": [
+ "console"
+ ],
+ "level": "ERROR"
+ },
+ "version": 1,
+ "loggers": {
+ "moon": {
+ "handlers": [
+ "console",
+ "file"
+ ],
+ "propagate": False,
+ "level": "DEBUG"
+ }
+ }
+ },
+ "slave": {
+ "name": None,
+ "master": {
+ "url": None,
+ "login": None,
+ "password": None
+ }
+ },
+ "docker": {
+ "url": "tcp://172.88.88.1:2376",
+ "network": "moon"
+ },
+ "database": {
+ "url": "sqlite:///database.db",
+ # "url": "mysql+pymysql://moon:p4sswOrd1@db/moon",
+ "driver": "sql"
+ },
+ "messenger": {
+ "url": "rabbit://moon:p4sswOrd1@messenger:5672/moon"
+ }
+}
+
+
+CONTEXT = {
+ "project_id": "a64beb1cc224474fb4badd43173e7101",
+ "subject_name": "testuser",
+ "object_name": "vm1",
+ "action_name": "boot",
+ "request_id": uuid4().hex,
+ "interface_name": "interface",
+ "manager_url": "http://{}:{}".format(
+ CONF["components"]["manager"]["hostname"],
+ CONF["components"]["manager"]["port"]
+ ),
+ "cookie": uuid4().hex,
+ "pdp_id": "b3d3e18abf3340e8b635fd49e6634ccd",
+ "security_pipeline": ["f8f49a779ceb47b3ac810f01ef71b4e0"]
+ }
+
+
+COMPONENTS = (
+ "logging",
+ "openstack/keystone",
+ "database",
+ "slave",
+ "components/manager",
+ "components/orchestrator",
+ "components/interface",
+ "components/wrapper",
+)
+
+
+def get_b64_conf(component=None):
+ if component == "components":
+ return base64.b64encode(
+ json.dumps(CONF["components"]).encode('utf-8')+b"\n").decode('utf-8')
+ elif component in CONF:
+ return base64.b64encode(
+ json.dumps(
+ CONF[component]).encode('utf-8')+b"\n").decode('utf-8')
+ elif not component:
+ return base64.b64encode(
+ json.dumps(CONF).encode('utf-8')+b"\n").decode('utf-8')
+ elif "/" in component:
+ key1, _, key2 = component.partition("/")
+ return base64.b64encode(
+ json.dumps(
+ CONF[key1][key2]).encode('utf-8')+b"\n").decode('utf-8')
+
+
+def get_json(data):
+ return json.loads(data.decode("utf-8"))
+
+
diff --git a/moonv4/moon_bouchon/Dockerfile b/moonv4/moon_bouchon/Dockerfile
new file mode 100644
index 00000000..ed013935
--- /dev/null
+++ b/moonv4/moon_bouchon/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/moonv4/moon_bouchon/README.md b/moonv4/moon_bouchon/README.md
new file mode 100644
index 00000000..11733cef
--- /dev/null
+++ b/moonv4/moon_bouchon/README.md
@@ -0,0 +1,42 @@
+#Moon Bouchon
+
+Moon_bouchon is a fake interface to the Moon platform.
+Moon platform can be requested through 2 interfaces:
+
+- ''wrapper'', interface for the OpenStack platform
+- ''interface'', interface for other components
+
+## Usage:
+
+### server
+
+To start the server:
+
+ docker run -ti -p 31002:31002 wukongsun/moon_bouchon:v1.0
+ # or docker run -dti -p 31002:31002 wukongsun/moon_bouchon:v1.0
+
+### wrapper
+
+Here are the URL, you can request:
+
+ POST /wrapper/authz/grant to request the wrapper component with always a "True" response
+ POST /wrapper/authz/deny to request the wrapper component with always a "False" response
+ POST /wrapper/authz to request the wrapper component with always a "True" or "False" response
+
+In each request you must pass the following data (or similar):
+
+ {'rule': 'start', 'target': '{"target": {"name": "vm0"}, "user_id": "user0"}', 'credentials': 'null'}
+
+You have examples in the moon_bouchon/tests directory.
+
+### interface
+
+Here are the URL, you can request:
+
+ GET /interface/authz/grant/<string:project_id>/<string:subject_name>/<string:object_name>/<string:action_name> to request the interface component with always a "True" response
+ GET /interface/authz/deny/<string:project_id>/<string:subject_name>/<string:object_name>/<string:action_name> to request the interface component with always a "False" response
+ GET /interface/authz/<string:project_id>/<string:subject_name>/<string:object_name>/<string:action_name> to request the interface component with always a "True" or "False" response
+
+You have examples in the moon_bouchon/tests directory.
+
+
diff --git a/moonv4/moon_router/moon_router/__init__.py b/moonv4/moon_bouchon/moon_bouchon/__init__.py
index 903c6518..8811d91d 100644
--- a/moonv4/moon_router/moon_router/__init__.py
+++ b/moonv4/moon_bouchon/moon_bouchon/__init__.py
@@ -3,4 +3,5 @@
# 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__ = "1.1"
diff --git a/moonv4/moon_consul/MANIFEST.in b/moonv4/moon_bouchon/moon_bouchon/__main__.py
index ba8a657e..4499a96b 100644
--- a/moonv4/moon_consul/MANIFEST.in
+++ b/moonv4/moon_bouchon/moon_bouchon/__main__.py
@@ -3,9 +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 LICENSE
-include setup.py
-include requirements.txt
-# graft tests
-graft bin \ No newline at end of file
+
+import moon_bouchon.server
+
+moon_bouchon.server.main()
diff --git a/moonv4/moon_bouchon/moon_bouchon/server.py b/moonv4/moon_bouchon/moon_bouchon/server.py
new file mode 100644
index 00000000..29e9101e
--- /dev/null
+++ b/moonv4/moon_bouchon/moon_bouchon/server.py
@@ -0,0 +1,138 @@
+# 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 sys
+import flask
+from flask import Flask
+from flask import request
+import json
+import logging
+import random
+
+logger = logging.getLogger(__name__)
+app = Flask(__name__)
+
+
+@app.route("/interface/authz/grant/<string:project_id>/<string:subject_name>/"
+ "<string:object_name>/<string:action_name>",
+ methods=["GET"])
+def interface_grant(project_id, subject_name, object_name, action_name):
+ logger.info("Requesting interface authz on {} {} {} {}".format(
+ project_id, subject_name, object_name, action_name))
+ return json.dumps({
+ "result": True,
+ "context": {
+ "project_id": project_id,
+ "subject_name": subject_name,
+ "object_name": object_name,
+ "action_name": action_name
+ }
+ })
+
+
+@app.route("/interface/authz/deny/<string:project_id>/<string:subject_name>/"
+ "<string:object_name>/<string:action_name>",
+ methods=["GET"])
+def interface_deny(project_id, subject_name, object_name, action_name):
+ logger.info("Requesting interface authz on {} {} {} {}".format(
+ project_id, subject_name, object_name, action_name))
+ return json.dumps({
+ "result": False,
+ "context": {
+ "project_id": project_id,
+ "subject_name": subject_name,
+ "object_name": object_name,
+ "action_name": action_name
+ }
+ })
+
+
+@app.route("/interface/authz/<string:project_id>/<string:subject_name>/"
+ "<string:object_name>/<string:action_name>",
+ methods=["GET"])
+def interface_authz(project_id, subject_name, object_name, action_name):
+ logger.info("Requesting interface authz on {} {} {} {}".format(
+ project_id, subject_name, object_name, action_name))
+ return json.dumps({
+ "result": random.choice((True, False)),
+ "context": {
+ "project_id": project_id,
+ "subject_name": subject_name,
+ "object_name": object_name,
+ "action_name": action_name
+ }
+ })
+
+
+def test_data():
+ data = request.form
+ 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")
+
+
+@app.route("/wrapper/authz/grant", methods=["POST"])
+def wrapper_grant():
+ logger.info("Requesting wrapper authz")
+ try:
+ test_data()
+ except Exception as e:
+ logger.exception(e)
+ return str(e), 400
+ response = flask.make_response("True")
+ response.headers['content-type'] = 'application/octet-stream'
+ return response
+
+
+@app.route("/wrapper/authz/deny", methods=["POST"])
+def wrapper_deny():
+ logger.info("Requesting wrapper authz")
+ try:
+ test_data()
+ except Exception as e:
+ logger.exception(e)
+ return str(e), 400
+ response = flask.make_response("False")
+ response.headers['content-type'] = 'application/octet-stream'
+ return response
+
+
+@app.route("/wrapper/authz", methods=["POST"])
+def wrapper_authz():
+ logger.info("Requesting wrapper authz")
+ try:
+ test_data()
+ except Exception as e:
+ logger.exception(e)
+ return str(e), 400
+ response = flask.make_response(random.choice(("True", "False")))
+ response.headers['content-type'] = 'application/octet-stream'
+ return response
+
+
+def main():
+ port = 31002
+ 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/moonv4/moon_bouchon/requirements.txt b/moonv4/moon_bouchon/requirements.txt
new file mode 100644
index 00000000..8ab6294c
--- /dev/null
+++ b/moonv4/moon_bouchon/requirements.txt
@@ -0,0 +1 @@
+flask \ No newline at end of file
diff --git a/moonv4/moon_bouchon/setup.cfg b/moonv4/moon_bouchon/setup.cfg
new file mode 100644
index 00000000..7c2b2874
--- /dev/null
+++ b/moonv4/moon_bouchon/setup.cfg
@@ -0,0 +1,2 @@
+[bdist_wheel]
+universal = 1 \ No newline at end of file
diff --git a/moonv4/moon_router/setup.py b/moonv4/moon_bouchon/setup.py
index aabe8349..a875be40 100644
--- a/moonv4/moon_router/setup.py
+++ b/moonv4/moon_bouchon/setup.py
@@ -4,14 +4,14 @@
# or at 'http://www.apache.org/licenses/LICENSE-2.0'.
from setuptools import setup, find_packages
-import moon_router
+import moon_bouchon
setup(
- name='moon_router',
+ name='moon_bouchon',
- version=moon_router.__version__,
+ version=moon_bouchon.__version__,
packages=find_packages(),
@@ -23,7 +23,7 @@ setup(
long_description=open('README.md').read(),
- # install_requires= ,
+ install_requires=["flask"],
include_package_data=True,
@@ -40,7 +40,8 @@ setup(
entry_points={
'console_scripts': [
- 'moon_router = moon_router.server:main',
+ 'moon_bouchon = moon_bouchon.server:main',
],
}
+
)
diff --git a/moonv4/moon_bouchon/tests/test_interface.py b/moonv4/moon_bouchon/tests/test_interface.py
new file mode 100644
index 00000000..425ba2e5
--- /dev/null
+++ b/moonv4/moon_bouchon/tests/test_interface.py
@@ -0,0 +1,61 @@
+import requests
+from uuid import uuid4
+import pytest
+
+
+@pytest.fixture
+def args():
+ return {
+ "project_id": uuid4().hex,
+ "subject_id": uuid4().hex,
+ "object_id": uuid4().hex,
+ "action_id": uuid4().hex
+ }
+
+
+def test_false(args):
+ url = "http://127.0.0.1:31002/interface/authz/deny/{project_id}" \
+ "/{subject_id}/{object_id}/{action_id}".format(**args)
+ data = {'rule': 'start',
+ 'target': '{"target": {"name": "vm0"}, "user_id": "user0"}',
+ 'credentials': 'null'}
+ req = requests.get(
+ url, json=data,
+ headers={'content-type': "application/x-www-form-urlencode"}
+ )
+ assert req.status_code == 200
+ assert "result" in req.json()
+ assert req.json()["result"] == False
+
+
+def test_true(args):
+ url = "http://127.0.0.1:31002/interface/authz/grant/{project_id}" \
+ "/{subject_id}/{object_id}/{action_id}".format(**args)
+
+ data = {'rule': 'start',
+ 'target': '{"target": {"name": "vm0"}, "user_id": "user0"}',
+ 'credentials': 'null'}
+ req = requests.get(
+ url, json=data,
+ headers={'content-type': "application/x-www-form-urlencode"}
+ )
+ assert req.status_code == 200
+ assert "result" in req.json()
+ assert req.json()["result"] == True
+
+
+def test_random(args):
+ url = "http://127.0.0.1:31002/interface/authz/{project_id}" \
+ "/{subject_id}/{object_id}/{action_id}".format(**args)
+
+ data = {'rule': 'start',
+ 'target': '{"target": {"name": "vm0"}, "user_id": "user0"}',
+ 'credentials': 'null'}
+ req = requests.get(
+ url, json=data,
+ headers={'content-type': "application/x-www-form-urlencode"}
+ )
+ assert req.status_code == 200
+ assert "result" in req.json()
+ assert req.json()["result"] in (False, True)
+
diff --git a/moonv4/moon_bouchon/tests/test_wrapper.py b/moonv4/moon_bouchon/tests/test_wrapper.py
new file mode 100644
index 00000000..3d5e150c
--- /dev/null
+++ b/moonv4/moon_bouchon/tests/test_wrapper.py
@@ -0,0 +1,38 @@
+import requests
+
+
+def test_false():
+ url = "http://127.0.0.1:31002/wrapper/authz/deny"
+
+ data = {'rule': 'start', 'target': '{"target": {"name": "vm0"}, "user_id": "user0"}', 'credentials': 'null'}
+ req = requests.post(
+ url, json=data,
+ headers={'content-type': "application/x-www-form-urlencode"}
+ )
+ assert req.status_code == 200
+ assert req.text == "False"
+
+
+def test_true():
+ url = "http://127.0.0.1:31002/wrapper/authz/grant"
+
+ data = {'rule': 'start', 'target': '{"target": {"name": "vm0"}, "user_id": "user0"}', 'credentials': 'null'}
+ req = requests.post(
+ url, json=data,
+ headers={'content-type': "application/x-www-form-urlencode"}
+ )
+ assert req.status_code == 200
+ assert req.text == "True"
+
+
+def test_random():
+ url = "http://127.0.0.1:31002/wrapper/authz"
+
+ data = {'rule': 'start', 'target': '{"target": {"name": "vm0"}, "user_id": "user0"}', 'credentials': 'null'}
+ req = requests.post(
+ url, json=data,
+ headers={'content-type': "application/x-www-form-urlencode"}
+ )
+ assert req.status_code == 200
+ assert req.text in ("False", "True")
+
diff --git a/moonv4/moon_consul/Dockerfile b/moonv4/moon_consul/Dockerfile
deleted file mode 100644
index 1d3c7108..00000000
--- a/moonv4/moon_consul/Dockerfile
+++ /dev/null
@@ -1,37 +0,0 @@
-# Pull base image.
-FROM ubuntu:latest
-
-ENV DB_URL="mysql+pymysql://moon:p4sswOrd1@db/moon"
-ENV DB_DRIVER=sql
-ENV TRANSPORT_URL="rabbit://moon:p4sswOrd1@messenger:5672/moon"
-ENV DOCKER_URL="unix://var/run/docker.sock"
-ENV SLAVE_NAME=
-ENV MASTER_URL=
-ENV MASTER_LOGIN=
-ENV MASTER_PASSWORD=
-ENV INTERFACE_PORT=8080
-ENV CONSUL_HOST="172.88.88.88"
-ENV CONSUL_PORT=88
-ENV KEYSTONE_URL="http://keystone:5000/v3"
-ENV KEYSTONE_USER=admin
-ENV KEYSTONE_PASSWORD=p4ssw0rd
-ENV KEYSTONE_DOMAIN=default
-ENV KEYSTONE_PROJECT=admin
-ENV KEYSTONE_CHECK_TOKEN=False
-ENV KEYSTONE_SERVER_CRT=False
-ENV PLUGIN_CONTAINERS="asteroide/authz:latest,asteroide/session:latest"
-ENV COMPONENTS_PORT_START=38001
-
-RUN apt-get update && apt-get install python3.5 python3-pip -y
-
-RUN pip3 install pip --upgrade
-#RUN pip3 install moon_db
-
-ADD . /root
-
-WORKDIR /root/
-RUN pip3 install -r requirements.txt
-RUN pip3 install .
-EXPOSE ${CONSUL_PORT}
-
-CMD ["python3", "-m", "moon_consul"] \ No newline at end of file
diff --git a/moonv4/moon_consul/LICENSE b/moonv4/moon_consul/LICENSE
deleted file mode 100644
index 4143aac2..00000000
--- a/moonv4/moon_consul/LICENSE
+++ /dev/null
@@ -1,204 +0,0 @@
-
- Apache License
- Version 2.0, January 2004
- http://www.apache.org/licenses/
-
- TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
-
- 1. Definitions.
-
- "License" shall mean the terms and conditions for use, reproduction,
- and distribution as defined by Sections 1 through 9 of this document.
-
- "Licensor" shall mean the copyright owner or entity authorized by
- the copyright owner that is granting the License.
-
- "Legal Entity" shall mean the union of the acting entity and all
- other entities that control, are controlled by, or are under common
- control with that entity. For the purposes of this definition,
- "control" means (i) the power, direct or indirect, to cause the
- direction or management of such entity, whether by contract or
- otherwise, or (ii) ownership of fifty percent (50%) or more of the
- outstanding shares, or (iii) beneficial ownership of such entity.
-
- "You" (or "Your") shall mean an individual or Legal Entity
- exercising permissions granted by this License.
-
- "Source" form shall mean the preferred form for making modifications,
- including but not limited to software source code, documentation
- source, and configuration files.
-
- "Object" form shall mean any form resulting from mechanical
- transformation or translation of a Source form, including but
- not limited to compiled object code, generated documentation,
- and conversions to other media types.
-
- "Work" shall mean the work of authorship, whether in Source or
- Object form, made available under the License, as indicated by a
- copyright notice that is included in or attached to the work
- (an example is provided in the Appendix below).
-
- "Derivative Works" shall mean any work, whether in Source or Object
- form, that is based on (or derived from) the Work and for which the
- editorial revisions, annotations, elaborations, or other modifications
- represent, as a whole, an original work of authorship. For the purposes
- of this License, Derivative Works shall not include works that remain
- separable from, or merely link (or bind by name) to the interfaces of,
- the Work and Derivative Works thereof.
-
- "Contribution" shall mean any work of authorship, including
- the original version of the Work and any modifications or additions
- to that Work or Derivative Works thereof, that is intentionally
- submitted to Licensor for inclusion in the Work by the copyright owner
- or by an individual or Legal Entity authorized to submit on behalf of
- the copyright owner. For the purposes of this definition, "submitted"
- means any form of electronic, verbal, or written communication sent
- to the Licensor or its representatives, including but not limited to
- communication on electronic mailing lists, source code control systems,
- and issue tracking systems that are managed by, or on behalf of, the
- Licensor for the purpose of discussing and improving the Work, but
- excluding communication that is conspicuously marked or otherwise
- designated in writing by the copyright owner as "Not a Contribution."
-
- "Contributor" shall mean Licensor and any individual or Legal Entity
- on behalf of whom a Contribution has been received by Licensor and
- subsequently incorporated within the Work.
-
- 2. Grant of Copyright License. Subject to the terms and conditions of
- this License, each Contributor hereby grants to You a perpetual,
- worldwide, non-exclusive, no-charge, royalty-free, irrevocable
- copyright license to reproduce, prepare Derivative Works of,
- publicly display, publicly perform, sublicense, and distribute the
- Work and such Derivative Works in Source or Object form.
-
- 3. Grant of Patent License. Subject to the terms and conditions of
- this License, each Contributor hereby grants to You a perpetual,
- worldwide, non-exclusive, no-charge, royalty-free, irrevocable
- (except as stated in this section) patent license to make, have made,
- use, offer to sell, sell, import, and otherwise transfer the Work,
- where such license applies only to those patent claims licensable
- by such Contributor that are necessarily infringed by their
- Contribution(s) alone or by combination of their Contribution(s)
- with the Work to which such Contribution(s) was submitted. If You
- institute patent litigation against any entity (including a
- cross-claim or counterclaim in a lawsuit) alleging that the Work
- or a Contribution incorporated within the Work constitutes direct
- or contributory patent infringement, then any patent licenses
- granted to You under this License for that Work shall terminate
- as of the date such litigation is filed.
-
- 4. Redistribution. You may reproduce and distribute copies of the
- Work or Derivative Works thereof in any medium, with or without
- modifications, and in Source or Object form, provided that You
- meet the following conditions:
-
- (a) You must give any other recipients of the Work or
- Derivative Works a copy of this License; and
-
- (b) You must cause any modified files to carry prominent notices
- stating that You changed the files; and
-
- (c) You must retain, in the Source form of any Derivative Works
- that You distribute, all copyright, patent, trademark, and
- attribution notices from the Source form of the Work,
- excluding those notices that do not pertain to any part of
- the Derivative Works; and
-
- (d) If the Work includes a "NOTICE" text file as part of its
- distribution, then any Derivative Works that You distribute must
- include a readable copy of the attribution notices contained
- within such NOTICE file, excluding those notices that do not
- pertain to any part of the Derivative Works, in at least one
- of the following places: within a NOTICE text file distributed
- as part of the Derivative Works; within the Source form or
- documentation, if provided along with the Derivative Works; or,
- within a display generated by the Derivative Works, if and
- wherever such third-party notices normally appear. The contents
- of the NOTICE file are for informational purposes only and
- do not modify the License. You may add Your own attribution
- notices within Derivative Works that You distribute, alongside
- or as an addendum to the NOTICE text from the Work, provided
- that such additional attribution notices cannot be construed
- as modifying the License.
-
- You may add Your own copyright statement to Your modifications and
- may provide additional or different license terms and conditions
- for use, reproduction, or distribution of Your modifications, or
- for any such Derivative Works as a whole, provided Your use,
- reproduction, and distribution of the Work otherwise complies with
- the conditions stated in this License.
-
- 5. Submission of Contributions. Unless You explicitly state otherwise,
- any Contribution intentionally submitted for inclusion in the Work
- by You to the Licensor shall be under the terms and conditions of
- this License, without any additional terms or conditions.
- Notwithstanding the above, nothing herein shall supersede or modify
- the terms of any separate license agreement you may have executed
- with Licensor regarding such Contributions.
-
- 6. Trademarks. This License does not grant permission to use the trade
- names, trademarks, service marks, or product names of the Licensor,
- except as required for reasonable and customary use in describing the
- origin of the Work and reproducing the content of the NOTICE file.
-
- 7. Disclaimer of Warranty. Unless required by applicable law or
- agreed to in writing, Licensor provides the Work (and each
- Contributor provides its Contributions) on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
- implied, including, without limitation, any warranties or conditions
- of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
- PARTICULAR PURPOSE. You are solely responsible for determining the
- appropriateness of using or redistributing the Work and assume any
- risks associated with Your exercise of permissions under this License.
-
- 8. Limitation of Liability. In no event and under no legal theory,
- whether in tort (including negligence), contract, or otherwise,
- unless required by applicable law (such as deliberate and grossly
- negligent acts) or agreed to in writing, shall any Contributor be
- liable to You for damages, including any direct, indirect, special,
- incidental, or consequential damages of any character arising as a
- result of this License or out of the use or inability to use the
- Work (including but not limited to damages for loss of goodwill,
- work stoppage, computer failure or malfunction, or any and all
- other commercial damages or losses), even if such Contributor
- has been advised of the possibility of such damages.
-
- 9. Accepting Warranty or Additional Liability. While redistributing
- the Work or Derivative Works thereof, You may choose to offer,
- and charge a fee for, acceptance of support, warranty, indemnity,
- or other liability obligations and/or rights consistent with this
- License. However, in accepting such obligations, You may act only
- on Your own behalf and on Your sole responsibility, not on behalf
- of any other Contributor, and only if You agree to indemnify,
- defend, and hold each Contributor harmless for any liability
- incurred by, or claims asserted against, such Contributor by reason
- of your accepting any such warranty or additional liability.
-
---- License for python-keystoneclient versions prior to 2.1 ---
-
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
-
- 1. Redistributions of source code must retain the above copyright notice,
- this list of conditions and the following disclaimer.
-
- 2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-
- 3. Neither the name of this project nor the names of its contributors may
- be used to endorse or promote products derived from this software without
- specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
-FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
-SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
-CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
-OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/moonv4/moon_consul/README.md b/moonv4/moon_consul/README.md
deleted file mode 100644
index afee9be5..00000000
--- a/moonv4/moon_consul/README.md
+++ /dev/null
@@ -1,9 +0,0 @@
-DB module for the Moon project
-==============================
-
-This package contains the database module for the Moon project
-It is designed to provide a driver to access the Moon database.
-
-For any other information, refer to the parent project:
-
- https://git.opnfv.org/moon
diff --git a/moonv4/moon_consul/moon_consul/__init__.py b/moonv4/moon_consul/moon_consul/__init__.py
deleted file mode 100644
index 3dc1f76b..00000000
--- a/moonv4/moon_consul/moon_consul/__init__.py
+++ /dev/null
@@ -1 +0,0 @@
-__version__ = "0.1.0"
diff --git a/moonv4/moon_consul/moon_consul/__main__.py b/moonv4/moon_consul/moon_consul/__main__.py
deleted file mode 100644
index 4d64288e..00000000
--- a/moonv4/moon_consul/moon_consul/__main__.py
+++ /dev/null
@@ -1,3 +0,0 @@
-from moon_consul.server import main
-
-main()
diff --git a/moonv4/moon_consul/moon_consul/api/database.py b/moonv4/moon_consul/moon_consul/api/database.py
deleted file mode 100644
index 5533b1a5..00000000
--- a/moonv4/moon_consul/moon_consul/api/database.py
+++ /dev/null
@@ -1,72 +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'.
-"""
-Assignments allow to connect data with elements of perimeter
-
-"""
-
-from flask import request
-from flask_restful import Resource
-# from oslo_config import cfg
-from oslo_log import log as logging
-# from moon_interface.tools import check_auth
-
-__version__ = "0.1.0"
-
-LOG = logging.getLogger(__name__)
-# CONF = cfg.CONF
-
-
-class Database(Resource):
- """
- Endpoint for database requests
- """
-
- __urls__ = (
- "/configuration/database",
- )
-
- def __init__(self, *args, **kwargs):
- self.conf = kwargs.get('conf', {})
-
- # @check_auth
- def get(self):
- """Retrieve database configuration
-
- :return: {
- "database": {
- "hostname": "hostname for the main database",
- "port": "port for the main database",
- "user": "user for the main database",
- "password": "password for the main database",
- "protocol": "protocol to use (eg. mysql+pymysql)",
- "driver": "driver to use",
- }
- }
- """
- url = self.conf.DB_URL
- driver = self.conf.DB_DRIVER
- hostname = url.split("@")[-1].split(":")[0].split("/")[0]
- try:
- port = int(url.split("@")[-1].split(":")[1].split("/")[0])
- except ValueError:
- port = None
- except IndexError:
- port = None
- user = url.split("//")[1].split(":")[0]
- # TODO: password must be encrypted
- password = url.split(":")[2].split("@")[0]
- protocol = url.split(":")[0]
- return {
- "database": {
- "hostname": hostname,
- "port": port,
- "user": user,
- "password": password,
- "protocol": protocol,
- "driver": driver
- }
- }
-
diff --git a/moonv4/moon_consul/moon_consul/api/messenger.py b/moonv4/moon_consul/moon_consul/api/messenger.py
deleted file mode 100644
index 28026baf..00000000
--- a/moonv4/moon_consul/moon_consul/api/messenger.py
+++ /dev/null
@@ -1,67 +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'.
-"""
-Assignments allow to connect data with elements of perimeter
-
-"""
-
-from flask import request
-from flask_restful import Resource
-# from oslo_config import cfg
-from oslo_log import log as logging
-# from moon_interface.tools import check_auth
-
-__version__ = "0.1.0"
-
-LOG = logging.getLogger(__name__)
-# CONF = cfg.CONF
-
-
-class Messenger(Resource):
- """
- Endpoint for messenger requests
- """
-
- __urls__ = (
- "/configuration/messenger",
- )
-
- def __init__(self, *args, **kwargs):
- self.conf = kwargs.get('conf', {})
-
- # @check_auth
- def get(self):
- """Retrieve messenger configuration
-
- :return: {
- "messenger": {
- "hostname": "hostname for the messenger server",
- "port": "port for the main messenger server",
- "user": "user for the main messenger server",
- "password": "password for the main messenger server",
- "protocol": "protocol to use (eg. rabbit)"
- }
- }
- """
- url = self.conf.TRANSPORT_URL
- hostname = url.split("@")[-1].split(":")[0].split("/")[0]
- try:
- port = int(url.split("@")[-1].split(":")[1].split("/")[0])
- except ValueError:
- port = None
- user = url.split("//")[1].split(":")[0]
- # TODO: password must be encrypted
- password = url.split(":")[2].split("@")[0]
- protocol = url.split(":")[0]
- return {
- "messenger": {
- "hostname": hostname,
- "port": port,
- "user": user,
- "password": password,
- "protocol": protocol,
- }
- }
-
diff --git a/moonv4/moon_consul/moon_consul/api/openstack.py b/moonv4/moon_consul/moon_consul/api/openstack.py
deleted file mode 100644
index 5d776981..00000000
--- a/moonv4/moon_consul/moon_consul/api/openstack.py
+++ /dev/null
@@ -1,63 +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'.
-"""
-Assignments allow to connect data with elements of perimeter
-
-"""
-
-from flask import request
-from flask_restful import Resource
-# from oslo_config import cfg
-from oslo_log import log as logging
-# from moon_interface.tools import check_auth
-
-__version__ = "0.1.0"
-
-LOG = logging.getLogger(__name__)
-# CONF = cfg.CONF
-
-
-class Keystone(Resource):
- """
- Endpoint for Keystone requests
- """
-
- __urls__ = (
- "/configuration/os/keystone",
- )
-
- def __init__(self, *args, **kwargs):
- self.conf = kwargs.get('conf', {})
-
- # @check_auth
- def get(self):
- """Retrieve Keystone configuration
-
- :return: {
- "keystone": {
- "url": "hostname for the Keystone server",
- "user": "user for the Keystone server",
- "password": "password for the Keystone server",
- "domain": "domain to use against Keystone server",
- "project": "main project to use",
- "check_token": "yes, no or strict",
- "server_crt": "certificate to use when using https"
- }
- }
- """
- # TODO: password must be encrypted
- # TODO: check_token is a sensitive information it must not be update through the network
- return {
- "keystone": {
- "url": self.conf.KEYSTONE_URL,
- "user": self.conf.KEYSTONE_USER,
- "password": self.conf.KEYSTONE_PASSWORD,
- "domain": self.conf.KEYSTONE_DOMAIN,
- "project": self.conf.KEYSTONE_PROJECT,
- "check_token": self.conf.KEYSTONE_CHECK_TOKEN,
- "server_crt": self.conf.KEYSTONE_SERVER_CRT
- }
- }
-
diff --git a/moonv4/moon_consul/moon_consul/api/slave.py b/moonv4/moon_consul/moon_consul/api/slave.py
deleted file mode 100644
index 7f8acb28..00000000
--- a/moonv4/moon_consul/moon_consul/api/slave.py
+++ /dev/null
@@ -1,72 +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'.
-"""
-Assignments allow to connect data with elements of perimeter
-
-"""
-
-from flask import request
-from flask_restful import Resource
-# from oslo_config import cfg
-from oslo_log import log as logging
-# from moon_interface.tools import check_auth
-
-__version__ = "0.1.0"
-
-LOG = logging.getLogger(__name__)
-# CONF = cfg.CONF
-
-
-class Slave(Resource):
- """
- Endpoint for slave requests
- """
-
- __urls__ = (
- "/configuration/slave",
- )
-
- def __init__(self, *args, **kwargs):
- self.conf = kwargs.get('conf', {})
-
- # @check_auth
- def get(self):
- """Retrieve slave configuration
-
- If current server is a slave:
- :return: {
- "slave": {
- "name": "name of the slave",
- "master_url": "URL of the master",
- "user": [
- {
- "username": "user to be used to connect to the master",
- "password": "password to be used to connect to the master"
- }
- ]
- }
- }
- else:
- :return: {
- "slave": {}
- }
- """
- # TODO: password must be encrypted
- if self.conf.SLAVE_NAME:
- return {
- "slave": {
- "name": self.conf.SLAVE_NAME,
- "master_url": self.conf.MASTER_URL,
- "user": [
- {
- "username": self.conf.MASTER_LOGIN,
- "password": self.conf.MASTER_PASSWORD
- }
- ]
- }
- }
- else:
- return {"slave": {}}
-
diff --git a/moonv4/moon_consul/moon_consul/api/system.py b/moonv4/moon_consul/moon_consul/api/system.py
deleted file mode 100644
index e21d9de2..00000000
--- a/moonv4/moon_consul/moon_consul/api/system.py
+++ /dev/null
@@ -1,169 +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'.
-"""
-Assignments allow to connect data with elements of perimeter
-
-"""
-
-from flask import request
-from flask_restful import Resource
-# from oslo_config import cfg
-from oslo_log import log as logging
-# from moon_interface.tools import check_auth
-
-__version__ = "0.1.0"
-
-LOG = logging.getLogger(__name__)
-# CONF = cfg.CONF
-
-
-class Docker(Resource):
- """
- Endpoint for system requests
- """
-
- __urls__ = (
- "/configuration/docker",
- )
-
- def __init__(self, *args, **kwargs):
- self.conf = kwargs.get('conf', {})
-
- # @check_auth
- def get(self):
- """Retrieve docker configuration
-
- :return: {
- "docker": {
- "url": "hostname for the docker server (eg. /var/run/docker.sock)",
- "port": "port of the server",
- "user": "user of the server",
- "password": "password of the server",
- "protocol": "protocol to use (eg. unix)"
- }
- }
- """
- url = self.conf.DOCKER_URL
- # LOG.info(url)
- # hostname = url.split("@")[-1].split(":")[0].split("/")[0]
- # try:
- # port = int(url.split("@")[-1].split(":")[1].split("/")[0])
- # except ValueError:
- # port = None
- # user = url.split("//")[1].split(":")[0]
- # # TODO: password must be encrypted
- # try:
- # password = url.split(":")[2].split("@")[0]
- # except IndexError:
- # password = ""
- # protocol = url.split(":")[0]
- return {
- "docker": {
- "url": self.conf.DOCKER_URL,
- # "port": port,
- # "user": user,
- # "password": password,
- # "protocol": protocol,
- }
- }
-
-
-class Components(Resource):
- """
- Endpoint for requests on components
- """
-
- __urls__ = (
- "/configuration/components",
- "/configuration/components/",
- "/configuration/components/<string:id_or_name>",
- )
-
- def __init__(self, *args, **kwargs):
- self.conf = kwargs.get('conf', {})
-
- # @check_auth
- def get(self, id_or_name=None):
- """Retrieve component list
-
- :param id_or_name: ID or name of the component
-
- :return: {
- "components": [
- {
- "hostname": "hostname of the component",
- "port": "port of the server in this component",
- "id": "id of the component",
- "keystone_id": "Keystone project ID served by this component if needed"
- },
- ]
- }
- """
- if id_or_name:
- for _component in self.conf.COMPONENTS:
- if id_or_name in (_component["hostname"], _component["id"]):
- return {
- "components": [_component, ]
- }
- return {"components": []}
- return {"components": self.conf.COMPONENTS}
-
- # @check_auth
- def put(self, id_or_name=None):
- """Ask for adding a new component
- The response gives the TCP port to be used
-
- :param id_or_name: ID or name of the component
- :request body: {
- "hostname": "hostname of the new component",
- "keystone_id": "Keystone ID mapped to that component (if needed)"
- }
- :return: {
- "components": [
- {
- "hostname": "hostname of the component",
- "port": "port of the server in this component",
- "id": "id of the component",
- "keystone_id": "Keystone project ID served by this component"
- }
- ]
- }
- """
- if not id_or_name:
- return "Need a name for that component", 400
- for _component in self.conf.COMPONENTS:
- if id_or_name in (_component["hostname"], _component["id"]):
- return "ID already used", 409
- self.conf.COMPONENTS_PORT_START += 1
- port = self.conf.COMPONENTS_PORT_START
- data = request.json
- new_component = {
- "hostname": data.get("hostname", id_or_name),
- "port": port,
- "id": id_or_name,
- "keystone_id": data.get("keystone_id", "")
- }
- self.conf.COMPONENTS.append(new_component)
- return {
- "components": [new_component, ]
- }
-
- # @check_auth
- def delete(self, id_or_name=None):
- """Delete a component
-
- :param id_or_name: ID or name of the component
- :return: {
- "result": true
- }
- """
- if not id_or_name:
- return "Need a name for that component", 400
- for index, _component in enumerate(self.conf.COMPONENTS):
- if id_or_name in (_component["hostname"], _component["id"]):
- self.conf.COMPONENTS.pop(index)
- return {"result": True}
- return "Cannot find component named {}".format(id_or_name), 403
-
diff --git a/moonv4/moon_consul/moon_consul/server.py b/moonv4/moon_consul/moon_consul/server.py
deleted file mode 100644
index 7d42228b..00000000
--- a/moonv4/moon_consul/moon_consul/server.py
+++ /dev/null
@@ -1,82 +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
-# from oslo_config import cfg
-from oslo_log import log as logging
-# from moon_utilities import options # noqa
-from moon_consul.http_server import HTTPServer
-
-LOG = logging.getLogger(__name__)
-# CONF = cfg.CONF
-# DOMAIN = "moon_consul"
-
-# __CWD__ = os.path.dirname(os.path.abspath(__file__))
-
-
-class Configuration:
- DB_URL = None
- DB_DRIVER = None
- TRANSPORT_URL = None
- DOCKER_URL = None
- SLAVE_NAME = None
- MASTER_URL = None
- MASTER_LOGIN = None
- MASTER_PASSWORD = None
- INTERFACE_PORT = None
- CONSUL_HOST = None
- CONSUL_PORT = None
- KEYSTONE_URL = None
- KEYSTONE_USER = None
- KEYSTONE_PASSWORD = None
- KEYSTONE_DOMAIN = None
- KEYSTONE_PROJECT = None
- KEYSTONE_CHECK_TOKEN = None
- KEYSTONE_SERVER_CRT = None
- PLUGIN_CONTAINERS = None
-
-
-def get_configuration():
- conf = Configuration()
- conf.DB_URL = os.getenv("DB_URL", "mysql+pymysql://moon:p4sswOrd1@db/moon")
- conf.DB_DRIVER = os.getenv("DB_DRIVER", "sql")
- conf.TRANSPORT_URL = os.getenv("TRANSPORT_URL", "rabbit://moon:p4sswOrd1@messenger:5672/moon")
- conf.DOCKER_URL = os.getenv("DOCKER_URL", "unix://var/run/docker.sock")
- conf.SLAVE_NAME = os.getenv("SLAVE_NAME", "")
- conf.MASTER_URL = os.getenv("MASTER_URL", "")
- conf.MASTER_LOGIN = os.getenv("MASTER_LOGIN", "")
- conf.MASTER_PASSWORD = os.getenv("MASTER_PASSWORD", "")
- conf.INTERFACE_PORT = os.getenv("INTERFACE_PORT", "8080")
- conf.CONSUL_HOST = os.getenv("CONSUL_HOST", "172.88.88.88")
- conf.CONSUL_PORT = os.getenv("CONSUL_PORT", "88")
- conf.KEYSTONE_URL = os.getenv("KEYSTONE_URL", "http://keystone:5000/v3")
- conf.KEYSTONE_USER = os.getenv("KEYSTONE_USER", "admin")
- conf.KEYSTONE_PASSWORD = os.getenv("KEYSTONE_PASSWORD", "p4ssw0rd")
- conf.KEYSTONE_DOMAIN = os.getenv("KEYSTONE_DOMAIN", "default")
- conf.KEYSTONE_PROJECT = os.getenv("KEYSTONE_PROJECT", "admin")
- conf.KEYSTONE_CHECK_TOKEN = os.getenv("KEYSTONE_CHECK_TOKEN", False)
- conf.KEYSTONE_SERVER_CRT = os.getenv("KEYSTONE_SERVER_CRT", False)
- conf.PLUGIN_CONTAINERS = os.getenv("PLUGIN_CONTAINERS", "asteroide/authz:latest,asteroide/session:latest")
- conf.COMPONENTS_PORT_START = int(os.getenv("COMPONENTS_PORT_START", "38001"))
- conf.COMPONENTS = [
- {
- "hostname": conf.CONSUL_HOST,
- "port": conf.CONSUL_PORT,
- "id": "consul",
- "keystone_id": None
- },
- ]
- return conf
-
-
-def main():
- conf = get_configuration()
- LOG.info("Starting server with IP {} on port {}".format(conf.CONSUL_HOST, conf.CONSUL_PORT))
- server = HTTPServer(host=conf.CONSUL_HOST, port=int(conf.CONSUL_PORT), conf=conf)
- server.run()
-
-
-if __name__ == '__main__':
- main()
diff --git a/moonv4/moon_consul/setup.py b/moonv4/moon_consul/setup.py
deleted file mode 100644
index d4aac83c..00000000
--- a/moonv4/moon_consul/setup.py
+++ /dev/null
@@ -1,50 +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'.
-
-from setuptools import setup, find_packages
-import moon_consul
-
-
-with open('requirements.txt') as f:
- required = f.read().splitlines()
-
-setup(
-
- name='moon_consul',
-
- version=moon_consul.__version__,
-
- packages=find_packages(),
-
- author="Thomas Duval",
-
- author_email="thomas.duval@orange.com",
-
- description="This component is a helper to retrieve configuration across the Moon platform.",
-
- long_description=open('README.md').read(),
-
- install_requires=required,
-
- include_package_data=True,
-
- url='https://git.opnfv.org/cgit/moon/',
-
- classifiers=[
- "Programming Language :: Python",
- "Development Status :: 1 - Planning",
- "License :: OSI Approved",
- "Natural Language :: English",
- "Operating System :: OS Independent",
- "Programming Language :: Python :: 3",
- ],
-
- entry_points={
- 'console_scripts': [
- 'moon_consul = moon_consul.server:run',
- ],
- }
-
-)
diff --git a/moonv4/moon_db/Changelog b/moonv4/moon_db/Changelog
index 16452f6e..de04eadc 100644
--- a/moonv4/moon_db/Changelog
+++ b/moonv4/moon_db/Changelog
@@ -28,3 +28,23 @@ CHANGES
- Fix a bug in core.py
- Update db_manager
+1.1.0
+-----
+- When adding a subject, check the existence of that user in the Keystone DB and
+ create it if necessary
+
+1.2.0
+-----
+- Update the db_manager in order to use it for tests
+
+1.2.1
+-----
+- Update moon_db_manager in order to use it for unit tests
+
+1.2.2
+-----
+- Fix a bug in moon_db_manager
+
+1.2.3
+-----
+- Cleanup moon_db code
diff --git a/moonv4/moon_db/LICENSE b/moonv4/moon_db/LICENSE
index 4143aac2..d6456956 100644
--- a/moonv4/moon_db/LICENSE
+++ b/moonv4/moon_db/LICENSE
@@ -174,31 +174,29 @@
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
---- License for python-keystoneclient versions prior to 2.1 ---
-
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
-
- 1. Redistributions of source code must retain the above copyright notice,
- this list of conditions and the following disclaimer.
-
- 2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-
- 3. Neither the name of this project nor the names of its contributors may
- be used to endorse or promote products derived from this software without
- specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
-FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
-SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
-CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
-OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ END OF TERMS AND CONDITIONS
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright [yyyy] [name of copyright owner]
+
+ 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.
diff --git a/moonv4/moon_db/MANIFEST.in b/moonv4/moon_db/MANIFEST.in
index ba8a657e..82b40140 100644
--- a/moonv4/moon_db/MANIFEST.in
+++ b/moonv4/moon_db/MANIFEST.in
@@ -7,5 +7,4 @@ include README.rst
include LICENSE
include setup.py
include requirements.txt
-# graft tests
graft bin \ No newline at end of file
diff --git a/moonv4/moon_db/README.md b/moonv4/moon_db/README.md
new file mode 100644
index 00000000..5aa877fc
--- /dev/null
+++ b/moonv4/moon_db/README.md
@@ -0,0 +1,32 @@
+# moon_db
+
+This package contains the database module for the Moon project
+It is designed to provide a driver to access the Moon database.
+
+For any other information, refer to the parent project:
+
+ https://git.opnfv.org/moon
+
+## Build
+### Build Python Package
+```bash
+cd ${MOON_HOME}/moonv4/moon_db
+python3 setup.py sdist bdist_wheel
+```
+
+### Push Python Package to PIP
+```bash
+cd ${MOON_HOME}/moonv4/moon_db
+gpg --detach-sign -u "${GPG_ID}" -a dist/moon_db-X.Y.Z-py3-none-any.whl
+gpg --detach-sign -u "${GPG_ID}" -a dist/moon_db-X.Y.Z.tar.gz
+twine upload dist/moon_db-X.Y.Z-py3-none-any.whl dist/moon_db-X.Y.Z-py3-none-any.whl.asc
+twine upload dist/moon_db-X.Y.Z.tar.gz dist/moon_db-X.Y.Z.tar.gz.asc
+```
+
+## Test
+### Python Unit Test
+launch Docker for Python unit tests
+```bash
+cd ${MOON_HOME}/moonv4/moon_db
+docker run --rm --volume $(pwd):/data wukongsun/moon_python_unit_test:latest
+``` \ No newline at end of file
diff --git a/moonv4/moon_db/README.rst b/moonv4/moon_db/README.rst
deleted file mode 100644
index afee9be5..00000000
--- a/moonv4/moon_db/README.rst
+++ /dev/null
@@ -1,9 +0,0 @@
-DB module for the Moon project
-==============================
-
-This package contains the database module for the Moon project
-It is designed to provide a driver to access the Moon database.
-
-For any other information, refer to the parent project:
-
- https://git.opnfv.org/moon
diff --git a/moonv4/moon_db/build.sh b/moonv4/moon_db/build.sh
new file mode 100644
index 00000000..f109e9b8
--- /dev/null
+++ b/moonv4/moon_db/build.sh
@@ -0,0 +1,38 @@
+#!/usr/bin/env bash
+
+VERSION=moon_db-$(grep __version__ moon_db/__init__.py | cut -d "\"" -f 2)
+
+python3 setup.py sdist bdist_wheel
+
+rm dist/*.asc 2>/dev/null
+
+gpg --detach-sign -u "A0A96E75" -a dist/${VERSION}-py3-none-any.whl
+gpg --detach-sign -u "A0A96E75" -a dist/${VERSION}.tar.gz
+
+if [ "$1" = "upload" ]; then
+ twine upload dist/${VERSION}-py3-none-any.whl dist/${VERSION}-py3-none-any.whl.asc
+ twine upload dist/${VERSION}.tar.gz dist/${VERSION}.tar.gz.asc
+ rm -f ../moon_orchestrator/dist/moon_db*
+ rm -f ../moon_interface/dist/moon_db*
+ rm -f ../moon_manager/dist/moon_db*
+ rm -f ../moon_authz/dist/moon_db*
+ rm -f ../moon_wrapper/dist/moon_db*
+fi
+
+if [ "$1" = "copy" ]; then
+ mkdir -p ../moon_orchestrator/dist/ 2>/dev/null
+ rm -f ../moon_orchestrator/dist/moon_db*
+ cp -v dist/${VERSION}-py3-none-any.whl ../moon_orchestrator/dist/
+ mkdir -p ../moon_interface/dist/ 2>/dev/null
+ rm -f ../moon_interface/dist/moon_db*
+ cp -v dist/${VERSION}-py3-none-any.whl ../moon_interface/dist/
+ mkdir -p ../moon_manager/dist/ 2>/dev/null
+ rm -f ../moon_manager/dist/moon_db*
+ cp -v dist/${VERSION}-py3-none-any.whl ../moon_manager/dist/
+ mkdir -p ../moon_authz/dist/ 2>/dev/null
+ rm -f ../moon_authz/dist/moon_db*
+ cp -v dist/${VERSION}-py3-none-any.whl ../moon_authz/dist/
+ mkdir -p ../moon_wrapper/dist/ 2>/dev/null
+ rm -f ../moon_wrapper/dist/moon_db*
+ cp -v dist/${VERSION}-py3-none-any.whl ../moon_wrapper/dist/
+fi
diff --git a/moonv4/moon_db/moon_db/__init__.py b/moonv4/moon_db/moon_db/__init__.py
index d42cdbdf..0be29aa0 100644
--- a/moonv4/moon_db/moon_db/__init__.py
+++ b/moonv4/moon_db/moon_db/__init__.py
@@ -3,5 +3,5 @@
# 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.0.3"
+__version__ = "1.2.3"
diff --git a/moonv4/moon_db/moon_db/api/policy.py b/moonv4/moon_db/moon_db/api/policy.py
index e0413bdc..272872ad 100644
--- a/moonv4/moon_db/moon_db/api/policy.py
+++ b/moonv4/moon_db/moon_db/api/policy.py
@@ -4,11 +4,10 @@
# or at 'http://www.apache.org/licenses/LICENSE-2.0'.
from uuid import uuid4
-from oslo_log import log as logging
-from moon_utilities.security_functions import filter_input, enforce
+import logging
+from moon_utilities.security_functions import enforce
from moon_db.api.managers import Managers
-
LOG = logging.getLogger("moon.db.api.policy")
@@ -52,9 +51,22 @@ class PolicyManager(Managers):
@enforce(("read", "write"), "perimeter")
def add_subject(self, user_id, policy_id, perimeter_id=None, value=None):
+ k_user = Managers.KeystoneManager.get_user_by_name(value.get('name'))
+ if not k_user['users']:
+ k_user = Managers.KeystoneManager.create_user(value)
if not perimeter_id:
- perimeter_id = uuid4().hex
- # TODO (asteroide): must check and add Keystone ID here
+ try:
+ LOG.info("k_user={}".format(k_user))
+ perimeter_id = k_user['users'][0].get('id', uuid4().hex)
+ except IndexError:
+ k_user = Managers.KeystoneManager.get_user_by_name(
+ value.get('name'))
+ perimeter_id = uuid4().hex
+ except KeyError:
+ k_user = Managers.KeystoneManager.get_user_by_name(
+ value.get('name'))
+ perimeter_id = uuid4().hex
+ value.update(k_user['users'][0])
return self.driver.set_subject(policy_id=policy_id, perimeter_id=perimeter_id, value=value)
@enforce(("read", "write"), "perimeter")
diff --git a/moonv4/moon_db/moon_db/api/tenants.py b/moonv4/moon_db/moon_db/api/tenants.py
deleted file mode 100644
index 527e6712..00000000
--- a/moonv4/moon_db/moon_db/api/tenants.py
+++ /dev/null
@@ -1,137 +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'.
-
-from uuid import uuid4
-from moon_utilities import exceptions
-from moon_db.api.managers import Managers
-from moon_utilities.security_functions import filter_input, enforce
-from oslo_log import log as logging
-
-LOG = logging.getLogger("moon.db.api.tenants")
-
-
-class TenantManager(Managers):
-
- def __init__(self, connector=None):
- self.driver = connector.driver
- Managers.TenantManager = self
-
- @filter_input
- @enforce("read", "tenants")
- def get_tenants_dict(self, user_id):
- """
- Return a dictionary with all tenants
- :return: {
- tenant_id1: {
- name: xxx,
- description: yyy,
- intra_authz_extension_id: zzz,
- intra_admin_extension_id: zzz,
- },
- tenant_id2: {...},
- ...
- }
- """
- return self.driver.get_tenants_dict()
-
- def __get_keystone_tenant_dict(self, tenant_id="", tenant_name=""):
- tenants = Managers.KeystoneManager.list_projects()
- for tenant in tenants:
- if tenant_id and tenant_id == tenant['id']:
- return tenant
- if tenant_name and tenant_name == tenant['name']:
- return tenant
- if not tenant_id:
- tenant_id = uuid4().hex
- if not tenant_name:
- tenant_name = tenant_id
- tenant = {
- "id": tenant_id,
- "name": tenant_name,
- "description": "Auto generated tenant from Moon platform",
- "enabled": True,
- "domain_id": "default"
- }
- keystone_tenant = Managers.KeystoneManager.create_project(tenant["id"], tenant)
- return keystone_tenant
-
- @filter_input
- @enforce(("read", "write"), "tenants")
- def add_tenant_dict(self, user_id, tenant_id, tenant_dict):
- tenants_dict = self.driver.get_tenants_dict()
- for tenant_id in tenants_dict:
- if tenants_dict[tenant_id]['name'] == tenant_dict['name']:
- raise exceptions.TenantAddedNameExisting()
-
- # Check (and eventually sync) Keystone tenant
- if 'id' not in tenant_dict:
- tenant_dict['id'] = None
- keystone_tenant = self.__get_keystone_tenant_dict(tenant_dict['id'], tenant_dict['name'])
- for att in keystone_tenant:
- if keystone_tenant[att]:
- tenant_dict[att] = keystone_tenant[att]
- # Sync users between intra_authz_extension and intra_admin_extension
- LOG.debug("add_tenant_dict {}".format(tenant_dict))
- if 'intra_admin_extension_id' in tenant_dict and tenant_dict['intra_admin_extension_id']:
- if 'intra_authz_extension_id' in tenant_dict and tenant_dict['intra_authz_extension_id']:
- authz_subjects_dict = Managers.IntraExtensionAdminManager.get_subjects_dict(
- Managers.IntraExtensionRootManager.root_admin_id, tenant_dict['intra_authz_extension_id'])
- authz_subject_names_list = [authz_subjects_dict[subject_id]["name"] for subject_id in authz_subjects_dict]
- admin_subjects_dict = Managers.IntraExtensionAdminManager.get_subjects_dict(
- Managers.IntraExtensionRootManager.root_admin_id, tenant_dict['intra_admin_extension_id'])
- admin_subject_names_list = [admin_subjects_dict[subject_id]["name"] for subject_id in admin_subjects_dict]
- for _subject_id in authz_subjects_dict:
- if authz_subjects_dict[_subject_id]["name"] not in admin_subject_names_list:
- Managers.IntraExtensionAdminManager.add_subject_dict(
- Managers.IntraExtensionRootManager.root_admin_id, tenant_dict['intra_admin_extension_id'], authz_subjects_dict[_subject_id])
- for _subject_id in admin_subjects_dict:
- if admin_subjects_dict[_subject_id]["name"] not in authz_subject_names_list:
- Managers.IntraExtensionAdminManager.add_subject_dict(
- Managers.IntraExtensionRootManager.root_admin_id, tenant_dict['intra_authz_extension_id'], admin_subjects_dict[_subject_id])
-
- return self.driver.add_tenant_dict(tenant_dict['id'], tenant_dict)
-
- @filter_input
- @enforce("read", "tenants")
- def get_tenant_dict(self, user_id, tenant_id):
- tenants_dict = self.driver.get_tenants_dict()
- if tenant_id not in tenants_dict:
- raise exceptions.TenantUnknown()
- return tenants_dict[tenant_id]
-
- @filter_input
- @enforce(("read", "write"), "tenants")
- def del_tenant(self, user_id, tenant_id):
- if tenant_id not in self.driver.get_tenants_dict():
- raise exceptions.TenantUnknown()
- self.driver.del_tenant(tenant_id)
-
- @filter_input
- @enforce(("read", "write"), "tenants")
- def set_tenant_dict(self, user_id, tenant_id, tenant_dict):
- tenants_dict = self.driver.get_tenants_dict()
- if tenant_id not in tenants_dict:
- raise exceptions.TenantUnknown()
-
- # Sync users between intra_authz_extension and intra_admin_extension
- if 'intra_admin_extension_id' in tenant_dict:
- if 'intra_authz_extension_id' in tenant_dict:
- authz_subjects_dict = Managers.IntraExtensionAdminManager.get_subjects_dict(
- Managers.IntraExtensionRootManager.root_admin_id, tenant_dict['intra_authz_extension_id'])
- authz_subject_names_list = [authz_subjects_dict[subject_id]["name"] for subject_id in authz_subjects_dict]
- admin_subjects_dict = Managers.IntraExtensionAdminManager.get_subjects_dict(
- Managers.IntraExtensionRootManager.root_admin_id, tenant_dict['intra_admin_extension_id'])
- admin_subject_names_list = [admin_subjects_dict[subject_id]["name"] for subject_id in admin_subjects_dict]
- for _subject_id in authz_subjects_dict:
- if authz_subjects_dict[_subject_id]["name"] not in admin_subject_names_list:
- Managers.IntraExtensionAdminManager.add_subject_dict(
- Managers.IntraExtensionRootManager.root_admin_id, tenant_dict['intra_admin_extension_id'], authz_subjects_dict[_subject_id])
- for _subject_id in admin_subjects_dict:
- if admin_subjects_dict[_subject_id]["name"] not in authz_subject_names_list:
- Managers.IntraExtensionAdminManager.add_subject_dict(
- Managers.IntraExtensionRootManager.root_admin_id, tenant_dict['intra_authz_extension_id'], admin_subjects_dict[_subject_id])
-
- return self.driver.set_tenant_dict(tenant_id, tenant_dict)
-
diff --git a/moonv4/moon_db/moon_db/backends/memory.py b/moonv4/moon_db/moon_db/backends/memory.py
deleted file mode 100644
index 5762b183..00000000
--- a/moonv4/moon_db/moon_db/backends/memory.py
+++ /dev/null
@@ -1,60 +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 json
-import logging
-import hashlib
-from glob import glob
-from oslo_config import cfg
-from moon_db.core import ConfigurationDriver
-
-LOG = logging.getLogger("moon.db.driver.memory")
-CONF = cfg.CONF
-
-
-class ConfigurationConnector(object):
-
- def __init__(self, engine):
- super(ConfigurationConnector, self).__init__()
- self.policy_directory = CONF.policy_directory
- self.aggregation_algorithms_dict = dict()
- self.aggregation_algorithms_dict[hashlib.sha224("all_true".encode("utf-8")).hexdigest()[:32]] = \
- {'name': 'all_true', 'description': 'all rules must match'}
- self.aggregation_algorithms_dict[hashlib.sha224("one_true".encode("utf-8")).hexdigest()[:32]] = \
- {'name': 'one_true', 'description': 'only one rule has to match'}
- self.sub_meta_rule_algorithms_dict = dict()
- self.sub_meta_rule_algorithms_dict[hashlib.sha224("inclusion".encode("utf-8")).hexdigest()[:32]] = \
- {'name': 'inclusion', 'description': 'inclusion'}
- self.sub_meta_rule_algorithms_dict[hashlib.sha224("comparison".encode("utf-8")).hexdigest()[:32]] = \
- {'name': 'comparison', 'description': 'comparison'}
-
- def get_policy_templates_dict(self):
- """
- :return: {
- template_id1: {name: template_name, description: template_description},
- template_id2: {name: template_name, description: template_description},
- ...
- }
- """
- nodes = glob(os.path.join(self.policy_directory, "*"))
- LOG.info("get_policy_templates_dict {} {}".format(self.policy_directory, nodes))
- templates = dict()
- for node in nodes:
- try:
- metadata = json.load(open(os.path.join(node, "metadata.json")))
- except IOError:
- # Note (asteroide): it's not a true policy directory, so we forgive it
- continue
- templates[os.path.basename(node)] = dict()
- templates[os.path.basename(node)]["name"] = metadata["name"]
- templates[os.path.basename(node)]["description"] = metadata["description"]
- return templates
-
- def get_aggregation_algorithms_dict(self):
- return self.aggregation_algorithms_dict
-
- def get_sub_meta_rule_algorithms_dict(self):
- return self.sub_meta_rule_algorithms_dict
diff --git a/moonv4/moon_db/moon_db/db_manager.py b/moonv4/moon_db/moon_db/db_manager.py
index 81e6fe77..75cbcdb0 100644
--- a/moonv4/moon_db/moon_db/db_manager.py
+++ b/moonv4/moon_db/moon_db/db_manager.py
@@ -14,51 +14,69 @@ from sqlalchemy import create_engine
from moon_db.migrate_repo import versions
from moon_utilities import configuration
-parser = argparse.ArgumentParser()
-parser.add_argument('command', help='command (upgrade or downgrade)', nargs=1)
-parser.add_argument("--verbose", "-v", action='store_true', help="verbose mode")
-parser.add_argument("--debug", "-d", action='store_true', help="debug mode")
-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)
+def init_args():
+ parser = argparse.ArgumentParser()
+ parser.add_argument('command', help='command (upgrade or downgrade)',
+ nargs=1)
+ parser.add_argument("--verbose", "-v", action='store_true',
+ help="verbose mode")
+ parser.add_argument("--debug", "-d", action='store_true',
+ help="debug mode")
+ args = parser.parse_args()
-requests_log = logging.getLogger("requests.packages.urllib3")
-requests_log.setLevel(logging.WARNING)
-requests_log.propagate = True
+ 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)
-logger = logging.getLogger("moon.db.manager")
+ requests_log = logging.getLogger("requests.packages.urllib3")
+ requests_log.setLevel(logging.WARNING)
+ requests_log.propagate = True
-db_conf = configuration.get_configuration("database")["database"]
-engine = create_engine(db_conf['url'])
+ logger = logging.getLogger("moon.db.manager")
+ return args, logger
-def format_data(ext):
- return ext.name, ext.obj.upgrade()
+def init_engine():
+ db_conf = configuration.get_configuration("database")["database"]
+ return create_engine(db_conf['url'])
-def run():
+def main(command, logger, engine):
files = glob.glob(versions.__path__[0] + "/[0-9][0-9][0-9]*.py")
for filename in files:
filename = os.path.basename(filename).replace(".py", "")
- o = importlib.import_module("moon_db.migrate_repo.versions.{}".format(filename))
- logger.info("Command is {}".format(args.command[0]))
- if args.command[0] in ("upgrade", "u", "up"):
- logger.info("upgrading moon_db.migrate_repo.versions.{}".format(filename))
+ o = importlib.import_module(
+ "moon_db.migrate_repo.versions.{}".format(filename))
+ logger.info("Command is {}".format(command))
+ if command in ("upgrade", "u", "up"):
+ logger.info(
+ "upgrading moon_db.migrate_repo.versions.{}".format(filename))
o.upgrade(engine)
- elif args.command[0] in ("downgrade", "d", "down"):
- logger.info("downgrading moon_db.migrate_repo.versions.{}".format(filename))
+ elif command in ("downgrade", "d", "down"):
+ logger.info(
+ "downgrading moon_db.migrate_repo.versions.{}".format(
+ filename))
o.downgrade(engine)
else:
logger.critical("Cannot understand the command!")
+
+
+def run():
+ args, logger = init_args()
+ engine = init_engine()
+ main(args.command[0], logger, engine)
+
+
+if __name__ == "__main__":
+ run()
diff --git a/moonv4/moon_db/setup.py b/moonv4/moon_db/setup.py
index 0d2aa1bf..0cd90940 100644
--- a/moonv4/moon_db/setup.py
+++ b/moonv4/moon_db/setup.py
@@ -24,7 +24,7 @@ setup(
description="This library is a helper to interact with the Moon database.",
- long_description=open('README.rst').read(),
+ long_description=open('README.md').read(),
install_requires=required,
@@ -46,7 +46,6 @@ setup(
[
"sql = moon_db.backends.sql:SQLConnector",
"flat = moon_db.backends.flat:LogConnector",
- "memory = moon_db.backends.memory:ConfigurationConnector",
],
'console_scripts': [
'moon_db_manager = moon_db.db_manager:run',
diff --git a/moonv4/moon_db/tests/configure_db.sh b/moonv4/moon_db/tests/configure_db.sh
deleted file mode 100644
index bdc259fe..00000000
--- a/moonv4/moon_db/tests/configure_db.sh
+++ /dev/null
@@ -1,9 +0,0 @@
-#!/usr/bin/env bash
-
-apt-get install mysql-server python-mysqldb python-pymysql
-
-mysql -uroot -ppassword <<EOF
-CREATE DATABASE moon DEFAULT CHARACTER SET utf8 DEFAULT COLLATE utf8_general_ci;
-GRANT ALL ON moon.* TO 'moonuser'@'%' IDENTIFIED BY 'password';
-GRANT ALL ON moon.* TO 'moonuser'@'localhost' IDENTIFIED BY 'password';
-EOF
diff --git a/moonv4/moon_db/tests/test_intraextension.py b/moonv4/moon_db/tests/test_intraextension.py
deleted file mode 100644
index a2267214..00000000
--- a/moonv4/moon_db/tests/test_intraextension.py
+++ /dev/null
@@ -1,44 +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 moon_db
-import uuid
-
-Connector = moon_db.Driver("sql", "mysql+pymysql://moonuser:password@localhost/moon")
-Connector.driver.init_db()
-
-
-def create_intra_extension(policy_model="policy_authz"):
- ie = dict()
- ie['id'] = uuid.uuid4().hex
- ie["name"] = "test IE " + uuid.uuid4().hex
- ie["policymodel"] = "policy_authz"
- ie["description"] = "a simple description."
- ie["model"] = policy_model
- genre = "admin"
- if "authz" in policy_model:
- genre = "authz"
- ie["genre"] = genre
- # ref = self.admin_api.load_intra_extension_dict(self.root_api.root_admin_id,
- # intra_extension_dict=ie)
- # self.admin_api.populate_default_data(ref)
- return ie
-
-
-def test_get_intraextension():
- t = Connector.driver.get_intra_extensions_dict()
- assert type(t) == dict
-
-
-def test_set_intra_extension():
- number_of_ie = len(Connector.driver.get_intra_extensions_dict())
- ie = create_intra_extension()
- data = Connector.driver.set_intra_extension_dict(ie['id'], ie)
- assert type(data) == dict
- assert len(Connector.driver.get_intra_extensions_dict()) == number_of_ie+1
-
-
-# TODO (dthom): all tests can be got from keystone-moon
diff --git a/moonv4/moon_db/tests/test_tenant.py b/moonv4/moon_db/tests/test_tenant.py
deleted file mode 100644
index 7e6cfa82..00000000
--- a/moonv4/moon_db/tests/test_tenant.py
+++ /dev/null
@@ -1,86 +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 moon_db
-import uuid
-
-Connector = moon_db.Driver("sql", "mysql+pymysql://moonuser:password@localhost/moon")
-Connector.driver.init_db()
-
-
-def test_get_tenants():
- t = Connector.driver.get_tenants_dict()
- print(t)
- assert type(t) == dict
-
-
-def test_add_tenant():
- new_tenant = {
- "id": uuid.uuid4().hex,
- "name": "demo",
- "description": uuid.uuid4().hex,
- "intra_authz_extension_id": "",
- "intra_admin_extension_id": "",
- }
- data = Connector.driver.add_tenant_dict(tenant_id=new_tenant['id'],
- tenant_dict=new_tenant)
- data_id = list(data.keys())[0]
- assert new_tenant["id"] == data_id
- assert new_tenant["name"] == data[data_id]["name"]
- assert new_tenant["intra_authz_extension_id"] == data[data_id]["intra_authz_extension_id"]
- assert new_tenant["intra_admin_extension_id"] == data[data_id]["intra_admin_extension_id"]
- data = Connector.driver.get_tenants_dict()
- assert data != {}
-
-
-def test_del_tenant():
- new_tenant = {
- "id": uuid.uuid4().hex,
- "name": "demo",
- "description": uuid.uuid4().hex,
- "intra_authz_extension_id": "",
- "intra_admin_extension_id": "",
- }
- data = Connector.driver.get_tenants_dict()
- number_of_tenant = len(data.keys())
- data = Connector.driver.add_tenant_dict(tenant_id=new_tenant['id'],
- tenant_dict=new_tenant)
- data_id = list(data.keys())[0]
- assert new_tenant["name"] == data[data_id]["name"]
- assert new_tenant["intra_authz_extension_id"] == data[data_id]["intra_authz_extension_id"]
- assert new_tenant["intra_admin_extension_id"] == data[data_id]["intra_admin_extension_id"]
- data = Connector.driver.get_tenants_dict()
- assert len(data.keys()) == number_of_tenant+1
- Connector.driver.del_tenant(data_id)
- data = Connector.driver.get_tenants_dict()
- assert len(data.keys()) == number_of_tenant
-
-
-def test_set_tenant():
- new_tenant = {
- "id": uuid.uuid4().hex,
- "name": "demo",
- "description": uuid.uuid4().hex,
- "intra_authz_extension_id": "123456",
- "intra_admin_extension_id": "0987654",
- }
- data = Connector.driver.get_tenants_dict()
- number_of_tenant = len(data.keys())
- data = Connector.driver.add_tenant_dict(tenant_id=new_tenant['id'],
- tenant_dict=new_tenant)
- data_id = list(data.keys())[0]
- assert new_tenant["name"] == data[data_id]["name"]
- assert new_tenant["intra_authz_extension_id"] == data[data_id]["intra_authz_extension_id"]
- assert new_tenant["intra_admin_extension_id"] == data[data_id]["intra_admin_extension_id"]
- data = Connector.driver.get_tenants_dict()
- assert len(data.keys()) == number_of_tenant+1
-
- new_tenant["name"] = "demo2"
- data = Connector.driver.set_tenant_dict(tenant_id=data_id, tenant_dict=new_tenant)
- data_id = list(data.keys())[0]
- assert new_tenant["name"] == data[data_id]["name"]
- assert new_tenant["intra_authz_extension_id"] == data[data_id]["intra_authz_extension_id"]
- assert new_tenant["intra_admin_extension_id"] == data[data_id]["intra_admin_extension_id"]
-
diff --git a/moonv4/moon_db/tests/unit_python/conftest.py b/moonv4/moon_db/tests/unit_python/conftest.py
new file mode 100644
index 00000000..c2e5e579
--- /dev/null
+++ b/moonv4/moon_db/tests/unit_python/conftest.py
@@ -0,0 +1,145 @@
+import base64
+import json
+import logging
+import os
+import pytest
+import requests_mock
+import mock_components
+import mock_keystone
+
+CONF = {
+ "openstack": {
+ "keystone": {
+ "url": "http://keystone:5000/v3",
+ "user": "admin",
+ "check_token": False,
+ "password": "p4ssw0rd",
+ "domain": "default",
+ "certificate": False,
+ "project": "admin"
+ }
+ },
+ "components": {
+ "wrapper": {
+ "bind": "0.0.0.0",
+ "port": 8080,
+ "container": "wukongsun/moon_wrapper:v4.3",
+ "timeout": 5,
+ "hostname": "wrapper"
+ },
+ "manager": {
+ "bind": "0.0.0.0",
+ "port": 8082,
+ "container": "wukongsun/moon_manager:v4.3",
+ "hostname": "manager"
+ },
+ "port_start": 31001,
+ "orchestrator": {
+ "bind": "0.0.0.0",
+ "port": 8083,
+ "container": "wukongsun/moon_orchestrator:v4.3",
+ "hostname": "interface"
+ },
+ "interface": {
+ "bind": "0.0.0.0",
+ "port": 8080,
+ "container": "wukongsun/moon_interface:v4.3",
+ "hostname": "interface"
+ }
+ },
+ "plugins": {
+ "session": {
+ "port": 8082,
+ "container": "asteroide/session:latest"
+ },
+ "authz": {
+ "port": 8081,
+ "container": "wukongsun/moon_authz:v4.3"
+ }
+ },
+ "logging": {
+ "handlers": {
+ "file": {
+ "filename": "/tmp/moon.log",
+ "class": "logging.handlers.RotatingFileHandler",
+ "level": "DEBUG",
+ "formatter": "custom",
+ "backupCount": 3,
+ "maxBytes": 1048576
+ },
+ "console": {
+ "class": "logging.StreamHandler",
+ "formatter": "brief",
+ "level": "INFO",
+ "stream": "ext://sys.stdout"
+ }
+ },
+ "formatters": {
+ "brief": {
+ "format": "%(levelname)s %(name)s %(message)-30s"
+ },
+ "custom": {
+ "format": "%(asctime)-15s %(levelname)s %(name)s %(message)s"
+ }
+ },
+ "root": {
+ "handlers": [
+ "console"
+ ],
+ "level": "ERROR"
+ },
+ "version": 1,
+ "loggers": {
+ "moon": {
+ "handlers": [
+ "console",
+ "file"
+ ],
+ "propagate": False,
+ "level": "DEBUG"
+ }
+ }
+ },
+ "slave": {
+ "name": None,
+ "master": {
+ "url": None,
+ "login": None,
+ "password": None
+ }
+ },
+ "docker": {
+ "url": "tcp://172.88.88.1:2376",
+ "network": "moon"
+ },
+ "database": {
+ "url": "sqlite:///database.db",
+ # "url": "mysql+pymysql://moon:p4sswOrd1@db/moon",
+ "driver": "sql"
+ },
+ "messenger": {
+ "url": "rabbit://moon:p4sswOrd1@messenger:5672/moon"
+ }
+}
+
+
+@pytest.fixture
+def db():
+ return CONF['database']
+
+
+@pytest.fixture(autouse=True)
+def set_consul_and_db(monkeypatch):
+ """ Modify the response from Requests module
+ """
+ with requests_mock.Mocker(real_http=True) as m:
+ mock_components.register_components(m)
+ mock_keystone.register_keystone(m)
+
+ from moon_db.db_manager import init_engine, main
+ engine = init_engine()
+ main("upgrade", logging.getLogger("db_manager"), engine)
+ yield m
+ os.unlink(CONF['database']['url'].replace("sqlite:///", ""))
+
+
diff --git a/moonv4/moon_db/tests/unit_python/mock_components.py b/moonv4/moon_db/tests/unit_python/mock_components.py
new file mode 100644
index 00000000..a0319e1a
--- /dev/null
+++ b/moonv4/moon_db/tests/unit_python/mock_components.py
@@ -0,0 +1,27 @@
+import utilities
+
+COMPONENTS = (
+ "logging",
+ "openstack/keystone",
+ "database",
+ "slave",
+ "components/manager",
+ "components/orchestrator",
+ "components/interface",
+)
+
+
+def register_components(m):
+ for component in COMPONENTS:
+ m.register_uri(
+ 'GET', 'http://consul:8500/v1/kv/{}'.format(component),
+ json=[{'Key': component, 'Value': utilities.get_b64_conf(component)}]
+ )
+
+ m.register_uri(
+ 'GET', 'http://consul:8500/v1/kv/components?recurse=true',
+ json=[
+ {"Key": key, "Value": utilities.get_b64_conf(key)} for key in COMPONENTS
+ ],
+ # json={'Key': "components", 'Value': get_b64_conf("components")}
+ ) \ No newline at end of file
diff --git a/moonv4/moon_db/tests/unit_python/mock_keystone.py b/moonv4/moon_db/tests/unit_python/mock_keystone.py
new file mode 100644
index 00000000..c0b26b88
--- /dev/null
+++ b/moonv4/moon_db/tests/unit_python/mock_keystone.py
@@ -0,0 +1,23 @@
+def register_keystone(m):
+ 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"
+ }]}
+ ) \ No newline at end of file
diff --git a/moonv4/moon_db/tests/unit_python/requirements.txt b/moonv4/moon_db/tests/unit_python/requirements.txt
new file mode 100644
index 00000000..d6110d12
--- /dev/null
+++ b/moonv4/moon_db/tests/unit_python/requirements.txt
@@ -0,0 +1,5 @@
+sqlalchemy
+pymysql
+pytest
+requests_mock
+moon_utilities \ No newline at end of file
diff --git a/moonv4/moon_db/tests/unit_python/test_policies.py b/moonv4/moon_db/tests/unit_python/test_policies.py
new file mode 100644
index 00000000..3bd1360e
--- /dev/null
+++ b/moonv4/moon_db/tests/unit_python/test_policies.py
@@ -0,0 +1,77 @@
+# 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 moon_db.core import PolicyManager
+ return PolicyManager.get_policies("admin")
+
+
+def add_policies(value=None):
+ from moon_db.core import PolicyManager
+ if not value:
+ value = {
+ "name": "test_policiy",
+ "model_id": "",
+ "genre": "authz",
+ "description": "test",
+ }
+ return PolicyManager.add_policy("admin", value=value)
+
+
+def delete_policies(uuid=None, name=None):
+ from moon_db.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 test_get_policies(db):
+ policies = get_policies()
+ assert isinstance(policies, dict)
+ assert not policies
+
+
+def test_add_policies(db):
+ value = {
+ "name": "test_policy",
+ "model_id": "",
+ "genre": "authz",
+ "description": "test",
+ }
+ policies = add_policies(value)
+ assert isinstance(policies, dict)
+ assert policies
+ assert len(policies.keys()) == 1
+ policy_id = list(policies.keys())[0]
+ for key in ("genre", "name", "model_id", "description"):
+ assert key in policies[policy_id]
+ assert policies[policy_id][key] == value[key]
+
+
+def test_delete_policies(db):
+ value = {
+ "name": "test_policy1",
+ "model_id": "",
+ "genre": "authz",
+ "description": "test",
+ }
+ policies = add_policies(value)
+ policy_id1 = list(policies.keys())[0]
+ value = {
+ "name": "test_policy2",
+ "model_id": "",
+ "genre": "authz",
+ "description": "test",
+ }
+ policies = add_policies(value)
+ policy_id2 = list(policies.keys())[0]
+ assert policy_id1 != policy_id2
+ delete_policies(policy_id1)
+ policies = get_policies()
+ assert policy_id1 not in policies
diff --git a/moonv4/moon_db/tests/unit_python/utilities.py b/moonv4/moon_db/tests/unit_python/utilities.py
new file mode 100644
index 00000000..1d79d890
--- /dev/null
+++ b/moonv4/moon_db/tests/unit_python/utilities.py
@@ -0,0 +1,136 @@
+import base64
+import json
+
+
+CONF = {
+ "openstack": {
+ "keystone": {
+ "url": "http://keystone:5000/v3",
+ "user": "admin",
+ "check_token": False,
+ "password": "p4ssw0rd",
+ "domain": "default",
+ "certificate": False,
+ "project": "admin"
+ }
+ },
+ "components": {
+ "wrapper": {
+ "bind": "0.0.0.0",
+ "port": 8080,
+ "container": "wukongsun/moon_wrapper:v4.3",
+ "timeout": 5,
+ "hostname": "wrapper"
+ },
+ "manager": {
+ "bind": "0.0.0.0",
+ "port": 8082,
+ "container": "wukongsun/moon_manager:v4.3",
+ "hostname": "manager"
+ },
+ "port_start": 31001,
+ "orchestrator": {
+ "bind": "0.0.0.0",
+ "port": 8083,
+ "container": "wukongsun/moon_orchestrator:v4.3",
+ "hostname": "interface"
+ },
+ "interface": {
+ "bind": "0.0.0.0",
+ "port": 8080,
+ "container": "wukongsun/moon_interface:v4.3",
+ "hostname": "interface"
+ }
+ },
+ "plugins": {
+ "session": {
+ "port": 8082,
+ "container": "asteroide/session:latest"
+ },
+ "authz": {
+ "port": 8081,
+ "container": "wukongsun/moon_authz:v4.3"
+ }
+ },
+ "logging": {
+ "handlers": {
+ "file": {
+ "filename": "/tmp/moon.log",
+ "class": "logging.handlers.RotatingFileHandler",
+ "level": "DEBUG",
+ "formatter": "custom",
+ "backupCount": 3,
+ "maxBytes": 1048576
+ },
+ "console": {
+ "class": "logging.StreamHandler",
+ "formatter": "brief",
+ "level": "INFO",
+ "stream": "ext://sys.stdout"
+ }
+ },
+ "formatters": {
+ "brief": {
+ "format": "%(levelname)s %(name)s %(message)-30s"
+ },
+ "custom": {
+ "format": "%(asctime)-15s %(levelname)s %(name)s %(message)s"
+ }
+ },
+ "root": {
+ "handlers": [
+ "console"
+ ],
+ "level": "ERROR"
+ },
+ "version": 1,
+ "loggers": {
+ "moon": {
+ "handlers": [
+ "console",
+ "file"
+ ],
+ "propagate": False,
+ "level": "DEBUG"
+ }
+ }
+ },
+ "slave": {
+ "name": None,
+ "master": {
+ "url": None,
+ "login": None,
+ "password": None
+ }
+ },
+ "docker": {
+ "url": "tcp://172.88.88.1:2376",
+ "network": "moon"
+ },
+ "database": {
+ "url": "sqlite:///database.db",
+ # "url": "mysql+pymysql://moon:p4sswOrd1@db/moon",
+ "driver": "sql"
+ },
+ "messenger": {
+ "url": "rabbit://moon:p4sswOrd1@messenger:5672/moon"
+ }
+}
+
+
+def get_b64_conf(component=None):
+ if component == "components":
+ return base64.b64encode(
+ json.dumps(CONF["components"]).encode('utf-8')+b"\n").decode('utf-8')
+ elif component in CONF:
+ return base64.b64encode(
+ json.dumps(
+ CONF[component]).encode('utf-8')+b"\n").decode('utf-8')
+ elif not component:
+ return base64.b64encode(
+ json.dumps(CONF).encode('utf-8')+b"\n").decode('utf-8')
+ elif "/" in component:
+ key1, _, key2 = component.partition("/")
+ return base64.b64encode(
+ json.dumps(
+ CONF[key1][key2]).encode('utf-8')+b"\n").decode('utf-8')
diff --git a/moonv4/moon_gui/DEV.md b/moonv4/moon_gui/DEV.md
new file mode 100644
index 00000000..28743da3
--- /dev/null
+++ b/moonv4/moon_gui/DEV.md
@@ -0,0 +1,49 @@
+# How-to develop on the Moon platform
+
+## Install the platform
+
+Follow the `moon/moonv4/README.md` file.
+
+## GUI
+
+The GUI code is located at `moon/moonv4/moon_gui`
+The configuration values is at `moonv4/moon_gui/static/app/moon.constants.js`
+
+To be able to only develop the GUI, you can install the Moon platform and run the GUI outside the platform.
+To link the outside GUI to the Moon Manager, you must update the configuration values and specially the
+following variables :
+
+- `{{MANAGER_HOST}}` : the hostname of the Manager (example: 127.0.0.1)
+- `{{MANAGER_PORT}}` : the TCP port of the Manager (30001)
+- `{{KEYSTONE_HOST}}` : the hostname of the Keystone server (example: 127.0.0.1)
+- `{{KEYSTONE_PORT}}` : the TCP port of the Keystone server (30006)
+
+To run the GUI service, follow the `README.md` file.
+
+## Current bugs
+
+1) Models -> "`List of Meta rules`", after updating the meta_rule
+"`Actions` -> `edit`" and clicking on `close`, the main screen doesn't refresh
+
+2) idem if we want to remove the meta_rule
+
+3) after deleting an action perimeter (`Policy` -> `Add an action` -> `select a perimeter` and delete it),
+the dropdown list is not updated
+
+4) when adding a data subject (`Policy` -> `Data` -> `Add a Data Subject`), only the right category names must
+be listed in `Catagory list`. Hide the categories that doesn't belong to that policy.
+
+5) idem for object data
+
+6) idem for action data
+
+7) after adding data (subject, object, action), the dropdown list in `Rules` -> `Add a rules` are not updated
+if the page is not manually refresh by the user and if the `Rules` window is already showing.
+
+8) typographic error in `Add a rules`
+
+9) in `Data` -> `Add a Data Object`, the `Create Data` never create the data in the backend
+
+10) Move the `project` tabular to the end
+
+11) create a simplified version (to be discussed)
diff --git a/moonv4/moon_gui/Dockerfile b/moonv4/moon_gui/Dockerfile
index ef809668..428e1037 100644
--- a/moonv4/moon_gui/Dockerfile
+++ b/moonv4/moon_gui/Dockerfile
@@ -1,11 +1,18 @@
FROM ubuntu:latest
-RUN apt update && apt install nodejs nodejs-legacy npm -y
+RUN apt update && apt install git nodejs nodejs-legacy npm apache2 -y
RUN npm install --global gulp-cli
+ENV MANAGER_HOST="127.0.0.1"
+ENV MANAGER_PORT=8080
+ENV KEYSTONE_HOST="127.0.0.1"
+ENV KEYSTONE_PORT=5000
+
ADD . /root
WORKDIR /root/
+
RUN npm install
-RUN gulp delivery
-CMD ["gulp", "webServerDelivery"] \ No newline at end of file
+#CMD ["gulp"]
+#CMD ["gulp", "webServerDelivery"]
+CMD ["sh", "/root/run.sh"] \ No newline at end of file
diff --git a/moonv4/moon_gui/readme.md b/moonv4/moon_gui/README.md
index ff6e5a97..ff6e5a97 100644
--- a/moonv4/moon_gui/readme.md
+++ b/moonv4/moon_gui/README.md
diff --git a/moonv4/moon_gui/run.sh b/moonv4/moon_gui/run.sh
new file mode 100644
index 00000000..94bc8360
--- /dev/null
+++ b/moonv4/moon_gui/run.sh
@@ -0,0 +1,17 @@
+#!/usr/bin/env bash
+
+service apache2 start
+
+sed "s/{{MANAGER_HOST}}/$MANAGER_HOST/g" -i /root/static/app/moon.constants.js
+sed "s/{{MANAGER_PORT}}/$MANAGER_PORT/g" -i /root/static/app/moon.constants.js
+sed "s/{{KEYSTONE_HOST}}/$KEYSTONE_HOST/g" -i /root/static/app/moon.constants.js
+sed "s/{{KEYSTONE_PORT}}/$KEYSTONE_PORT/g" -i /root/static/app/moon.constants.js
+
+echo "--------------------------"
+cat /root/static/app/moon.constants.js
+echo "--------------------------"
+
+gulp delivery
+cp -rv /root/delivery/* /var/www/html
+
+tail -f /var/log/apache2/error.log
diff --git a/moonv4/moon_gui/static/app/authentication/authentication.controller.js b/moonv4/moon_gui/static/app/authentication/authentication.controller.js
index ce38bc5f..ce38bc5f 100644..100755
--- a/moonv4/moon_gui/static/app/authentication/authentication.controller.js
+++ b/moonv4/moon_gui/static/app/authentication/authentication.controller.js
diff --git a/moonv4/moon_gui/static/app/authentication/authentication.tpl.html b/moonv4/moon_gui/static/app/authentication/authentication.tpl.html
index 77d1646b..77d1646b 100644..100755
--- a/moonv4/moon_gui/static/app/authentication/authentication.tpl.html
+++ b/moonv4/moon_gui/static/app/authentication/authentication.tpl.html
diff --git a/moonv4/moon_gui/static/app/common/404/404.tpl.html b/moonv4/moon_gui/static/app/common/404/404.tpl.html
index 61e0420c..61e0420c 100644..100755
--- a/moonv4/moon_gui/static/app/common/404/404.tpl.html
+++ b/moonv4/moon_gui/static/app/common/404/404.tpl.html
diff --git a/moonv4/moon_gui/static/app/common/compatibility/compatibility.tpl.html b/moonv4/moon_gui/static/app/common/compatibility/compatibility.tpl.html
index 0e32dc4f..0e32dc4f 100644..100755
--- a/moonv4/moon_gui/static/app/common/compatibility/compatibility.tpl.html
+++ b/moonv4/moon_gui/static/app/common/compatibility/compatibility.tpl.html
diff --git a/moonv4/moon_gui/static/app/common/footer/footer.controller.js b/moonv4/moon_gui/static/app/common/footer/footer.controller.js
index d7506840..d7506840 100644..100755
--- a/moonv4/moon_gui/static/app/common/footer/footer.controller.js
+++ b/moonv4/moon_gui/static/app/common/footer/footer.controller.js
diff --git a/moonv4/moon_gui/static/app/common/footer/footer.tpl.html b/moonv4/moon_gui/static/app/common/footer/footer.tpl.html
index aacb392d..aacb392d 100644..100755
--- a/moonv4/moon_gui/static/app/common/footer/footer.tpl.html
+++ b/moonv4/moon_gui/static/app/common/footer/footer.tpl.html
diff --git a/moonv4/moon_gui/static/app/common/header/header.controller.js b/moonv4/moon_gui/static/app/common/header/header.controller.js
index 13ef4d6f..13ef4d6f 100644..100755
--- a/moonv4/moon_gui/static/app/common/header/header.controller.js
+++ b/moonv4/moon_gui/static/app/common/header/header.controller.js
diff --git a/moonv4/moon_gui/static/app/common/header/header.tpl.html b/moonv4/moon_gui/static/app/common/header/header.tpl.html
index f703fa79..f703fa79 100644..100755
--- a/moonv4/moon_gui/static/app/common/header/header.tpl.html
+++ b/moonv4/moon_gui/static/app/common/header/header.tpl.html
diff --git a/moonv4/moon_gui/static/app/common/loader/loader.dir.js b/moonv4/moon_gui/static/app/common/loader/loader.dir.js
index ba40c121..ba40c121 100644..100755
--- a/moonv4/moon_gui/static/app/common/loader/loader.dir.js
+++ b/moonv4/moon_gui/static/app/common/loader/loader.dir.js
diff --git a/moonv4/moon_gui/static/app/common/loader/loader.tpl.html b/moonv4/moon_gui/static/app/common/loader/loader.tpl.html
index 51da439f..51da439f 100644..100755
--- a/moonv4/moon_gui/static/app/common/loader/loader.tpl.html
+++ b/moonv4/moon_gui/static/app/common/loader/loader.tpl.html
diff --git a/moonv4/moon_gui/static/app/common/waiting/waiting.tpl.html b/moonv4/moon_gui/static/app/common/waiting/waiting.tpl.html
index 6c042635..6c042635 100644..100755
--- a/moonv4/moon_gui/static/app/common/waiting/waiting.tpl.html
+++ b/moonv4/moon_gui/static/app/common/waiting/waiting.tpl.html
diff --git a/moonv4/moon_gui/static/app/dashboard/dashboard.tpl.html b/moonv4/moon_gui/static/app/dashboard/dashboard.tpl.html
index 67184bcc..67184bcc 100644..100755
--- a/moonv4/moon_gui/static/app/dashboard/dashboard.tpl.html
+++ b/moonv4/moon_gui/static/app/dashboard/dashboard.tpl.html
diff --git a/moonv4/moon_gui/static/app/logs/logs.controller.js b/moonv4/moon_gui/static/app/logs/logs.controller.js
index e48e2b8b..e48e2b8b 100644..100755
--- a/moonv4/moon_gui/static/app/logs/logs.controller.js
+++ b/moonv4/moon_gui/static/app/logs/logs.controller.js
diff --git a/moonv4/moon_gui/static/app/logs/logs.tpl.html b/moonv4/moon_gui/static/app/logs/logs.tpl.html
index fecc0289..fecc0289 100644..100755
--- a/moonv4/moon_gui/static/app/logs/logs.tpl.html
+++ b/moonv4/moon_gui/static/app/logs/logs.tpl.html
diff --git a/moonv4/moon_gui/static/app/model/action/model-add.tpl.html b/moonv4/moon_gui/static/app/model/action/model-add.tpl.html
index dee53a97..dee53a97 100644..100755
--- a/moonv4/moon_gui/static/app/model/action/model-add.tpl.html
+++ b/moonv4/moon_gui/static/app/model/action/model-add.tpl.html
diff --git a/moonv4/moon_gui/static/app/model/action/model-delete.tpl.html b/moonv4/moon_gui/static/app/model/action/model-delete.tpl.html
index cde16d0e..cde16d0e 100644..100755
--- a/moonv4/moon_gui/static/app/model/action/model-delete.tpl.html
+++ b/moonv4/moon_gui/static/app/model/action/model-delete.tpl.html
diff --git a/moonv4/moon_gui/static/app/model/action/model-view.tpl.html b/moonv4/moon_gui/static/app/model/action/model-view.tpl.html
index 46c295c7..46c295c7 100644..100755
--- a/moonv4/moon_gui/static/app/model/action/model-view.tpl.html
+++ b/moonv4/moon_gui/static/app/model/action/model-view.tpl.html
diff --git a/moonv4/moon_gui/static/app/model/action/model.controller.add.js b/moonv4/moon_gui/static/app/model/action/model.controller.add.js
index 11d3abf4..11d3abf4 100644..100755
--- a/moonv4/moon_gui/static/app/model/action/model.controller.add.js
+++ b/moonv4/moon_gui/static/app/model/action/model.controller.add.js
diff --git a/moonv4/moon_gui/static/app/model/action/model.controller.delete.js b/moonv4/moon_gui/static/app/model/action/model.controller.delete.js
index 5d9dae1a..5d9dae1a 100644..100755
--- a/moonv4/moon_gui/static/app/model/action/model.controller.delete.js
+++ b/moonv4/moon_gui/static/app/model/action/model.controller.delete.js
diff --git a/moonv4/moon_gui/static/app/model/action/model.controller.view.js b/moonv4/moon_gui/static/app/model/action/model.controller.view.js
index 7605eecf..7605eecf 100644..100755
--- a/moonv4/moon_gui/static/app/model/action/model.controller.view.js
+++ b/moonv4/moon_gui/static/app/model/action/model.controller.view.js
diff --git a/moonv4/moon_gui/static/app/model/edit/metadata/metadata-edit.tpl.html b/moonv4/moon_gui/static/app/model/edit/metadata/metadata-edit.tpl.html
index 2616be1c..2616be1c 100644..100755
--- a/moonv4/moon_gui/static/app/model/edit/metadata/metadata-edit.tpl.html
+++ b/moonv4/moon_gui/static/app/model/edit/metadata/metadata-edit.tpl.html
diff --git a/moonv4/moon_gui/static/app/model/edit/metadata/metadata-list.tpl.html b/moonv4/moon_gui/static/app/model/edit/metadata/metadata-list.tpl.html
index 30a42dbc..30a42dbc 100644..100755
--- a/moonv4/moon_gui/static/app/model/edit/metadata/metadata-list.tpl.html
+++ b/moonv4/moon_gui/static/app/model/edit/metadata/metadata-list.tpl.html
diff --git a/moonv4/moon_gui/static/app/model/edit/metadata/metadata.edit.dir.js b/moonv4/moon_gui/static/app/model/edit/metadata/metadata.edit.dir.js
index 10df83b0..10df83b0 100644..100755
--- a/moonv4/moon_gui/static/app/model/edit/metadata/metadata.edit.dir.js
+++ b/moonv4/moon_gui/static/app/model/edit/metadata/metadata.edit.dir.js
diff --git a/moonv4/moon_gui/static/app/model/edit/metadata/metadata.list.dir.js b/moonv4/moon_gui/static/app/model/edit/metadata/metadata.list.dir.js
index beb2ed86..beb2ed86 100644..100755
--- a/moonv4/moon_gui/static/app/model/edit/metadata/metadata.list.dir.js
+++ b/moonv4/moon_gui/static/app/model/edit/metadata/metadata.list.dir.js
diff --git a/moonv4/moon_gui/static/app/model/edit/metarules/action/mapping/metarules-add.tpl.html b/moonv4/moon_gui/static/app/model/edit/metarules/action/mapping/metarules-add.tpl.html
index a721e6d0..a721e6d0 100644..100755
--- a/moonv4/moon_gui/static/app/model/edit/metarules/action/mapping/metarules-add.tpl.html
+++ b/moonv4/moon_gui/static/app/model/edit/metarules/action/mapping/metarules-add.tpl.html
diff --git a/moonv4/moon_gui/static/app/model/edit/metarules/action/mapping/metarules-map.tpl.html b/moonv4/moon_gui/static/app/model/edit/metarules/action/mapping/metarules-map.tpl.html
index 1830204b..1830204b 100644..100755
--- a/moonv4/moon_gui/static/app/model/edit/metarules/action/mapping/metarules-map.tpl.html
+++ b/moonv4/moon_gui/static/app/model/edit/metarules/action/mapping/metarules-map.tpl.html
diff --git a/moonv4/moon_gui/static/app/model/edit/metarules/action/mapping/metarules-unmap.tpl.html b/moonv4/moon_gui/static/app/model/edit/metarules/action/mapping/metarules-unmap.tpl.html
index bb02aba2..bb02aba2 100644..100755
--- a/moonv4/moon_gui/static/app/model/edit/metarules/action/mapping/metarules-unmap.tpl.html
+++ b/moonv4/moon_gui/static/app/model/edit/metarules/action/mapping/metarules-unmap.tpl.html
diff --git a/moonv4/moon_gui/static/app/model/edit/metarules/action/mapping/metarules.controller.add.js b/moonv4/moon_gui/static/app/model/edit/metarules/action/mapping/metarules.controller.add.js
index a95951fa..a95951fa 100644..100755
--- a/moonv4/moon_gui/static/app/model/edit/metarules/action/mapping/metarules.controller.add.js
+++ b/moonv4/moon_gui/static/app/model/edit/metarules/action/mapping/metarules.controller.add.js
diff --git a/moonv4/moon_gui/static/app/model/edit/metarules/action/mapping/metarules.map.controller.js b/moonv4/moon_gui/static/app/model/edit/metarules/action/mapping/metarules.map.controller.js
index cf9ba06c..cf9ba06c 100644..100755
--- a/moonv4/moon_gui/static/app/model/edit/metarules/action/mapping/metarules.map.controller.js
+++ b/moonv4/moon_gui/static/app/model/edit/metarules/action/mapping/metarules.map.controller.js
diff --git a/moonv4/moon_gui/static/app/model/edit/metarules/action/mapping/metarules.unmap.controller.js b/moonv4/moon_gui/static/app/model/edit/metarules/action/mapping/metarules.unmap.controller.js
index 30f32d51..30f32d51 100644..100755
--- a/moonv4/moon_gui/static/app/model/edit/metarules/action/mapping/metarules.unmap.controller.js
+++ b/moonv4/moon_gui/static/app/model/edit/metarules/action/mapping/metarules.unmap.controller.js
diff --git a/moonv4/moon_gui/static/app/model/edit/metarules/action/metarules-edit-basic.tpl.html b/moonv4/moon_gui/static/app/model/edit/metarules/action/metarules-edit-basic.tpl.html
index b6136195..b6136195 100644..100755
--- a/moonv4/moon_gui/static/app/model/edit/metarules/action/metarules-edit-basic.tpl.html
+++ b/moonv4/moon_gui/static/app/model/edit/metarules/action/metarules-edit-basic.tpl.html
diff --git a/moonv4/moon_gui/static/app/model/edit/metarules/action/metarules-edit.tpl.html b/moonv4/moon_gui/static/app/model/edit/metarules/action/metarules-edit.tpl.html
index 7b074448..7b074448 100644..100755
--- a/moonv4/moon_gui/static/app/model/edit/metarules/action/metarules-edit.tpl.html
+++ b/moonv4/moon_gui/static/app/model/edit/metarules/action/metarules-edit.tpl.html
diff --git a/moonv4/moon_gui/static/app/model/edit/metarules/action/metarules.controller.edit.js b/moonv4/moon_gui/static/app/model/edit/metarules/action/metarules.controller.edit.js
index b2ebc45d..b2ebc45d 100644..100755
--- a/moonv4/moon_gui/static/app/model/edit/metarules/action/metarules.controller.edit.js
+++ b/moonv4/moon_gui/static/app/model/edit/metarules/action/metarules.controller.edit.js
diff --git a/moonv4/moon_gui/static/app/model/edit/metarules/action/metarules.edit.basic.dir.js b/moonv4/moon_gui/static/app/model/edit/metarules/action/metarules.edit.basic.dir.js
index 603e7a33..603e7a33 100644..100755
--- a/moonv4/moon_gui/static/app/model/edit/metarules/action/metarules.edit.basic.dir.js
+++ b/moonv4/moon_gui/static/app/model/edit/metarules/action/metarules.edit.basic.dir.js
diff --git a/moonv4/moon_gui/static/app/model/edit/metarules/metarules-list.tpl.html b/moonv4/moon_gui/static/app/model/edit/metarules/metarules-list.tpl.html
index ebe307c3..ebe307c3 100644..100755
--- a/moonv4/moon_gui/static/app/model/edit/metarules/metarules-list.tpl.html
+++ b/moonv4/moon_gui/static/app/model/edit/metarules/metarules-list.tpl.html
diff --git a/moonv4/moon_gui/static/app/model/edit/metarules/metarules.list.dir.js b/moonv4/moon_gui/static/app/model/edit/metarules/metarules.list.dir.js
index 120b6a8b..120b6a8b 100644..100755
--- a/moonv4/moon_gui/static/app/model/edit/metarules/metarules.list.dir.js
+++ b/moonv4/moon_gui/static/app/model/edit/metarules/metarules.list.dir.js
diff --git a/moonv4/moon_gui/static/app/model/edit/model-edit-basic.tpl.html b/moonv4/moon_gui/static/app/model/edit/model-edit-basic.tpl.html
index bd73b4ef..bd73b4ef 100644..100755
--- a/moonv4/moon_gui/static/app/model/edit/model-edit-basic.tpl.html
+++ b/moonv4/moon_gui/static/app/model/edit/model-edit-basic.tpl.html
diff --git a/moonv4/moon_gui/static/app/model/edit/model-edit.tpl.html b/moonv4/moon_gui/static/app/model/edit/model-edit.tpl.html
index 4955f441..4955f441 100644..100755
--- a/moonv4/moon_gui/static/app/model/edit/model-edit.tpl.html
+++ b/moonv4/moon_gui/static/app/model/edit/model-edit.tpl.html
diff --git a/moonv4/moon_gui/static/app/model/edit/model.controller.edit.js b/moonv4/moon_gui/static/app/model/edit/model.controller.edit.js
index 3e10a533..3e10a533 100644..100755
--- a/moonv4/moon_gui/static/app/model/edit/model.controller.edit.js
+++ b/moonv4/moon_gui/static/app/model/edit/model.controller.edit.js
diff --git a/moonv4/moon_gui/static/app/model/edit/model.edit.basic.dir.js b/moonv4/moon_gui/static/app/model/edit/model.edit.basic.dir.js
index 54bb7071..54bb7071 100644..100755
--- a/moonv4/moon_gui/static/app/model/edit/model.edit.basic.dir.js
+++ b/moonv4/moon_gui/static/app/model/edit/model.edit.basic.dir.js
diff --git a/moonv4/moon_gui/static/app/model/model-list.tpl.html b/moonv4/moon_gui/static/app/model/model-list.tpl.html
index 89c682cc..89c682cc 100644..100755
--- a/moonv4/moon_gui/static/app/model/model-list.tpl.html
+++ b/moonv4/moon_gui/static/app/model/model-list.tpl.html
diff --git a/moonv4/moon_gui/static/app/model/model.controller.list.js b/moonv4/moon_gui/static/app/model/model.controller.list.js
index 5021a57e..5021a57e 100644..100755
--- a/moonv4/moon_gui/static/app/model/model.controller.list.js
+++ b/moonv4/moon_gui/static/app/model/model.controller.list.js
diff --git a/moonv4/moon_gui/static/app/moon.constants.js b/moonv4/moon_gui/static/app/moon.constants.js
index 872dfd5a..9681e3dc 100644
--- a/moonv4/moon_gui/static/app/moon.constants.js
+++ b/moonv4/moon_gui/static/app/moon.constants.js
@@ -59,21 +59,21 @@
}
})
.constant('REST_URI', {
- PDP : 'http://interface:8081/pdp/',
- MODELS : 'http://interface:8081/models/',
- METARULES: 'http://interface:8081/meta_rules/',
- RULES: 'http://interface:8081/rules/',
- POLICIES: 'http://interface:8081/policies/',
+ PDP : 'http://{{MANAGER_HOST}}:{{MANAGER_PORT}}/pdp/',
+ MODELS : 'http://{{MANAGER_HOST}}:{{MANAGER_PORT}}/models/',
+ METARULES: 'http://{{MANAGER_HOST}}:{{MANAGER_PORT}}/meta_rules/',
+ RULES: 'http://{{MANAGER_HOST}}:{{MANAGER_PORT}}/rules/',
+ POLICIES: 'http://{{MANAGER_HOST}}:{{MANAGER_PORT}}/policies/',
METADATA: {
- subject : 'http://interface:8081/subject_categories/',
- object : 'http://interface:8081/object_categories/',
- action : 'http://interface:8081/action_categories/'
+ subject : 'http://{{MANAGER_HOST}}:{{MANAGER_PORT}}/subject_categories/',
+ object : 'http://{{MANAGER_HOST}}:{{MANAGER_PORT}}/object_categories/',
+ action : 'http://{{MANAGER_HOST}}:{{MANAGER_PORT}}/action_categories/'
},
PERIMETERS :{
- subject : 'http://interface:8081/subjects/',
- object : 'http://interface:8081/objects/',
- action : 'http://interface:8081/actions/'
+ subject : 'http://{{MANAGER_HOST}}:{{MANAGER_PORT}}/subjects/',
+ object : 'http://{{MANAGER_HOST}}:{{MANAGER_PORT}}/objects/',
+ action : 'http://{{MANAGER_HOST}}:{{MANAGER_PORT}}/actions/'
},
- KEYSTONE : 'http://keystone:5000/v3/'
+ KEYSTONE : 'http://{{KEYSTONE_HOST}}:{{KEYSTONE_PORT}}/v3/'
});
})();
diff --git a/moonv4/moon_gui/static/app/moon.module.js b/moonv4/moon_gui/static/app/moon.module.js
index a653f8f3..a653f8f3 100644..100755
--- a/moonv4/moon_gui/static/app/moon.module.js
+++ b/moonv4/moon_gui/static/app/moon.module.js
diff --git a/moonv4/moon_gui/static/app/pdp/action/pdp-add.tpl.html b/moonv4/moon_gui/static/app/pdp/action/pdp-add.tpl.html
index f83fb85c..f83fb85c 100644..100755
--- a/moonv4/moon_gui/static/app/pdp/action/pdp-add.tpl.html
+++ b/moonv4/moon_gui/static/app/pdp/action/pdp-add.tpl.html
diff --git a/moonv4/moon_gui/static/app/pdp/action/pdp-delete.tpl.html b/moonv4/moon_gui/static/app/pdp/action/pdp-delete.tpl.html
index 167ba417..167ba417 100644..100755
--- a/moonv4/moon_gui/static/app/pdp/action/pdp-delete.tpl.html
+++ b/moonv4/moon_gui/static/app/pdp/action/pdp-delete.tpl.html
diff --git a/moonv4/moon_gui/static/app/pdp/action/pdp.controller.add.js b/moonv4/moon_gui/static/app/pdp/action/pdp.controller.add.js
index d1c34c79..d1c34c79 100644..100755
--- a/moonv4/moon_gui/static/app/pdp/action/pdp.controller.add.js
+++ b/moonv4/moon_gui/static/app/pdp/action/pdp.controller.add.js
diff --git a/moonv4/moon_gui/static/app/pdp/action/pdp.controller.delete.js b/moonv4/moon_gui/static/app/pdp/action/pdp.controller.delete.js
index 62557864..62557864 100644..100755
--- a/moonv4/moon_gui/static/app/pdp/action/pdp.controller.delete.js
+++ b/moonv4/moon_gui/static/app/pdp/action/pdp.controller.delete.js
diff --git a/moonv4/moon_gui/static/app/pdp/edit/pdp-edit-basic.tpl.html b/moonv4/moon_gui/static/app/pdp/edit/pdp-edit-basic.tpl.html
index 887d81ca..887d81ca 100644..100755
--- a/moonv4/moon_gui/static/app/pdp/edit/pdp-edit-basic.tpl.html
+++ b/moonv4/moon_gui/static/app/pdp/edit/pdp-edit-basic.tpl.html
diff --git a/moonv4/moon_gui/static/app/pdp/edit/pdp-edit.tpl.html b/moonv4/moon_gui/static/app/pdp/edit/pdp-edit.tpl.html
index 1fbd555a..1fbd555a 100644..100755
--- a/moonv4/moon_gui/static/app/pdp/edit/pdp-edit.tpl.html
+++ b/moonv4/moon_gui/static/app/pdp/edit/pdp-edit.tpl.html
diff --git a/moonv4/moon_gui/static/app/pdp/edit/pdp.controller.edit.js b/moonv4/moon_gui/static/app/pdp/edit/pdp.controller.edit.js
index 41b73098..41b73098 100644..100755
--- a/moonv4/moon_gui/static/app/pdp/edit/pdp.controller.edit.js
+++ b/moonv4/moon_gui/static/app/pdp/edit/pdp.controller.edit.js
diff --git a/moonv4/moon_gui/static/app/pdp/edit/pdp.edit.basic.dir.js b/moonv4/moon_gui/static/app/pdp/edit/pdp.edit.basic.dir.js
index 402422b6..402422b6 100644..100755
--- a/moonv4/moon_gui/static/app/pdp/edit/pdp.edit.basic.dir.js
+++ b/moonv4/moon_gui/static/app/pdp/edit/pdp.edit.basic.dir.js
diff --git a/moonv4/moon_gui/static/app/pdp/pdp-list.tpl.html b/moonv4/moon_gui/static/app/pdp/pdp-list.tpl.html
index 8aa4e653..8aa4e653 100644..100755
--- a/moonv4/moon_gui/static/app/pdp/pdp-list.tpl.html
+++ b/moonv4/moon_gui/static/app/pdp/pdp-list.tpl.html
diff --git a/moonv4/moon_gui/static/app/pdp/pdp.controller.list.js b/moonv4/moon_gui/static/app/pdp/pdp.controller.list.js
index a831cfe3..a831cfe3 100644..100755
--- a/moonv4/moon_gui/static/app/pdp/pdp.controller.list.js
+++ b/moonv4/moon_gui/static/app/pdp/pdp.controller.list.js
diff --git a/moonv4/moon_gui/static/app/policy/action/mapping/policy-map.tpl.html b/moonv4/moon_gui/static/app/policy/action/mapping/policy-map.tpl.html
index 8b787f14..8b787f14 100644..100755
--- a/moonv4/moon_gui/static/app/policy/action/mapping/policy-map.tpl.html
+++ b/moonv4/moon_gui/static/app/policy/action/mapping/policy-map.tpl.html
diff --git a/moonv4/moon_gui/static/app/policy/action/mapping/policy-unmap.tpl.html b/moonv4/moon_gui/static/app/policy/action/mapping/policy-unmap.tpl.html
index a2cda52a..a2cda52a 100644..100755
--- a/moonv4/moon_gui/static/app/policy/action/mapping/policy-unmap.tpl.html
+++ b/moonv4/moon_gui/static/app/policy/action/mapping/policy-unmap.tpl.html
diff --git a/moonv4/moon_gui/static/app/policy/action/mapping/policy.controller.map.js b/moonv4/moon_gui/static/app/policy/action/mapping/policy.controller.map.js
index 6ad8caa7..6ad8caa7 100644..100755
--- a/moonv4/moon_gui/static/app/policy/action/mapping/policy.controller.map.js
+++ b/moonv4/moon_gui/static/app/policy/action/mapping/policy.controller.map.js
diff --git a/moonv4/moon_gui/static/app/policy/action/mapping/policy.controller.unmap.js b/moonv4/moon_gui/static/app/policy/action/mapping/policy.controller.unmap.js
index d309ec0f..d309ec0f 100644..100755
--- a/moonv4/moon_gui/static/app/policy/action/mapping/policy.controller.unmap.js
+++ b/moonv4/moon_gui/static/app/policy/action/mapping/policy.controller.unmap.js
diff --git a/moonv4/moon_gui/static/app/policy/action/policy-add.tpl.html b/moonv4/moon_gui/static/app/policy/action/policy-add.tpl.html
index d20c41be..d20c41be 100644..100755
--- a/moonv4/moon_gui/static/app/policy/action/policy-add.tpl.html
+++ b/moonv4/moon_gui/static/app/policy/action/policy-add.tpl.html
diff --git a/moonv4/moon_gui/static/app/policy/action/policy-delete.tpl.html b/moonv4/moon_gui/static/app/policy/action/policy-delete.tpl.html
index 3b5df88b..3b5df88b 100644..100755
--- a/moonv4/moon_gui/static/app/policy/action/policy-delete.tpl.html
+++ b/moonv4/moon_gui/static/app/policy/action/policy-delete.tpl.html
diff --git a/moonv4/moon_gui/static/app/policy/action/policy.controller.add.js b/moonv4/moon_gui/static/app/policy/action/policy.controller.add.js
index 0320c2e9..0320c2e9 100644..100755
--- a/moonv4/moon_gui/static/app/policy/action/policy.controller.add.js
+++ b/moonv4/moon_gui/static/app/policy/action/policy.controller.add.js
diff --git a/moonv4/moon_gui/static/app/policy/action/policy.controller.delete.js b/moonv4/moon_gui/static/app/policy/action/policy.controller.delete.js
index 9a718ddc..9a718ddc 100644..100755
--- a/moonv4/moon_gui/static/app/policy/action/policy.controller.delete.js
+++ b/moonv4/moon_gui/static/app/policy/action/policy.controller.delete.js
diff --git a/moonv4/moon_gui/static/app/policy/edit/parameter/assignments/assignments-edit.tpl.html b/moonv4/moon_gui/static/app/policy/edit/parameter/assignments/assignments-edit.tpl.html
new file mode 100755
index 00000000..9069dcd0
--- /dev/null
+++ b/moonv4/moon_gui/static/app/policy/edit/parameter/assignments/assignments-edit.tpl.html
@@ -0,0 +1,165 @@
+<div>
+
+ <div class="col-md-12 col-sm-12 col-xs-12">
+
+ <form ng-if="!edit.fromList" class="form-horizontal" role="form" name="edit.form">
+
+ <!-- Select Policy -->
+ <div class="form-group" ng-class="{'has-error': edit.form.policyList.$invalid && edit.form.policyList.$dirty}" >
+
+ <label for="policyList" class="col-sm-3 control-label" data-translate="moon.policy.assignments.edit.policies">Policy List</label>
+
+ <div class="col-sm-6" ng-if="edit.loadingPolicies" >
+ <moon-loader></moon-loader>
+ </div>
+
+ <div class="col-sm-6" ng-if="!edit.loadingPolicies" >
+
+ <ui-select ng-model="edit.selectedPolicy" name="policyList" id="policyList" required>
+
+ <ui-select-match placeholder="(None)" ng-bind="$select.selected.name"></ui-select-match>
+ <ui-select-choices repeat="aPolicy in edit.policyList">
+ <div ng-value="aPolicy" ng-bind="aPolicy.name"></div>
+ </ui-select-choices>
+
+ </ui-select>
+
+ <div class="help-block" ng-show="edit.form.policyList.$dirty && edit.form.policyList.$invalid">
+ <small class="error" ng-show="edit.form.policyList.$error.required" data-translate="moon.policy.assignments.edit.check.policy.required">Policy is required</small>
+ </div>
+
+ </div>
+
+ </div>
+
+ <!-- Select Perimeter -->
+ <div class="form-group" ng-class="{'has-error': edit.form.perimeterList.$invalid && edit.form.perimeterList.$dirty}" >
+
+ <label for="perimeterList" class="col-sm-3 control-label" data-translate="moon.policy.assignments.edit.perimeters">Perimeter List</label>
+
+ <div class="col-sm-6" ng-if="edit.loadingPerimeters" >
+ <moon-loader></moon-loader>
+ </div>
+
+ <div class="col-sm-6" ng-if="!edit.loadingPerimeters" >
+
+ <ui-select ng-model="edit.selectedPerimeter" name="perimeterList" id="perimeterList" required>
+
+ <ui-select-match placeholder="(None)" ng-bind="$select.selected.name"></ui-select-match>
+ <ui-select-choices repeat="aPerimeter in edit.perimeterList">
+ <div ng-value="aPerimeter" ng-bind="aPerimeter.name"></div>
+ </ui-select-choices>
+
+ </ui-select>
+
+ <div class="help-block" ng-show="edit.form.perimeterList.$dirty && edit.form.perimeterList.$invalid">
+ <small class="error" ng-show="edit.form.perimeterList.$error.required" data-translate="moon.policy.assignments.edit.check.perimeter.required">Perimeter is required</small>
+ </div>
+
+ </div>
+
+ </div>
+
+ <!-- Select Category -->
+ <div class="form-group" ng-class="{'has-error': edit.form.categoryList.$invalid && edit.form.categoryList.$dirty}" >
+
+ <label for="categoryList" class="col-sm-3 control-label" data-translate="moon.policy.assignments.edit.categories">Category List</label>
+
+ <div class="col-sm-6" ng-if="edit.loadingCategories" >
+ <moon-loader></moon-loader>
+ </div>
+
+ <div class="col-sm-6" ng-if="!edit.loadingCategories" >
+
+ <ui-select ng-model="edit.selectedCategory" name="categoryList" id="categoryList" required>
+
+ <ui-select-match placeholder="(None)" ng-bind="$select.selected.name"></ui-select-match>
+ <ui-select-choices repeat="aCategory in edit.categoryList">
+ <div ng-value="aCategory" ng-bind="aCategory.name"></div>
+ </ui-select-choices>
+
+ </ui-select>
+
+ <div class="help-block" ng-show="edit.form.categoryList.$dirty && edit.form.categoryList.$invalid">
+ <small class="error" ng-show="edit.form.categoryList.$error.required" data-translate="moon.policy.assignments.edit.check.category.required">Category is required</small>
+ </div>
+
+ </div>
+
+ </div>
+
+ <!-- Select Data -->
+ <div class="form-group" ng-if="edit.selectedCategory" ng-class="{'has-error': edit.form.dataList.$invalid && edit.form.dataList.$dirty}" >
+
+ <label for="dataList" class="col-sm-3 control-label" data-translate="moon.policy.assignments.edit.data">Data List</label>
+
+ <div class="col-sm-6" ng-if="edit.loadingData" >
+ <moon-loader></moon-loader>
+ </div>
+
+ <div class="col-sm-4" ng-if="!edit.loadingData" >
+
+ <ui-select ng-model="edit.selectedData" name="dataList" id="dataList">
+
+ <ui-select-match placeholder="(None)" ng-bind="edit.getName($select.selected)"></ui-select-match>
+ <ui-select-choices repeat="aData in edit.dataToBeSelected">
+ <div ng-value="aData" ng-bind="edit.getName(aData)"></div>
+ </ui-select-choices>
+
+ </ui-select>
+
+ <div class="help-block" ng-show="edit.form.dataList.$dirty && edit.form.dataList.$invalid || !edit.assignementsAttributeValid">
+ <small class="error" ng-show="edit.form.dataList.$error.required || !edit.assignementsAttributeValid" data-translate="moon.policy.assignments.edit.check.data.required">Data is required</small>
+ </div>
+
+ </div>
+
+ <div class="col-sm-2 text-center">
+ <a href="" ng-if="edit.selectedData"
+ ng-click="edit.addSelectedData()"><span style="font-size:1.5em; line-height: 1.5em;" class="glyphicon glyphicon-plus-sign"></span></a>
+ </div>
+
+ </div>
+
+ <!-- Selected DataList -->
+ <div class="form-group" ng-if="!edit.loadingData">
+
+ <label class="col-sm-3 control-label" data-translate="moon.policy.assignments.edit.selectedData">Selected Data)</label>
+
+ <div class="col-sm-6">
+
+ <ul>
+
+ <li ng-repeat="(key, value) in edit.selectedDataList">
+
+ <span ng-bind="edit.getName(value)" ></span> <a href="" ng-click="edit.removeSelectedData(value)"><span style="font-size:1.5em; line-height: 1.5em" class="glyphicon glyphicon-remove"></span></a>
+
+ </li>
+
+ </ul>
+
+ </div>
+
+ </div>
+
+ <div class="form-group">
+
+ <div class="pull-right">
+
+ <a href="" ng-disabled="edit.loading" ng-click="edit.create()" class="btn btn-warning">
+ <span class="glyphicon glyphicon-save"></span>
+ <span data-translate="moon.policy.assignments.edit.action.create">Create</span>
+ </a>
+
+ <moon-loader ng-if="edit.loading"></moon-loader>
+
+ </div>
+
+ </div>
+
+
+ </form>
+
+ </div>
+
+</div> \ No newline at end of file
diff --git a/moonv4/moon_gui/static/app/policy/edit/parameter/assignments/assignments-list.tpl.html b/moonv4/moon_gui/static/app/policy/edit/parameter/assignments/assignments-list.tpl.html
index 34bbc7a8..34bbc7a8 100644..100755
--- a/moonv4/moon_gui/static/app/policy/edit/parameter/assignments/assignments-list.tpl.html
+++ b/moonv4/moon_gui/static/app/policy/edit/parameter/assignments/assignments-list.tpl.html
diff --git a/moonv4/moon_gui/static/app/policy/edit/parameter/assignments/assignments.edit.dir.js b/moonv4/moon_gui/static/app/policy/edit/parameter/assignments/assignments.edit.dir.js
new file mode 100755
index 00000000..5297eccb
--- /dev/null
+++ b/moonv4/moon_gui/static/app/policy/edit/parameter/assignments/assignments.edit.dir.js
@@ -0,0 +1,439 @@
+(function () {
+
+ 'use strict';
+
+ angular
+ .module('moon')
+ .directive('moonAssignmentsEdit', moonAssignmentsEdit);
+
+ moonAssignmentsEdit.$inject = [];
+
+ function moonAssignmentsEdit() {
+
+ return {
+ templateUrl: 'html/policy/edit/parameter/assignments/assignments-edit.tpl.html',
+ bindToController: true,
+ controller: moonAssignmentsEditController,
+ controllerAs: 'edit',
+ scope: {
+ //Type can be 'ACTION', 'OBJECT', 'SUBJECT'
+ assignmentsType: '=',
+ policy: '='
+ },
+ restrict: 'E',
+ replace: true
+ };
+ }
+
+ angular
+ .module('moon')
+ .controller('moonAssignmentsEditController', moonAssignmentsEditController);
+
+ moonAssignmentsEditController.$inject = ['$scope', 'assignmentsService', 'alertService', '$translate', 'formService',
+ 'policyService', 'utilService', 'perimeterService', 'ASSIGNMENTS_CST',
+ 'metaDataService', 'dataService'];
+
+ function moonAssignmentsEditController($scope, assignmentsService, alertService, $translate, formService,
+ policyService, utilService, perimeterService, ASSIGNMENTS_CST,
+ metaDataService, dataService ) {
+
+ var edit = this;
+
+ edit.assignmentsType = $scope.edit.assignmentsType;
+ edit.policy = $scope.edit.policy;
+
+ edit.laoading = false;
+
+ edit.form = {};
+
+ edit.policyList = [];
+ edit.loadingPolicies = true;
+
+ edit.categoryList = [];
+ edit.loadingCategories = true;
+
+ edit.perimeterList = [];
+ edit.loadingPerimeters = true;
+
+ edit.dataList = [];
+ edit.dataToBeSelected = [];
+ edit.selectedDataList = [];
+ edit.loadingData = true;
+
+ edit.assignementsAttributeValid = true;
+
+ edit.addSelectedData = addSelectedData;
+ edit.removeSelectedData = removeSelectedData;
+ edit.getName = getName;
+ edit.create = createAssignments;
+
+ activate();
+
+ /*
+ *
+ */
+
+ function activate() {
+
+ edit.assignments = {id: null, category_id: null, data_id: null, policy_id: null};
+
+ loadAllPolicies();
+ loadAllCategories();
+
+ }
+
+ function createAssignments() {
+
+ edit.assignementsAttributeValid = true;
+
+ manageSelectedDataListy();
+
+ if(formService.isInvalid(edit.form)) {
+
+ formService.checkFieldsValidity(edit.form);
+
+ }else if(edit.assignementsAttributeValid){
+
+ startLoading();
+
+ var throwEvent = false;
+ edit.assignments.id = edit.selectedPerimeter.id;
+ edit.assignments.category_id = edit.selectedCategory.id;
+ edit.assignments.policy_id = edit.selectedPolicy.id;
+
+ var selectedDataListTemp = angular.copy(edit.selectedDataList);
+
+ _.each(selectedDataListTemp, function(elem){
+
+ edit.assignments.data_id = elem.id;
+
+ var assignmentsToSend = angular.copy(edit.assignments);
+
+ switch(edit.assignmentsType){
+
+ case ASSIGNMENTS_CST.TYPE.SUBJECT:
+
+ assignmentsService.subject.add(assignmentsToSend, edit.policy.id, createSuccess, createError);
+ break;
+
+ case ASSIGNMENTS_CST.TYPE.OBJECT:
+
+ assignmentsService.object.add(assignmentsToSend, edit.policy.id, createSuccess, createError);
+ break;
+
+ case ASSIGNMENTS_CST.TYPE.ACTION:
+
+ assignmentsService.action.add(assignmentsToSend, edit.policy.id, createSuccess, createError);
+ break;
+
+ default :
+
+ break;
+
+ }
+
+ });
+
+ throwEvent = true;
+
+ }
+
+ function createSuccess(data) {
+
+ var created = {};
+
+ switch(edit.assignmentsType){
+
+ case ASSIGNMENTS_CST.TYPE.SUBJECT:
+
+ created = utilService.transformOne(data, 'subject_assignments');
+ break;
+
+ case ASSIGNMENTS_CST.TYPE.OBJECT:
+
+ created = utilService.transformOne(data, 'object_assignments');
+ break;
+
+ case ASSIGNMENTS_CST.TYPE.ACTION:
+
+ created = utilService.transformOne(data, 'action_assignments');
+ break;
+
+ default:
+
+ break;
+
+ }
+
+ $translate('moon.policy.assignments.edit.create.success').then(function (translatedValue) {
+ alertService.alertSuccess(translatedValue);
+ });
+
+ if(throwEvent && created.policy_id === edit.policy.id){
+
+ $scope.$emit('event:createAssignmentsFromAssignmentsEditSuccess', edit.assignmentsType);
+
+ activate();
+
+ stopLoading();
+
+ }else if(throwEvent){
+
+ activate();
+
+ stopLoading();
+
+ }
+
+ }
+
+ function createError(reason) {
+
+ $translate('moon.policy.rules.edit.action.add.create.error').then(function (translatedValue) {
+ alertService.alertError(translatedValue);
+ });
+
+ stopLoading();
+
+ }
+
+ }
+
+ $scope.$watch('edit.selectedPolicy', function(newValue){
+
+ if(!_.isUndefined(newValue)){
+
+ loadRelatedPerimeters();
+
+ }
+
+ });
+
+
+ $scope.$watch('edit.selectedCategory', function(newValue){
+
+ clearSelectedCategories();
+
+ if(!_.isUndefined(newValue)){
+
+ loadRelatedData(newValue.id);
+
+ }
+
+ });
+
+ function loadAllPolicies() {
+
+ edit.policyList = [];
+ edit.loadingPolicies = true;
+
+ policyService.findAllWithCallback( function(data) {
+
+ _.each(data, function(element){
+
+ if(element.id === edit.policy.id){
+ edit.selectedPolicy = element;
+ }
+
+ });
+
+ edit.policyList = data;
+ edit.loadingPolicies = false;
+
+ });
+ }
+
+ function loadRelatedPerimeters(){
+
+ edit.perimeterList = [];
+ edit.loadingPerimeters = true;
+
+ switch(edit.assignmentsType){
+
+ case ASSIGNMENTS_CST.TYPE.SUBJECT:
+
+ perimeterService.subject.findAllFromPolicyWithCallback(edit.selectedPolicy.id, callBackList);
+ break;
+
+ case ASSIGNMENTS_CST.TYPE.OBJECT:
+
+ perimeterService.object.findAllFromPolicyWithCallback(edit.selectedPolicy.id,callBackList);
+ break;
+
+ case ASSIGNMENTS_CST.TYPE.ACTION:
+
+ perimeterService.action.findAllFromPolicyWithCallback(edit.selectedPolicy.id, callBackList);
+ break;
+
+ default :
+
+ edit.perimeterList = [];
+ edit.loadingPerimeters = false;
+ break;
+
+ }
+
+ function callBackList(list){
+
+ edit.perimeterList = list;
+
+ edit.loadingPerimeters = false;
+
+ }
+ }
+
+ function loadAllCategories(){
+
+ edit.categoryList = [];
+ edit.loadingCategories = true;
+
+ switch(edit.assignmentsType){
+
+ case ASSIGNMENTS_CST.TYPE.SUBJECT:
+
+ metaDataService.subject.findAllWithCallback(callBackList);
+ break;
+
+ case ASSIGNMENTS_CST.TYPE.OBJECT:
+
+ metaDataService.object.findAllWithCallback(callBackList);
+ break;
+
+ case ASSIGNMENTS_CST.TYPE.ACTION:
+
+ metaDataService.action.findAllWithCallback(callBackList);
+ break;
+
+ default :
+
+ edit.categoryList = [];
+ edit.loadingCategories = false;
+ break;
+
+ }
+
+ function callBackList(list){
+
+ edit.categoryList = list;
+ edit.loadingCategories = false;
+
+ }
+ }
+
+ function loadRelatedData(categoryId){
+
+ edit.dataList = [];
+ edit.dataToBeSelected = [];
+ edit.selectedDataList = [];
+ edit.loadingData = true;
+
+ switch(edit.assignmentsType){
+
+ case ASSIGNMENTS_CST.TYPE.SUBJECT:
+
+ dataService.subject.findAllFromCategoriesWithCallback(edit.selectedPolicy.id, categoryId, callBackList);
+ break;
+
+ case ASSIGNMENTS_CST.TYPE.OBJECT:
+
+ dataService.object.findAllFromCategoriesWithCallback(edit.selectedPolicy.id, categoryId, callBackList);
+ break;
+
+ case ASSIGNMENTS_CST.TYPE.ACTION:
+
+ dataService.action.findAllFromCategoriesWithCallback(edit.selectedPolicy.id, categoryId, callBackList);
+ break;
+
+ default :
+
+ edit.loadingData = false;
+ break;
+
+ }
+
+ function callBackList(list){
+
+ edit.dataList = list;
+ edit.dataToBeSelected = angular.copy(edit.dataList);
+ edit.selectedDataList = [];
+ edit.loadingData = false;
+
+ }
+
+ }
+
+ function addSelectedData(){
+
+ edit.dataToBeSelected = _.without(edit.dataToBeSelected, edit.selectedData);
+ edit.selectedDataList.push(edit.selectedData);
+ clearSelectedCategories();
+
+ }
+
+ function removeSelectedData(data){
+
+ edit.dataToBeSelected.push(data);
+ edit.selectedDataList = _.without(edit.selectedDataList, data);
+
+ }
+
+ function clearSelectedCategories(){
+
+ edit.selectedData = undefined;
+
+ }
+
+ function getName(assignment){
+
+ if(_.isUndefined(assignment)) return '(None)';
+
+ switch(edit.assignmentsType){
+
+ case ASSIGNMENTS_CST.TYPE.SUBJECT:
+
+ return assignment.name;
+
+ case ASSIGNMENTS_CST.TYPE.OBJECT:
+
+ return assignment.value.name;
+
+
+ case ASSIGNMENTS_CST.TYPE.ACTION:
+
+ return assignment.value.name;
+
+ default :
+
+ return assignment.name;
+
+ }
+
+ }
+
+ function manageSelectedDataListy(){
+
+ if (edit.selectedDataList.length >= 1 ){
+
+ edit.assignementsAttributeValid = true;
+
+ }else{
+
+ edit.assignementsAttributeValid = false;
+
+ }
+ }
+
+ function startLoading(){
+
+ edit.loading = true;
+
+ }
+
+ function stopLoading(){
+
+ edit.loading = false;
+
+ }
+ }
+
+})(); \ No newline at end of file
diff --git a/moonv4/moon_gui/static/app/policy/edit/parameter/assignments/assignments.list.dir.js b/moonv4/moon_gui/static/app/policy/edit/parameter/assignments/assignments.list.dir.js
index 22931e4d..22931e4d 100644..100755
--- a/moonv4/moon_gui/static/app/policy/edit/parameter/assignments/assignments.list.dir.js
+++ b/moonv4/moon_gui/static/app/policy/edit/parameter/assignments/assignments.list.dir.js
diff --git a/moonv4/moon_gui/static/app/policy/edit/parameter/data/data-edit.tpl.html b/moonv4/moon_gui/static/app/policy/edit/parameter/data/data-edit.tpl.html
new file mode 100755
index 00000000..3f11a641
--- /dev/null
+++ b/moonv4/moon_gui/static/app/policy/edit/parameter/data/data-edit.tpl.html
@@ -0,0 +1,110 @@
+<div>
+
+ <div class="col-md-12 col-sm-12 col-xs-12">
+
+ <form ng-if="!edit.fromList" class="form-horizontal" role="form" name="edit.form">
+
+ <div class="form-group" ng-class="{'has-error': edit.form.name.$invalid && edit.form.name.$dirty}">
+
+ <label for="name" class="col-sm-3 control-label"
+ data-translate="moon.policy.data.edit.name">Name</label>
+
+ <div class="col-sm-6">
+
+ <input name="name" id="name" class="form-control" type="text" data-ng-model="edit.data.name"
+ required/>
+
+ <div class="help-block" ng-show="edit.form.name.$dirty && edit.form.name.$invalid">
+ <small class="error" ng-show="edit.form.name.$error.required"
+ data-translate="moon.policy.data.edit.check.name.required">Name is required
+ </small>
+ </div>
+
+ </div>
+
+ </div>
+
+ <div class="form-group">
+
+ <label for="description" class="col-sm-3 control-label"
+ data-translate="moon.policy.data.edit.description">Description</label>
+ <div class="col-sm-6">
+ <textarea id="description" name="description" class="form-control"
+ data-ng-model="edit.data.description"></textarea>
+ </div>
+
+ </div>
+
+ <div class="form-group"
+ ng-class="{'has-error': edit.form.policyList.$invalid && edit.form.policyList.$dirty}">
+
+ <label for="policyList" class="col-sm-3 control-label" data-translate="moon.policy.data.edit.policies">Policy
+ List </label>
+
+ <div class="col-sm-6">
+
+ <ui-select ng-model="edit.selectedPolicy" name="policyList" id="policyList" required>
+
+ <ui-select-match placeholder="(None)" ng-bind="$select.selected.name"></ui-select-match>
+ <ui-select-choices repeat="aPolicy in edit.policyList">
+ <div ng-value="aPolicy" ng-bind="aPolicy.name"></div>
+ </ui-select-choices>
+
+ </ui-select>
+
+ <div class="help-block" ng-show="edit.form.policyList.$dirty && edit.form.policyList.$invalid">
+ <small class="error" ng-show="edit.form.policyList.$error.required"
+ data-translate="moon.policy.data.edit.check.policy.required">Policy is required
+ </small>
+ </div>
+
+ </div>
+
+ </div>
+
+ <div class="form-group"
+ ng-class="{'has-error': edit.form.categoryList.$invalid && edit.form.categoryList.$dirty}">
+
+ <label for="categoryList" class="col-sm-3 control-label"
+ data-translate="moon.policy.data.edit.categories">Category List </label>
+
+ <div class="col-sm-6">
+
+ <ui-select ng-model="edit.selectedCategory" name="categoryList" id="categoryList" required>
+
+ <ui-select-match placeholder="(None)" ng-bind="$select.selected.name"></ui-select-match>
+ <ui-select-choices repeat="aCategory in edit.categoriesToBeSelected">
+ <div ng-value="aCategory" ng-bind="aCategory.name"></div>
+ </ui-select-choices>
+
+ </ui-select>
+
+ <div class="help-block" ng-show="edit.form.categoryList.$dirty && edit.form.categoryList.$invalid">
+ <small class="error" ng-show="edit.form.categoryList.$error.required"
+ data-translate="moon.policy.data.edit.check.category.required">Category is required
+ </small>
+ </div>
+
+ </div>
+ </div>
+
+ <div class="form-group">
+
+ <div class="pull-right">
+
+ <a href="" ng-disabled="edit.loading" ng-click="edit.create()" class="btn btn-warning">
+ <span class="glyphicon glyphicon-save"></span>
+ <span data-translate="moon.policy.data.edit.action.create">Create</span>
+ </a>
+
+ <moon-loader ng-if="edit.loading"></moon-loader>
+
+ </div>
+
+ </div>
+
+ </form>
+
+ </div>
+
+</div> \ No newline at end of file
diff --git a/moonv4/moon_gui/static/app/policy/edit/parameter/data/data-list.tpl.html b/moonv4/moon_gui/static/app/policy/edit/parameter/data/data-list.tpl.html
index b69a4eed..b69a4eed 100644..100755
--- a/moonv4/moon_gui/static/app/policy/edit/parameter/data/data-list.tpl.html
+++ b/moonv4/moon_gui/static/app/policy/edit/parameter/data/data-list.tpl.html
diff --git a/moonv4/moon_gui/static/app/policy/edit/parameter/data/data.edit.dir.js b/moonv4/moon_gui/static/app/policy/edit/parameter/data/data.edit.dir.js
index 57ad0c9b..57ad0c9b 100644..100755
--- a/moonv4/moon_gui/static/app/policy/edit/parameter/data/data.edit.dir.js
+++ b/moonv4/moon_gui/static/app/policy/edit/parameter/data/data.edit.dir.js
diff --git a/moonv4/moon_gui/static/app/policy/edit/parameter/data/data.list.dir.js b/moonv4/moon_gui/static/app/policy/edit/parameter/data/data.list.dir.js
index 23a7e535..23a7e535 100644..100755
--- a/moonv4/moon_gui/static/app/policy/edit/parameter/data/data.list.dir.js
+++ b/moonv4/moon_gui/static/app/policy/edit/parameter/data/data.list.dir.js
diff --git a/moonv4/moon_gui/static/app/policy/edit/parameter/perimeter/perimeter-edit.tpl.html b/moonv4/moon_gui/static/app/policy/edit/parameter/perimeter/perimeter-edit.tpl.html
new file mode 100755
index 00000000..fa2f93c0
--- /dev/null
+++ b/moonv4/moon_gui/static/app/policy/edit/parameter/perimeter/perimeter-edit.tpl.html
@@ -0,0 +1,166 @@
+<div>
+
+ <div class="col-md-4 col-sm-4 col-xs-4">
+ <a class="btn btn-primary" type="button" style="white-space: normal;" ng-click="edit.fromList = !edit.fromList">
+ <span ng-if="!edit.fromList" data-translate="moon.policy.perimeter.edit.action.list">Add from the list</span>
+ <span ng-if="edit.fromList" data-translate="moon.policy.perimeter.edit.action.new">Add a new Perimeter</span>
+ </a>
+ </div>
+
+ <div class="col-md-8 col-sm-8 col-xs-8">
+
+ <form name="selectMetaData" ng-if="edit.fromList" class="form-horizontal" role="form" >
+
+ <div class="form-group" >
+
+ <ui-select ng-model="edit.selectedPerimeter" name="object">
+
+ <ui-select-match placeholder="(None)" ng-bind="$select.selected.name"></ui-select-match>
+ <ui-select-choices repeat="aPerimeter in edit.list">
+ <div ng-value="aPerimeter" ng-bind="aPerimeter.name"></div>
+ </ui-select-choices>
+
+ </ui-select>
+
+ </div>
+
+ <div class="form-group">
+
+ <div class="pull-left col-md-4 col-sm-4 col-xs-4">
+
+ <a href="" ng-disabled="edit.loading || !edit.selectedPerimeter" ng-click="edit.deletePerimeter()" class="btn btn-warning">
+ <span class="glyphicon glyphicon-trash"></span>
+ <span data-translate="moon.policy.perimeter.edit.action.delete">Delete</span>
+ </a>
+
+ </div>
+
+ <div class="pull-right col-md-7 col-md-offset-1 col-sm-7 col-sm-offset-1 col-xs-7 col-xs-offset-1 ">
+
+ <a href="" ng-disabled="edit.loading || !edit.selectedPerimeter" ng-click="edit.addToPolicy()" class="btn btn-warning" style="white-space: normal;">
+ <span class="glyphicon glyphicon-link"></span>
+ <span data-translate="moon.policy.perimeter.edit.action.add">Add the selected Perimeter</span>
+ </a>
+
+ </div>
+
+ </div>
+
+ <moon-loader ng-if="edit.loading"></moon-loader>
+
+ </form>
+
+ <form ng-if="!edit.fromList" class="form-horizontal" role="form" name="edit.form">
+
+ <div class="form-group" ng-class="{'has-error': edit.form.name.$invalid && edit.form.name.$dirty}">
+
+ <label for="name" class="col-sm-3 control-label" data-translate="moon.policy.perimeter.edit.name">Name</label>
+
+ <div class="col-sm-6">
+
+ <input name="name" id="name" class="form-control" type="text" data-ng-model="edit.perimeter.name" required />
+
+ <div class="help-block" ng-show="edit.form.name.$dirty && edit.form.name.$invalid">
+ <small class="error" ng-show="edit.form.name.$error.required" data-translate="moon.policy.perimeter.edit.check.name.required">Name is required</small>
+ </div>
+
+ </div>
+
+ </div>
+
+ <div class="form-group">
+
+ <label for="description" class="col-sm-3 control-label" data-translate="moon.policy.perimeter.edit.description">Description</label>
+ <div class="col-sm-6">
+ <textarea id="description" name="description" class="form-control" data-ng-model="edit.perimeter.description"></textarea>
+ </div>
+
+ </div>
+
+ <!--
+ <div class="form-group">
+
+ <label for="partnerId" class="col-sm-3 control-label" data-translate="moon.policy.perimeter.edit.partnerId">Partner Id</label>
+
+ <div class="col-sm-6">
+ <input name="partnerId" id="partnerId" class="form-control" type="text" data-ng-model="edit.perimeter.partnerId" />
+ </div>
+
+ </div>
+ -->
+
+
+ <div class="form-group" ng-if="edit.perimeterType === edit.subjectType" ng-class="{'has-error': edit.form.email.$invalid && edit.form.email.$dirty}">
+
+ <label for="email" class="col-sm-3 control-label" data-translate="moon.policy.perimeter.edit.email">Email</label>
+
+ <div class="col-sm-6">
+ <input name="email" id="email" class="form-control" type="email" data-ng-model="edit.perimeter.email" />
+ </div>
+
+ </div>
+
+
+ <div class="form-group" >
+
+ <label for="policyList" class="col-sm-3 control-label" data-translate="moon.policy.perimeter.edit.policies">Policy List </label>
+
+ <div class="col-sm-5">
+
+ <ui-select ng-model="edit.selectedPolicy" id="policyList">
+
+ <ui-select-match placeholder="(None)" ng-bind="$select.selected.name"></ui-select-match>
+ <ui-select-choices repeat="aPolicy in edit.policiesToBeSelected">
+ <div ng-value="aPolicy" ng-bind="aPolicy.name"></div>
+ </ui-select-choices>
+
+ </ui-select>
+
+ </div>
+
+ <div class="col-sm-1 text-center">
+ <a href="" ng-click="edit.addPolicyToPerimeter()"><span style="font-size:1.5em; line-height: 1.5em;" class="glyphicon glyphicon-plus-sign"></span></a>
+ </div>
+
+ </div>
+
+ <div class="form-group">
+
+ <label class="col-sm-3 control-label" data-translate="moon.policy.perimeter.edit.selectedPolicies">Selected Policies</label>
+
+ <div class="col-sm-6">
+
+ <ul>
+
+ <li ng-repeat="(key, value) in edit.selectedPolicyList">
+
+ <span ng-bind="value.name" ></span> <a href="" ng-click="edit.removeSelectedPolicy(value)"><span style="font-size:1.5em; line-height: 1.5em" class="glyphicon glyphicon-remove"></span></a>
+
+ </li>
+
+ </ul>
+
+ </div>
+
+ </div>
+
+ <div class="form-group">
+
+ <div class="pull-right">
+
+ <a href="" ng-disabled="edit.loading" ng-click="edit.create()" class="btn btn-warning">
+ <span class="glyphicon glyphicon-save"></span>
+ <span data-translate="moon.policy.perimeter.edit.action.create">Create</span>
+ </a>
+
+ <moon-loader ng-if="edit.loading"></moon-loader>
+
+ </div>
+
+ </div>
+
+ </form>
+
+ </div>
+
+</div> \ No newline at end of file
diff --git a/moonv4/moon_gui/static/app/policy/edit/parameter/perimeter/perimeter-list.tpl.html b/moonv4/moon_gui/static/app/policy/edit/parameter/perimeter/perimeter-list.tpl.html
index a94d663e..a94d663e 100644..100755
--- a/moonv4/moon_gui/static/app/policy/edit/parameter/perimeter/perimeter-list.tpl.html
+++ b/moonv4/moon_gui/static/app/policy/edit/parameter/perimeter/perimeter-list.tpl.html
diff --git a/moonv4/moon_gui/static/app/policy/edit/parameter/perimeter/perimeter.edit.dir.js b/moonv4/moon_gui/static/app/policy/edit/parameter/perimeter/perimeter.edit.dir.js
new file mode 100755
index 00000000..a96741fe
--- /dev/null
+++ b/moonv4/moon_gui/static/app/policy/edit/parameter/perimeter/perimeter.edit.dir.js
@@ -0,0 +1,437 @@
+(function () {
+
+ 'use strict';
+
+ angular
+ .module('moon')
+ .directive('moonPerimeterEdit', moonPerimeterEdit);
+
+ moonPerimeterEdit.$inject = [];
+
+ function moonPerimeterEdit() {
+
+ return {
+ templateUrl: 'html/policy/edit/parameter/perimeter/perimeter-edit.tpl.html',
+ bindToController: true,
+ controller: moonPerimeterEditController,
+ controllerAs: 'edit',
+ scope: {
+ //Type can be 'ACTION', 'OBJECT', 'SUBJECT'
+ perimeterType: '=',
+ policy: '='
+ },
+ restrict: 'E',
+ replace: true
+ };
+ }
+
+
+ angular
+ .module('moon')
+ .controller('moonPerimeterEditController', moonPerimeterEditController);
+
+ moonPerimeterEditController.$inject = ['$scope', '$rootScope',
+ 'perimeterService', 'PERIMETER_CST', 'alertService',
+ '$translate', 'formService', 'policyService', 'utilService'];
+
+ function moonPerimeterEditController($scope, $rootScope,
+ perimeterService, PERIMETER_CST, alertService,
+ $translate, formService, policyService, utilService) {
+
+ var edit = this;
+
+ edit.perimeterType = $scope.edit.perimeterType;
+ // This variable is used in the view in order to display or not display email field
+ edit.subjectType = PERIMETER_CST.TYPE.SUBJECT;
+ edit.policy = $scope.edit.policy;
+
+ edit.fromList = true;
+
+ edit.loading = false;
+
+ edit.form = {};
+
+ edit.perimeter = {name: null, description: null, partner_id: null, policy_list: [], email: null};
+
+ edit.list = [];
+ edit.policyList = [];
+ edit.policiesToBeSelected = [];
+ edit.selectedPolicyList = []; // List of Policies to be added to a new perimeter
+
+ edit.create = createPerimeter;
+ edit.addToPolicy = addToPolicy;
+ edit.addPolicyToPerimeter = addPolicyToPerimeter;
+ edit.clearSelectedPolicies = clearSelectedPolicies;
+ edit.removeSelectedPolicy = removeSelectedPolicy;
+ edit.deletePerimeter = deletePerimeter;
+
+ activate();
+
+ /*
+ *
+ */
+
+ function activate() {
+
+ loadAllPolicies();
+
+ switch (edit.perimeterType) {
+
+ case PERIMETER_CST.TYPE.SUBJECT:
+
+ perimeterService.subject.findAllWithCallback(callBackList);
+ break;
+
+ case PERIMETER_CST.TYPE.OBJECT:
+
+ perimeterService.object.findAllWithCallback(callBackList);
+ break;
+
+ case PERIMETER_CST.TYPE.ACTION:
+
+ perimeterService.action.findAllWithCallback(callBackList);
+ break;
+
+ default :
+
+ edit.list = [];
+ break;
+
+ }
+
+ function callBackList(list) {
+
+ // For each Perimeter, there is a check about the mapping between the perimeter and the policy
+ _.each(list, function (element) {
+
+ if (_.indexOf(element.policy_list, edit.policy.id) === -1) {
+
+ edit.list.push(element);
+
+ }
+
+ });
+
+ }
+
+ }
+
+ var rootListeners = {
+
+ 'event:unMapPerimeterFromPerimeterList': $rootScope.$on('event:unMapPerimeterFromPerimeterList', manageUnMappedPerimeter)
+
+ };
+
+ _.each(rootListeners, function(unbind){
+ $scope.$on('$destroy', rootListeners[unbind]);
+ });
+
+
+ function loadAllPolicies() {
+
+ edit.policyList = [];
+
+ policyService.findAllWithCallback( function(data) {
+
+ edit.policyList = data;
+ edit.policiesToBeSelected = angular.copy(edit.policyList);
+
+ });
+ }
+
+ function addPolicyToPerimeter() {
+
+ if (!edit.selectedPolicy || _.contains(edit.perimeter.policy_list, edit.selectedPolicy.id)) {
+ return;
+ }
+
+ edit.perimeter.policy_list.push(edit.selectedPolicy.id);
+ edit.selectedPolicyList.push(edit.selectedPolicy);
+ edit.policiesToBeSelected = _.without(edit.policiesToBeSelected, edit.selectedPolicy);
+
+ }
+
+ function clearSelectedPolicies() {
+
+ edit.perimeter.policy_list = [];
+ edit.selectedPolicyList = [];
+ edit.policiesToBeSelected = angular.copy(edit.policyList);
+
+ }
+
+ function removeSelectedPolicy(policy) {
+
+ edit.policiesToBeSelected.push(policy);
+ edit.perimeter.policy_list = _.without(edit.perimeter.policy_list, policy.id);
+ edit.selectedPolicyList = _.without(edit.selectedPolicyList, policy);
+
+ }
+
+ /**
+ * Add
+ */
+
+ function addToPolicy() {
+
+ if (!edit.selectedPerimeter) {
+
+ return;
+
+ }
+
+ startLoading();
+
+ var perimeterToSend = edit.selectedPerimeter;
+
+ perimeterToSend.policy_list.push(edit.policy.id);
+
+ switch (edit.perimeterType) {
+
+ case PERIMETER_CST.TYPE.SUBJECT:
+
+ perimeterService.subject.update(perimeterToSend, updatePerimeterSuccess, updatePerimeterError);
+ break;
+
+ case PERIMETER_CST.TYPE.OBJECT:
+
+ perimeterService.object.update(perimeterToSend, updatePerimeterSuccess, updatePerimeterError);
+ break;
+
+ case PERIMETER_CST.TYPE.ACTION:
+
+ perimeterService.action.update(perimeterToSend, updatePerimeterSuccess, updatePerimeterError);
+ break;
+ }
+
+
+ function updatePerimeterSuccess(data) {
+
+ $translate('moon.perimeter.update.success', {policyName: perimeterToSend.name}).then(function (translatedValue) {
+
+ alertService.alertSuccess(translatedValue);
+
+ });
+
+ stopLoading();
+
+ }
+
+ function updatePerimeterError(reason) {
+
+ $translate('moon.policy.update.error', {
+ policyName: perimeterToSend.name,
+ reason: reason.message
+ }).then(function (translatedValue) {
+
+ alertService.alertError(translatedValue);
+
+ });
+
+ stopLoading();
+
+ }
+
+ }
+
+ /**
+ * Create
+ */
+
+ function createPerimeter() {
+
+ if (formService.isInvalid(edit.form)) {
+
+ formService.checkFieldsValidity(edit.form);
+
+ } else {
+
+ startLoading();
+
+ var perimeterToSend = angular.copy(edit.perimeter);
+
+ switch (edit.perimeterType) {
+
+ case PERIMETER_CST.TYPE.SUBJECT:
+
+ perimeterService.subject.add(perimeterToSend, createSuccess, createError);
+ break;
+
+ case PERIMETER_CST.TYPE.OBJECT:
+
+ perimeterService.object.add(perimeterToSend, createSuccess, createError);
+ break;
+
+ case PERIMETER_CST.TYPE.ACTION:
+
+ perimeterService.action.add(perimeterToSend, createSuccess, createError);
+ break;
+ }
+
+ }
+
+ function createSuccess(data) {
+
+ var created = {};
+
+ switch (edit.perimeterType) {
+
+ case PERIMETER_CST.TYPE.SUBJECT:
+
+ created = utilService.transformOne(data, 'subjects');
+ break;
+
+ case PERIMETER_CST.TYPE.OBJECT:
+
+ created = utilService.transformOne(data, 'objects');
+ break;
+
+ case PERIMETER_CST.TYPE.ACTION:
+
+ created = utilService.transformOne(data, 'actions');
+ break;
+ }
+
+ $translate('moon.policy.perimeter.edit.create.success', {name: created.name}).then(function (translatedValue) {
+ alertService.alertSuccess(translatedValue);
+ });
+
+ stopLoading();
+
+ /**
+ * If during the creating the created assignments has be mapped with the current policy, then it is not required to push the new Assignments in the list
+ */
+ if (_.indexOf(created.policy_list, edit.policy.id) === -1) {
+
+ edit.list.push(created);
+
+ }else{
+
+ $scope.$emit('event:createAssignmentsFromAssignmentsEditSuccess', created, edit.perimeterType);
+
+ }
+
+ displayList();
+
+ clearSelectedPolicies();
+
+ }
+
+ function createError(reason) {
+
+ $translate('moon.policy.perimeter.edit.create.error', {name: perimeterToSend.name}).then(function (translatedValue) {
+ alertService.alertError(translatedValue);
+ });
+
+ stopLoading();
+
+ }
+
+ }
+
+ /**
+ * Delete
+ */
+ function deletePerimeter() {
+
+ if (!edit.selectedPerimeter) {
+
+ return;
+
+ }
+
+ startLoading();
+
+ var perimeterToDelete = angular.copy(edit.selectedPerimeter);
+
+ switch (edit.perimeterType) {
+ case PERIMETER_CST.TYPE.SUBJECT:
+
+ perimeterService.subject.delete(perimeterToDelete, deleteSuccess, deleteError);
+ break;
+
+ case PERIMETER_CST.TYPE.OBJECT:
+
+ perimeterService.object.delete(perimeterToDelete, deleteSuccess, deleteError);
+ break;
+
+ case PERIMETER_CST.TYPE.ACTION:
+
+ perimeterService.action.delete(perimeterToDelete, deleteSuccess, deleteError);
+ break;
+ }
+
+
+ function deleteSuccess(data) {
+
+ $translate('moon.policy.perimeter.edit.delete.success', {name: perimeterToDelete.name})
+ .then(function (translatedValue) {
+ alertService.alertSuccess(translatedValue);
+ });
+
+ policyService.findOneReturningPromise(edit.policy.id).then(function (data) {
+
+ edit.policy = utilService.transformOne(data, 'policies');
+
+ cleanSelectedValue();
+ activate();
+ stopLoading();
+
+ $scope.$emit('event:deletePerimeterFromPerimeterAddSuccess', edit.policy);
+
+ });
+
+ }
+
+ function deleteError(reason) {
+
+ $translate('moon.policy.perimeter.edit.delete.error', {name: perimeterToDelete.name}).then(function (translatedValue) {
+ alertService.alertError(translatedValue);
+ });
+
+ stopLoading();
+
+ }
+ }
+
+ function cleanSelectedValue() {
+
+ delete edit.selectedPerimeter;
+
+ }
+
+ function startLoading() {
+
+ edit.loading = true;
+
+ }
+
+ function stopLoading() {
+
+ edit.loading = false;
+
+ }
+
+ function displayList() {
+
+ edit.fromList = true;
+
+ }
+
+ /**
+ * If A perimeter has been unMapped, maybe it has to be display into the available list of Perimeter
+ * @param perimeter
+ * @param type
+ */
+ function manageUnMappedPerimeter(event, perimeter, type){
+
+ if(type === edit.perimeterType && _.indexOf(perimeter.policy_list, edit.policy.id) === -1){
+
+ edit.list.push(perimeter);
+
+ }
+
+ }
+
+ }
+
+})(); \ No newline at end of file
diff --git a/moonv4/moon_gui/static/app/policy/edit/parameter/perimeter/perimeter.list.dir.js b/moonv4/moon_gui/static/app/policy/edit/parameter/perimeter/perimeter.list.dir.js
index dffa7783..dffa7783 100644..100755
--- a/moonv4/moon_gui/static/app/policy/edit/parameter/perimeter/perimeter.list.dir.js
+++ b/moonv4/moon_gui/static/app/policy/edit/parameter/perimeter/perimeter.list.dir.js
diff --git a/moonv4/moon_gui/static/app/policy/edit/parameter/rules/rules-edit.tpl.html b/moonv4/moon_gui/static/app/policy/edit/parameter/rules/rules-edit.tpl.html
new file mode 100755
index 00000000..685046a5
--- /dev/null
+++ b/moonv4/moon_gui/static/app/policy/edit/parameter/rules/rules-edit.tpl.html
@@ -0,0 +1,341 @@
+<div>
+
+ <div class="col-md-12 col-sm-12 col-xs-12">
+
+ <form ng-if="!edit.fromList" class="form-horizontal" role="form" name="edit.form">
+
+ <!-- Select Policy -->
+ <div class="form-group" ng-class="{'has-error': edit.form.policyList.$invalid && edit.form.policyList.$dirty}" >
+
+ <label for="policyList" class="col-sm-3 control-label" data-translate="moon.policy.rules.edit.action.add.policies">Policy List</label>
+
+ <div class="col-sm-6" >
+
+ <ui-select ng-model="edit.selectedPolicy" name="policyList" id="policyList" required>
+
+ <ui-select-match placeholder="(None)" ng-bind="$select.selected.name"></ui-select-match>
+ <ui-select-choices repeat="aPolicy in edit.policyList">
+ <div ng-value="aPolicy" ng-bind="aPolicy.name"></div>
+ </ui-select-choices>
+
+ </ui-select>
+
+ <div class="help-block" ng-show="edit.form.policyList.$dirty && edit.form.policyList.$invalid">
+ <small class="error" ng-show="edit.form.policyList.$error.required" data-translate="moon.policy.rules.edit.action.add.check.policy.required">Policy is required</small>
+ </div>
+
+ </div>
+
+ </div>
+
+ <div ng-if="!edit.selectedPolicy.meta_rules_values">
+ <div class="col-sm-6 col-sm-offset-3">
+ <moon-loader></moon-loader>
+ </div>
+ </div>
+
+ <div ng-if="edit.selectedPolicy.meta_rules_values">
+
+ <!-- Select Meta Rules -->
+ <div class="form-group" ng-class="{'has-error': edit.form.metaRulesList.$invalid && edit.form.metaRulesList.$dirty}" >
+
+ <label for="metaRulesList" class="col-sm-3 control-label" data-translate="moon.policy.rules.edit.action.add.metarules">MetaRules List</label>
+
+ <div class="col-sm-6" >
+
+ <ui-select ng-model="edit.selectedMetaRules" name="metaRulesList" id="metaRulesList" required>
+
+ <ui-select-match placeholder="(None)" ng-bind="$select.selected.name"></ui-select-match>
+ <ui-select-choices repeat="aMetaRules in edit.selectedPolicy.meta_rules_values">
+ <div ng-value="aMetaRules" ng-bind="aMetaRules.name"></div>
+ </ui-select-choices>
+
+ </ui-select>
+
+ <div class="help-block" ng-show="edit.form.metaRulesList.$dirty && edit.form.metaRulesList.$invalid">
+ <small class="error" ng-show="edit.form.metaRulesList.$error.required" data-translate="moon.policy.rules.edit.action.add.check.metarules.required">A MetaRules is required</small>
+ </div>
+
+ </div>
+
+ <div>
+ <a href="" ng-if="edit.selectedMetaRules" ng-click="edit.showDetailselectedMetaRules = !edit.showDetailselectedMetaRules">
+
+ <span ng-if="!edit.showDetailselectedMetaRules">
+ <span data-translate="moon.policy.rules.edit.action.add.details.show">Show</span>
+ <span class="glyphicon glyphicon-eye-open"></span>
+ </span>
+
+ <span ng-if="edit.showDetailselectedMetaRules">
+ <span data-translate="moon.policy.rules.edit.action.add.details.close">Close</span>
+ <span class="glyphicon glyphicon-eye-close"></span>
+ </span>
+
+ </a>
+ </div>
+
+ </div>
+
+ <div class="form-group" ng-if="edit.showDetailselectedMetaRules && edit.selectedMetaRules">
+ <moon-meta-data-list edit-mode="edit.editMode" meta-rule="edit.selectedMetaRules" short-display="true"></moon-meta-data-list>
+ </div>
+
+ <!-- Select Data -->
+ <div class="form-group" ng-if="edit.selectedMetaRules">
+
+ <div class="col-md-4">
+
+ <div ng-if="edit.selectedMetaRules.subject_categories.length > 0">
+
+ <div class="row">
+
+ <div ng-if="!edit.data.loadingSubjects">
+
+ <label for="subjectsList" class="col-sm-3 control-label" data-translate="moon.policy.rules.edit.action.add.categories.subject" data-translate-values="{ number: edit.selectedMetaRules.subject_categories.length }">Select Subject(s)</label>
+
+ <div class="col-sm-7" >
+
+ <ui-select ng-model="edit.selectedSubject" name="subjectsList" id="subjectsList" required>
+
+ <ui-select-match placeholder="(None)" ng-bind="$select.selected.name"></ui-select-match>
+ <ui-select-choices repeat="aSubject in edit.data.subjectsToBeSelected">
+ <div ng-value="aSubject" ng-bind="aSubject.name"></div>
+ </ui-select-choices>
+
+ </ui-select>
+
+ <div class="help-block" ng-show="edit.form.subjectsList.$dirty && edit.form.subjectsList.$invalid || !edit.numberOfSelectedSubjectValid">
+ <small class="error" ng-show="edit.form.subjectsList.$error.required || !edit.numberOfSelectedSubjectValid" data-translate="moon.policy.rules.edit.action.add.check.subject.required" data-translate-values="{ number: edit.selectedMetaRules.subject_categories.length }">Some subject are required</small>
+ </div>
+
+ </div>
+
+ <div class="col-sm-2 text-center">
+ <a href="" ng-if="edit.selectedSubject && !edit.isNumberSelectedDataAtMaximum(edit.data.subjectCST)"
+ ng-click="edit.addDataToRules(edit.data.subjectCST)"><span style="font-size:1.5em; line-height: 1.5em;" class="glyphicon glyphicon-plus-sign"></span></a>
+ </div>
+
+ </div>
+
+ <div ng-if="edit.data.loadingSubjects">
+
+ <moon-loader></moon-loader>
+
+ </div>
+
+ </div>
+
+ <div class="row" ng-if="!edit.data.loadingSubjects">
+
+ <div class="form-group">
+
+ <label class="col-sm-3 control-label" data-translate="moon.policy.rules.edit.action.add.selectedSubjects">Selected Subjcet(s)</label>
+
+ <div class="col-sm-6">
+
+ <ul>
+
+ <li ng-repeat="(key, value) in edit.data.selectedSubjectsList">
+
+ <span ng-bind="value.name" ></span> <a href="" ng-click="edit.removeSelectedDataFromRules(value, edit.data.subjectCST)"><span style="font-size:1.5em; line-height: 1.5em" class="glyphicon glyphicon-remove"></span></a>
+
+ </li>
+
+ </ul>
+
+ </div>
+
+ </div>
+
+ </div>
+
+ </div>
+
+ <div ng-if="edit.selectedMetaRules.subject_categories.length === 0">
+
+ </div>
+
+ </div>
+
+ <div class="col-md-4">
+
+ <div ng-if="edit.selectedMetaRules.object_categories.length > 0">
+
+ <div class="row">
+
+ <div ng-if="!edit.data.loadingObjects">
+
+ <label for="objectsList" class="col-sm-3 control-label" data-translate="moon.policy.rules.edit.action.add.categories.object" data-translate-values="{ number: edit.selectedMetaRules.object_categories.length }">Select Object(s)</label>
+
+ <div class="col-sm-7" >
+
+ <ui-select ng-model="edit.selectedObject" name="objectsList" id="objectsList" required>
+
+ <ui-select-match placeholder="(None)" ng-bind="$select.selected.value.name"></ui-select-match>
+ <ui-select-choices repeat="aObject in edit.data.objectsToBeSelected">
+ <div ng-value="aObject" ng-bind="aObject.value.name"></div>
+ </ui-select-choices>
+
+ </ui-select>
+
+ <div class="help-block" ng-show="edit.form.objectsList.$dirty && edit.form.objectsList.$invalid || !edit.numberOfSelectedObjecttValid">
+ <small class="error" ng-show="edit.form.objectsList.$error.required || !edit.numberOfSelectedObjecttValid" data-translate="moon.policy.rules.edit.action.add.check.object.required" data-translate-values="{ number: edit.selectedMetaRules.object_categories.length }">Some objects are required</small>
+ </div>
+
+ </div>
+
+ <div class="col-sm-2 text-center">
+ <a href="" ng-if="edit.selectedObject && !edit.isNumberSelectedDataAtMaximum(edit.data.objectCST)"
+ ng-click="edit.addDataToRules(edit.data.objectCST)"><span style="font-size:1.5em; line-height: 1.5em;" class="glyphicon glyphicon-plus-sign"></span></a>
+ </div>
+
+ </div>
+
+ <div ng-if="edit.data.loadingObjects">
+
+ <moon-loader></moon-loader>
+
+ </div>
+
+ </div>
+
+ <div class="row" ng-if="!edit.data.loadingObjects">
+
+ <div class="form-group">
+
+ <label class="col-sm-3 control-label" data-translate="moon.policy.rules.edit.action.add.selectedObjects">Selected Objcet(s)</label>
+
+ <div class="col-sm-6">
+
+ <ul>
+
+ <li ng-repeat="(key, value) in edit.data.selectedObjectsList">
+
+ <span ng-bind="value.value.name" ></span> <a href="" ng-click="edit.removeSelectedDataFromRules(value, edit.data.objectCST)"><span style="font-size:1.5em; line-height: 1.5em" class="glyphicon glyphicon-remove"></span></a>
+
+ </li>
+
+ </ul>
+
+ </div>
+ </div>
+
+ </div>
+
+ </div>
+
+ <div ng-if="edit.selectedMetaRules.object_categories.length === 0">
+
+ </div>
+
+ </div>
+
+ <div class="col-md-4">
+
+ <div ng-if="edit.selectedMetaRules.action_categories.length > 0">
+
+ <div class="row">
+
+ <div ng-if="!edit.data.loadingActions">
+
+ <label for="actionsList" class="col-sm-3 control-label" data-translate="moon.policy.rules.edit.action.add.categories.action" data-translate-values="{ number: edit.selectedMetaRules.action_categories.length }">Select Action(s)</label>
+
+ <div class="col-sm-7" >
+
+ <ui-select ng-model="edit.selectedAction" name="actionsList" id="actionsList" required>
+
+ <ui-select-match placeholder="(None)" ng-bind="$select.selected.value.name"></ui-select-match>
+ <ui-select-choices repeat="aAction in edit.data.actionsToBeSelected">
+ <div ng-value="aAction" ng-bind="aAction.value.name"></div>
+ </ui-select-choices>
+
+ </ui-select>
+
+ <div class="help-block" ng-show="edit.form.actionsList.$dirty && edit.form.actionsList.$invalid || !edit.numberOfSelectedActionsValid">
+ <small class="error" ng-show="edit.form.actionsList.$error.required || !edit.numberOfSelectedActionsValid" data-translate="moon.policy.rules.edit.action.add.check.action.required" data-translate-values="{ number: edit.selectedMetaRules.action_categories.length }">Some action are required</small>
+ </div>
+ </div>
+
+ <div class="col-sm-2 text-center">
+ <a href="" ng-if="edit.selectedAction && !edit.isNumberSelectedDataAtMaximum(edit.data.actionCST)"
+ ng-click="edit.addDataToRules(edit.data.actionCST)"><span style="font-size:1.5em; line-height: 1.5em;" class="glyphicon glyphicon-plus-sign"></span></a>
+ </div>
+
+ </div>
+
+ <div ng-if="edit.data.loadingActions">
+
+ <moon-loader></moon-loader>
+
+ </div>
+
+ </div>
+
+ <div class="row" ng-if="!edit.data.loadingActions">
+
+ <div class="form-group">
+
+ <label class="col-sm-3 control-label" data-translate="moon.policy.rules.edit.action.add.selectedActions">Selected Action(s)</label>
+
+ <div class="col-sm-6">
+
+ <ul>
+
+ <li ng-repeat="(key, value) in edit.data.selectedActionsList">
+
+ <span ng-bind="value.value.name" ></span> <a href="" ng-click="edit.removeSelectedDataFromRules(value, edit.data.actionCST)"><span style="font-size:1.5em; line-height: 1.5em" class="glyphicon glyphicon-remove"></span></a>
+
+ </li>
+
+ </ul>
+
+ </div>
+ </div>
+
+ </div>
+
+ </div>
+
+ <div ng-if="edit.selectedMetaRules.action_categories.length === 0">
+
+ </div>
+
+ </div>
+
+ </div>
+
+ <div class="form-group" ng-class="{'has-error': edit.form.instructions.$invalid && edit.form.instructions.$dirty || !edit.instructionsValid}">
+
+ <label for="instructions" class="col-sm-3 control-label" data-translate="moon.policy.rules.edit.action.add.instructions">Instruction</label>
+
+ <div class="col-sm-6">
+ <textarea id="instructions" name="instructions" class="form-control" ng-model="edit.rules.instructions" rows="6" required></textarea>
+ <div class="help-block" ng-show="edit.form.instructions.$dirty && edit.form.instructions.$invalid || !edit.instructionsValid ">
+ <small class="error" data-translate="moon.policy.rules.edit.action.add.check.instructions.required">An instructions is required</small>
+ </div>
+ </div>
+
+ </div>
+
+ <div class="form-group">
+
+ <div class="pull-right">
+
+ <a href="" ng-disabled="edit.loading" ng-click="edit.create()" class="btn btn-warning">
+ <span class="glyphicon glyphicon-save"></span>
+ <span data-translate="moon.policy.rules.edit.action.create">Create</span>
+ </a>
+
+ <moon-loader ng-if="edit.loading"></moon-loader>
+
+ </div>
+
+ </div>
+
+ </div>
+
+ </form>
+
+ </div>
+
+</div> \ No newline at end of file
diff --git a/moonv4/moon_gui/static/app/policy/edit/parameter/rules/rules-list.tpl.html b/moonv4/moon_gui/static/app/policy/edit/parameter/rules/rules-list.tpl.html
index 76ac4365..76ac4365 100644..100755
--- a/moonv4/moon_gui/static/app/policy/edit/parameter/rules/rules-list.tpl.html
+++ b/moonv4/moon_gui/static/app/policy/edit/parameter/rules/rules-list.tpl.html
diff --git a/moonv4/moon_gui/static/app/policy/edit/parameter/rules/rules.edit.dir.js b/moonv4/moon_gui/static/app/policy/edit/parameter/rules/rules.edit.dir.js
new file mode 100755
index 00000000..b7bb7614
--- /dev/null
+++ b/moonv4/moon_gui/static/app/policy/edit/parameter/rules/rules.edit.dir.js
@@ -0,0 +1,537 @@
+(function() {
+
+ 'use strict';
+
+ angular
+ .module('moon')
+ .directive('moonRulesEdit', moonRulesEdit);
+
+ moonRulesEdit.$inject = [];
+
+ function moonRulesEdit() {
+
+ return {
+ templateUrl : 'html/policy/edit/parameter/rules/rules-edit.tpl.html',
+ bindToController : true,
+ controller : moonRulesEditController,
+ controllerAs : 'edit',
+ scope : {
+ policy : '='
+ },
+ restrict : 'E',
+ replace : true
+ };
+
+ }
+
+ angular
+ .module('moon')
+ .controller('moonRulesEditController', moonRulesEditController);
+
+ moonRulesEditController.$inject = ['$scope', 'rulesService', 'alertService', '$translate',
+ 'formService', 'policyService', 'utilService', 'metaRuleService', 'metaDataService', 'modelService', 'dataService', 'DATA_CST'];
+
+ function moonRulesEditController($scope, rulesService, alertService, $translate,
+ formService, policyService, utilService, metaRuleService, metaDataService, modelService, dataService, DATA_CST) {
+
+ var edit = this;
+
+ edit.policy = $scope.edit.policy;
+ edit.editMode = true;
+
+ edit.fromList = false;
+
+ edit.loading = false;
+
+ edit.form = {};
+ edit.showDetailselectedMetaRules = false;
+
+ edit.list = [];
+ edit.policyList = [];
+
+ edit.categories = {
+ subject : [],
+ loadingSubjects: true,
+ object : [],
+ loadingObjects: true,
+ action : [],
+ loadingActions : true
+ };
+
+ edit.data = {}; // this object is filled in declareDataObject():
+
+ edit.create = createRules;
+ edit.addDataToRules = addDataToRules;
+ edit.removeSelectedDataFromRules = removeSelectedDataFromRules;
+ edit.isNumberSelectedDataAtMaximum = isNumberSelectedDataAtMaximum;
+
+ //this variable is related to checks on Instruction field which is in JSON
+ edit.instructionsValid = true;
+ edit.numberOfSelectedSubjectValid = true;
+ edit.numberOfSelectedObjecttValid = true;
+ edit.numberOfSelectedActionsValid = true;
+
+ activate();
+
+ /*
+ *
+ */
+ function activate(){
+
+ edit.rules = {meta_rule_id: null, rule: [], policy_id: null, instructions: '[{"decision": "grant"}]', enabled: true};
+ declareDataObject();
+ loadAllPolicies();
+ clearSelectedMetaRules();
+
+ }
+
+ function loadAllPolicies() {
+
+ edit.policyList = [];
+
+ policyService.findAllWithCallback( function(data) {
+
+ _.each(data, function(element){
+
+ if(element.id === edit.policy.id){
+ edit.selectedPolicy = element;
+ }
+
+ });
+
+ edit.policyList = data;
+
+ });
+ }
+
+ $scope.$watch('edit.selectedPolicy', function(newValue){
+
+ clearSelectedMetaRules();
+
+ if(!_.isUndefined(newValue)){
+
+ loadRelatedMetaRules();
+
+ }
+
+ });
+
+ $scope.$watch('edit.selectedMetaRules', function(newValue){
+
+ clearSelectedData();
+
+ edit.categories = {
+ subject : [],
+ loadingSubjects: true,
+ object : [],
+ loadingObjects: true,
+ action : [],
+ loadingActions : true
+ };
+
+ declareDataObject();
+
+ if(!_.isUndefined(newValue)){
+
+ loadRelatedCategoriesAndData(newValue.subject_categories, newValue.object_categories, newValue.action_categories);
+
+ }
+
+ });
+
+ /**
+ * To get the related MetaRules, it is required to :
+ * - Get the model related to the policy
+ * - Get the metaRules associated to the model
+ * - Get the MetaData associated to the metaRules
+ */
+ function loadRelatedMetaRules() {
+
+ edit.selectedPolicy.meta_rules_values = undefined;
+
+ modelService.findOneWithCallback(edit.selectedPolicy.model_id, function(model){
+
+ metaRuleService.findSomeWithCallback(model.meta_rules, function(metaRules){
+
+ edit.selectedPolicy.meta_rules_values = metaRules;
+
+ });
+
+ });
+
+ }
+
+ /**
+ * Load categories from arrays of id in args
+ * @param subjectsCategories, list of subject id related to the metaRule
+ * @param objectCategories, list of object id related to the metaRule
+ * @param actionsCategories, list of action id related to the metaRule
+ */
+ function loadRelatedCategoriesAndData(subjectsCategories, objectCategories, actionsCategories){
+
+ metaDataService.subject.findSomeWithCallback(subjectsCategories, function(list){
+
+ edit.categories.subject = list;
+ edit.categories.loadingSubjects = false;
+
+ _.each(edit.categories.subject, function(aSubject){
+
+ dataService.subject.findAllFromCategoriesWithCallback(edit.selectedPolicy.id, aSubject.id, function(subjects){
+
+ edit.data.subject = subjects;
+ edit.data.loadingSubjects = false;
+ edit.data.subjectsToBeSelected = angular.copy(edit.data.subject);
+
+ });
+
+ });
+
+ });
+
+ metaDataService.object.findSomeWithCallback(objectCategories, function(list){
+
+ edit.categories.object = list;
+ edit.categories.loadingObjects = false;
+
+ _.each(edit.categories.object, function(aObject){
+
+ dataService.object.findAllFromCategoriesWithCallback(edit.selectedPolicy.id, aObject.id, function(objects){
+
+ edit.data.object = objects;
+ edit.data.loadingObjects = false;
+ edit.data.objectsToBeSelected = angular.copy(edit.data.object);
+
+ });
+
+ });
+
+ });
+
+ metaDataService.action.findSomeWithCallback(actionsCategories, function(list){
+
+ edit.categories.action = list;
+ edit.categories.loadingActions = false;
+
+ _.each(edit.categories.action, function(aAction){
+
+ dataService.action.findAllFromCategoriesWithCallback(edit.selectedPolicy.id, aAction.id, function(actions){
+
+ edit.data.action = actions;
+ edit.data.loadingActions = false;
+ edit.data.actionsToBeSelected = angular.copy(edit.data.action);
+
+ });
+
+ });
+
+ });
+
+ }
+
+ /**
+ * createRules, create Rules depending of what has been filled in the view
+ */
+ function createRules() {
+
+ edit.instructionsValid = true;
+ edit.numberOfSelectedSubjectValid = true;
+ edit.numberOfSelectedObjecttValid = true;
+ edit.numberOfSelectedActionsValid = true;
+
+ manageInstructionContent();
+ // bellow function is called here in order to display errors into the view
+ manageNumberOfSelectedData();
+
+ if(formService.isInvalid(edit.form)) {
+
+ formService.checkFieldsValidity(edit.form);
+
+ //manageNumberOfSelectedData is call again in order to check if errors have been display into the view
+ }else if(edit.instructionsValid && manageNumberOfSelectedData()){
+
+ startLoading();
+ buildRulesArray();
+
+ edit.rules.meta_rule_id = edit.selectedMetaRules.id;
+ edit.rules.policy_id = edit.selectedPolicy.id;
+
+ var rulesToSend = angular.copy(edit.rules);
+ rulesToSend.instructions = JSON.parse(edit.rules.instructions);
+
+ rulesService.add(rulesToSend, edit.policy.id, createSuccess, createError);
+ }
+
+
+ function createSuccess(data) {
+
+ var created = utilService.transformOne(data, 'rules');
+
+ $translate('moon.policy.rules.edit.action.add.create.success').then(function (translatedValue) {
+ alertService.alertSuccess(translatedValue);
+ });
+
+ $scope.$emit('event:createRulesFromDataRulesSuccess', created);
+
+ activate();
+
+ stopLoading();
+
+ }
+
+ function createError(reason) {
+
+ $translate('moon.policy.rules.edit.action.add.create.error').then(function (translatedValue) {
+ alertService.alertError(translatedValue);
+ });
+
+ stopLoading();
+
+ }
+
+ }
+
+ /**
+ * if instructions attribute is not good then edit.instructionsValid is set to false
+ * it will allow the view to display an error
+ */
+ function manageInstructionContent(){
+
+ if (!isInstructionValid(edit.rules.instructions)){
+
+ edit.instructionsValid = false;
+
+ }else{
+
+ edit.instructionsValid = true;
+
+ }
+ }
+
+ /**
+ * return true if the user has selected the number required of Selected Data (subject, object or action)
+ * if one is missing then return false
+ * it will also set numberOfSelected(Subject/Object/Action)Valid to true or false in order to display errors form in the view
+ * @returns {boolean}
+ */
+ function manageNumberOfSelectedData(){
+
+ isNumberSelectedDataAtMaximum(DATA_CST.TYPE.SUBJECT) ?
+ edit.numberOfSelectedSubjectValid = true: edit.numberOfSelectedSubjectValid = false;
+ isNumberSelectedDataAtMaximum(DATA_CST.TYPE.OBJECT) ?
+ edit.numberOfSelectedObjecttValid = true: edit.numberOfSelectedObjecttValid = false;
+ isNumberSelectedDataAtMaximum(DATA_CST.TYPE.ACTION) ?
+ edit.numberOfSelectedActionsValid = true: edit.numberOfSelectedActionsValid = false;
+
+ return edit.numberOfSelectedSubjectValid && edit.numberOfSelectedObjecttValid && edit.numberOfSelectedActionsValid;
+ }
+
+ /**
+ * Check if the variables in param is not undefined and if it is a JSON
+ * It is used for instructions attribute of a Rules object
+ * @param str
+ * @returns {boolean|*}
+ */
+ function isInstructionValid(str){
+
+ return !_.isUndefined(str) && isJsonString(str);
+
+ }
+
+ function isJsonString(str) {
+
+ var item = null;
+
+ try {
+ item = JSON.parse(str);
+ } catch (e) {
+
+ return false;
+ }
+
+ if (typeof item === 'object' && item !== null) {
+
+ return true;
+ }
+
+ return false;
+ }
+
+ function startLoading(){
+
+ edit.loading = true;
+
+ }
+
+ function stopLoading(){
+
+ edit.loading = false;
+
+ }
+
+ /**
+ * allow to clear selected values in the form
+ */
+ function clearSelectedMetaRules(){
+
+ edit.selectedMetaRules = undefined;
+
+ clearSelectedData();
+
+ }
+
+ function clearSelectedData(){
+
+ edit.selectedSubject = undefined;
+ edit.selectedObject = undefined;
+ edit.selectedAction = undefined;
+
+ }
+
+ /**
+ * check if the number of Selected Data is equal to the number of categories associated to the metaRule
+ * @param typeCST : 'SUBJECT', 'OBJECT', 'ACTION'
+ * @returns {boolean}
+ */
+ function isNumberSelectedDataAtMaximum(typeCST){
+
+ if(!edit.selectedMetaRules){
+ return false;
+ }
+
+ switch (typeCST) {
+
+ case DATA_CST.TYPE.SUBJECT:
+
+ return edit.data.selectedSubjectsList.length === edit.selectedMetaRules.subject_categories.length;
+
+ case DATA_CST.TYPE.OBJECT:
+
+ return edit.data.selectedObjectsList.length === edit.selectedMetaRules.object_categories.length;
+
+ case DATA_CST.TYPE.ACTION:
+
+ return edit.data.selectedActionsList.length === edit.selectedMetaRules.action_categories.length;
+ }
+ }
+
+ /**
+ * Add a data to an array of selected value (SUBJECT/OBJECT/ACTION)
+ * those arrays will used in the create function in order to filled the rule attribute of a rules object
+ * it will remove the selected value from the possible value to be selected once the data is added
+ * @param typeCST
+ */
+ function addDataToRules(typeCST){
+
+ switch (typeCST) {
+ case DATA_CST.TYPE.SUBJECT:
+
+ if (!edit.selectedSubject || isNumberSelectedDataAtMaximum(typeCST)
+ || _.contains(edit.data.selectedSubjectsList, edit.selectedSubject)) {
+ return;
+ }
+
+ edit.data.selectedSubjectsList.push(edit.selectedSubject);
+ edit.data.subjectsToBeSelected = _.without(edit.data.subjectsToBeSelected, edit.selectedSubject);
+
+ break;
+ case DATA_CST.TYPE.OBJECT:
+
+ if (!edit.selectedObject || isNumberSelectedDataAtMaximum(typeCST)
+ || _.contains(edit.data.selectedObjectsList, edit.selectedObject)) {
+ return;
+ }
+
+ edit.data.selectedObjectsList.push(edit.selectedObject);
+ edit.data.objectsToBeSelected = _.without(edit.data.objectsToBeSelected, edit.selectedObject);
+
+ break;
+
+ case DATA_CST.TYPE.ACTION:
+ if (!edit.selectedAction || isNumberSelectedDataAtMaximum(typeCST)
+ || _.contains(edit.data.selectedActionsList, edit.selectedAction)) {
+ return;
+ }
+
+ edit.data.selectedActionsList.push(edit.selectedAction);
+ edit.data.actionsToBeSelected = _.without(edit.data.actionsToBeSelected, edit.selectedAction);
+
+ break;
+ }
+
+ }
+
+ /**
+ * Remove a selected value,
+ * refresh the list of possible value to be selected with the removed selected value
+ * @param data
+ * @param typeCST
+ */
+ function removeSelectedDataFromRules(data, typeCST) {
+
+ switch (typeCST) {
+
+ case DATA_CST.TYPE.SUBJECT:
+
+ edit.data.subjectsToBeSelected.push(data);
+ edit.data.selectedSubjectsList = _.without(edit.data.selectedSubjectsList, data);
+ break;
+
+ case DATA_CST.TYPE.OBJECT:
+
+ edit.data.objectsToBeSelected.push(data);
+ edit.data.selectedObjectsList = _.without(edit.data.selectedObjectsList, data);
+ break;
+
+ case DATA_CST.TYPE.ACTION:
+
+ edit.data.actionsToBeSelected.push(data);
+ edit.data.selectedActionsList = _.without(edit.data.selectedActionsList, data);
+ break;
+ }
+
+ }
+
+ /**
+ * fill edit.rules.rule array with the selected data
+ * it will first add subject list, object list and then action list
+ */
+ function buildRulesArray(){
+
+ _.each(edit.data.selectedSubjectsList, pushInRulesTab);
+ _.each(edit.data.selectedObjectsList, pushInRulesTab);
+ _.each(edit.data.selectedActionsList, pushInRulesTab);
+
+ function pushInRulesTab(elem){
+ edit.rules.rule.push(elem.id);
+ }
+ }
+
+ /**
+ * Declare the data object which contains attributes related to data,
+ * values to be selected, values selected, loader...
+ */
+ function declareDataObject(){
+
+ edit.data = {
+ subject : [], // List of subjects related to the policy
+ loadingSubjects: true, // allow to know if a call to the API is in progress
+ subjectsToBeSelected : [], // List of subjects the user can select
+ selectedSubjectsList: [], // List of subjects selected by the user from subjectsToBeSelected
+ subjectCST : DATA_CST.TYPE.SUBJECT,
+ object : [],
+ loadingObjects: true,
+ objectsToBeSelected: [],
+ selectedObjectsList: [],
+ objectCST : DATA_CST.TYPE.OBJECT,
+ action : [],
+ loadingActions : true,
+ actionsToBeSelected : [],
+ selectedActionsList: [],
+ actionCST : DATA_CST.TYPE.ACTION
+ }
+
+ }
+
+ }
+
+})(); \ No newline at end of file
diff --git a/moonv4/moon_gui/static/app/policy/edit/parameter/rules/rules.list.dir.js b/moonv4/moon_gui/static/app/policy/edit/parameter/rules/rules.list.dir.js
index 5c3e7457..5c3e7457 100644..100755
--- a/moonv4/moon_gui/static/app/policy/edit/parameter/rules/rules.list.dir.js
+++ b/moonv4/moon_gui/static/app/policy/edit/parameter/rules/rules.list.dir.js
diff --git a/moonv4/moon_gui/static/app/policy/edit/policy-edit-basic.tpl.html b/moonv4/moon_gui/static/app/policy/edit/policy-edit-basic.tpl.html
index f55c1d05..f55c1d05 100644..100755
--- a/moonv4/moon_gui/static/app/policy/edit/policy-edit-basic.tpl.html
+++ b/moonv4/moon_gui/static/app/policy/edit/policy-edit-basic.tpl.html
diff --git a/moonv4/moon_gui/static/app/policy/edit/policy-edit.tpl.html b/moonv4/moon_gui/static/app/policy/edit/policy-edit.tpl.html
index a1a6a54a..a1a6a54a 100644..100755
--- a/moonv4/moon_gui/static/app/policy/edit/policy-edit.tpl.html
+++ b/moonv4/moon_gui/static/app/policy/edit/policy-edit.tpl.html
diff --git a/moonv4/moon_gui/static/app/policy/edit/policy.controller.edit.js b/moonv4/moon_gui/static/app/policy/edit/policy.controller.edit.js
index 123ee58b..123ee58b 100644..100755
--- a/moonv4/moon_gui/static/app/policy/edit/policy.controller.edit.js
+++ b/moonv4/moon_gui/static/app/policy/edit/policy.controller.edit.js
diff --git a/moonv4/moon_gui/static/app/policy/edit/policy.edit.basic.dir.js b/moonv4/moon_gui/static/app/policy/edit/policy.edit.basic.dir.js
index c32d9e69..c32d9e69 100644..100755
--- a/moonv4/moon_gui/static/app/policy/edit/policy.edit.basic.dir.js
+++ b/moonv4/moon_gui/static/app/policy/edit/policy.edit.basic.dir.js
diff --git a/moonv4/moon_gui/static/app/policy/policy-list.tpl.html b/moonv4/moon_gui/static/app/policy/policy-list.tpl.html
index aeb90f0b..aeb90f0b 100644..100755
--- a/moonv4/moon_gui/static/app/policy/policy-list.tpl.html
+++ b/moonv4/moon_gui/static/app/policy/policy-list.tpl.html
diff --git a/moonv4/moon_gui/static/app/policy/policy-mapped-list.tpl.html b/moonv4/moon_gui/static/app/policy/policy-mapped-list.tpl.html
index 127dae3b..127dae3b 100644..100755
--- a/moonv4/moon_gui/static/app/policy/policy-mapped-list.tpl.html
+++ b/moonv4/moon_gui/static/app/policy/policy-mapped-list.tpl.html
diff --git a/moonv4/moon_gui/static/app/policy/policy.controller.list.js b/moonv4/moon_gui/static/app/policy/policy.controller.list.js
index fc2c6503..fc2c6503 100644..100755
--- a/moonv4/moon_gui/static/app/policy/policy.controller.list.js
+++ b/moonv4/moon_gui/static/app/policy/policy.controller.list.js
diff --git a/moonv4/moon_gui/static/app/policy/policy.mapped.list.dir.js b/moonv4/moon_gui/static/app/policy/policy.mapped.list.dir.js
index 78bb3b8d..78bb3b8d 100644..100755
--- a/moonv4/moon_gui/static/app/policy/policy.mapped.list.dir.js
+++ b/moonv4/moon_gui/static/app/policy/policy.mapped.list.dir.js
diff --git a/moonv4/moon_gui/static/app/project/action/mapping/project-map.tpl.html b/moonv4/moon_gui/static/app/project/action/mapping/project-map.tpl.html
index 5ffd98e2..5ffd98e2 100644..100755
--- a/moonv4/moon_gui/static/app/project/action/mapping/project-map.tpl.html
+++ b/moonv4/moon_gui/static/app/project/action/mapping/project-map.tpl.html
diff --git a/moonv4/moon_gui/static/app/project/action/mapping/project-unmap.tpl.html b/moonv4/moon_gui/static/app/project/action/mapping/project-unmap.tpl.html
index 5cc5c6dd..5cc5c6dd 100644..100755
--- a/moonv4/moon_gui/static/app/project/action/mapping/project-unmap.tpl.html
+++ b/moonv4/moon_gui/static/app/project/action/mapping/project-unmap.tpl.html
diff --git a/moonv4/moon_gui/static/app/project/action/mapping/project.controller.map.js b/moonv4/moon_gui/static/app/project/action/mapping/project.controller.map.js
index afa2bfc0..afa2bfc0 100644..100755
--- a/moonv4/moon_gui/static/app/project/action/mapping/project.controller.map.js
+++ b/moonv4/moon_gui/static/app/project/action/mapping/project.controller.map.js
diff --git a/moonv4/moon_gui/static/app/project/action/mapping/project.controller.unmap.js b/moonv4/moon_gui/static/app/project/action/mapping/project.controller.unmap.js
index 911b30ff..911b30ff 100644..100755
--- a/moonv4/moon_gui/static/app/project/action/mapping/project.controller.unmap.js
+++ b/moonv4/moon_gui/static/app/project/action/mapping/project.controller.unmap.js
diff --git a/moonv4/moon_gui/static/app/project/action/project-add.tpl.html b/moonv4/moon_gui/static/app/project/action/project-add.tpl.html
index a90dcfa1..a90dcfa1 100644..100755
--- a/moonv4/moon_gui/static/app/project/action/project-add.tpl.html
+++ b/moonv4/moon_gui/static/app/project/action/project-add.tpl.html
diff --git a/moonv4/moon_gui/static/app/project/action/project-delete.tpl.html b/moonv4/moon_gui/static/app/project/action/project-delete.tpl.html
index 96b4f2e3..96b4f2e3 100644..100755
--- a/moonv4/moon_gui/static/app/project/action/project-delete.tpl.html
+++ b/moonv4/moon_gui/static/app/project/action/project-delete.tpl.html
diff --git a/moonv4/moon_gui/static/app/project/action/project-view.tpl.html b/moonv4/moon_gui/static/app/project/action/project-view.tpl.html
index 3228c915..3228c915 100644..100755
--- a/moonv4/moon_gui/static/app/project/action/project-view.tpl.html
+++ b/moonv4/moon_gui/static/app/project/action/project-view.tpl.html
diff --git a/moonv4/moon_gui/static/app/project/action/project.controller.add.js b/moonv4/moon_gui/static/app/project/action/project.controller.add.js
index 4d12b75d..4d12b75d 100644..100755
--- a/moonv4/moon_gui/static/app/project/action/project.controller.add.js
+++ b/moonv4/moon_gui/static/app/project/action/project.controller.add.js
diff --git a/moonv4/moon_gui/static/app/project/action/project.controller.delete.js b/moonv4/moon_gui/static/app/project/action/project.controller.delete.js
index 4f18f8e6..4f18f8e6 100644..100755
--- a/moonv4/moon_gui/static/app/project/action/project.controller.delete.js
+++ b/moonv4/moon_gui/static/app/project/action/project.controller.delete.js
diff --git a/moonv4/moon_gui/static/app/project/action/project.controller.view.js b/moonv4/moon_gui/static/app/project/action/project.controller.view.js
index fe98a507..fe98a507 100644..100755
--- a/moonv4/moon_gui/static/app/project/action/project.controller.view.js
+++ b/moonv4/moon_gui/static/app/project/action/project.controller.view.js
diff --git a/moonv4/moon_gui/static/app/project/project-list.tpl.html b/moonv4/moon_gui/static/app/project/project-list.tpl.html
index 82a3745e..82a3745e 100644..100755
--- a/moonv4/moon_gui/static/app/project/project-list.tpl.html
+++ b/moonv4/moon_gui/static/app/project/project-list.tpl.html
diff --git a/moonv4/moon_gui/static/app/project/project.controller.list.js b/moonv4/moon_gui/static/app/project/project.controller.list.js
index b1cb2056..b1cb2056 100644..100755
--- a/moonv4/moon_gui/static/app/project/project.controller.list.js
+++ b/moonv4/moon_gui/static/app/project/project.controller.list.js
diff --git a/moonv4/moon_gui/static/app/services/gui/alert.service.js b/moonv4/moon_gui/static/app/services/gui/alert.service.js
index 8435eab1..8435eab1 100644..100755
--- a/moonv4/moon_gui/static/app/services/gui/alert.service.js
+++ b/moonv4/moon_gui/static/app/services/gui/alert.service.js
diff --git a/moonv4/moon_gui/static/app/services/gui/browser.service.js b/moonv4/moon_gui/static/app/services/gui/browser.service.js
index 88c693a8..88c693a8 100644..100755
--- a/moonv4/moon_gui/static/app/services/gui/browser.service.js
+++ b/moonv4/moon_gui/static/app/services/gui/browser.service.js
diff --git a/moonv4/moon_gui/static/app/services/gui/form.service.js b/moonv4/moon_gui/static/app/services/gui/form.service.js
index e436593c..e436593c 100644..100755
--- a/moonv4/moon_gui/static/app/services/gui/form.service.js
+++ b/moonv4/moon_gui/static/app/services/gui/form.service.js
diff --git a/moonv4/moon_gui/static/app/services/gui/menu.service.js b/moonv4/moon_gui/static/app/services/gui/menu.service.js
index fd90a2fa..fd90a2fa 100644..100755
--- a/moonv4/moon_gui/static/app/services/gui/menu.service.js
+++ b/moonv4/moon_gui/static/app/services/gui/menu.service.js
diff --git a/moonv4/moon_gui/static/app/services/gui/security.pipeline.service.js b/moonv4/moon_gui/static/app/services/gui/security.pipeline.service.js
index 3831e487..3831e487 100644..100755
--- a/moonv4/moon_gui/static/app/services/gui/security.pipeline.service.js
+++ b/moonv4/moon_gui/static/app/services/gui/security.pipeline.service.js
diff --git a/moonv4/moon_gui/static/app/services/gui/util.service.js b/moonv4/moon_gui/static/app/services/gui/util.service.js
index 7274244a..7274244a 100644..100755
--- a/moonv4/moon_gui/static/app/services/gui/util.service.js
+++ b/moonv4/moon_gui/static/app/services/gui/util.service.js
diff --git a/moonv4/moon_gui/static/app/services/gui/version.service.js b/moonv4/moon_gui/static/app/services/gui/version.service.js
index 5f9f2786..5f9f2786 100644..100755
--- a/moonv4/moon_gui/static/app/services/gui/version.service.js
+++ b/moonv4/moon_gui/static/app/services/gui/version.service.js
diff --git a/moonv4/moon_gui/static/app/services/moon/model/model.service.js b/moonv4/moon_gui/static/app/services/moon/model/model.service.js
index a676fc1a..a676fc1a 100644..100755
--- a/moonv4/moon_gui/static/app/services/moon/model/model.service.js
+++ b/moonv4/moon_gui/static/app/services/moon/model/model.service.js
diff --git a/moonv4/moon_gui/static/app/services/moon/pdp.service.js b/moonv4/moon_gui/static/app/services/moon/pdp.service.js
index 822f7414..822f7414 100644..100755
--- a/moonv4/moon_gui/static/app/services/moon/pdp.service.js
+++ b/moonv4/moon_gui/static/app/services/moon/pdp.service.js
diff --git a/moonv4/moon_gui/static/app/services/moon/policy/parameters/assignements.service.js b/moonv4/moon_gui/static/app/services/moon/policy/parameters/assignements.service.js
index ca138b45..ca138b45 100644..100755
--- a/moonv4/moon_gui/static/app/services/moon/policy/parameters/assignements.service.js
+++ b/moonv4/moon_gui/static/app/services/moon/policy/parameters/assignements.service.js
diff --git a/moonv4/moon_gui/static/app/services/moon/policy/parameters/data.service.js b/moonv4/moon_gui/static/app/services/moon/policy/parameters/data.service.js
index 1bbd3b24..1bbd3b24 100644..100755
--- a/moonv4/moon_gui/static/app/services/moon/policy/parameters/data.service.js
+++ b/moonv4/moon_gui/static/app/services/moon/policy/parameters/data.service.js
diff --git a/moonv4/moon_gui/static/app/services/moon/policy/parameters/perimeter.service.js b/moonv4/moon_gui/static/app/services/moon/policy/parameters/perimeter.service.js
index 42e7288a..42e7288a 100644..100755
--- a/moonv4/moon_gui/static/app/services/moon/policy/parameters/perimeter.service.js
+++ b/moonv4/moon_gui/static/app/services/moon/policy/parameters/perimeter.service.js
diff --git a/moonv4/moon_gui/static/app/services/moon/policy/parameters/rules.service.js b/moonv4/moon_gui/static/app/services/moon/policy/parameters/rules.service.js
new file mode 100755
index 00000000..76b24011
--- /dev/null
+++ b/moonv4/moon_gui/static/app/services/moon/policy/parameters/rules.service.js
@@ -0,0 +1,56 @@
+/**
+ * @author Samy Abdallah
+ */
+
+(function() {
+
+ 'use strict';
+
+ angular
+ .module('moon')
+ .factory('rulesService', rulesService);
+
+ rulesService.$inject = ['$resource', 'REST_URI', 'utilService'];
+
+ function rulesService($resource, REST_URI, utilService) {
+
+ return {
+
+ data: {
+
+ policy: $resource(REST_URI.POLICIES + ':policy_id/rules/:rule_id', {}, {
+ get: {method: 'GET'},
+ create: {method: 'POST'},
+ remove: {method: 'DELETE'}
+ })
+
+ },
+
+ add: function (rules, policyId, callbackSuccess, callbackError ) {
+
+ this.data.policy.create({policy_id: policyId}, rules, callbackSuccess, callbackError);
+
+ },
+
+ delete: function (ruleId, policyId, callbackSuccess, callbackError ) {
+
+ this.data.policy.remove({policy_id: policyId, rule_id: ruleId}, {}, callbackSuccess, callbackError);
+
+ },
+
+ findAllFromPolicyWithCallback: function(policyId, callback){
+
+ this.data.policy.get({policy_id: policyId}).$promise.then(function(data) {
+
+ callback(data.rules.rules);
+ //callback(utilService.transform(data['rules'], 'rules'));
+
+ });
+
+ }
+
+
+ }
+
+ }
+})(); \ No newline at end of file
diff --git a/moonv4/moon_gui/static/app/services/moon/policy/policy.service.js b/moonv4/moon_gui/static/app/services/moon/policy/policy.service.js
index 5ad31421..5ad31421 100644..100755
--- a/moonv4/moon_gui/static/app/services/moon/policy/policy.service.js
+++ b/moonv4/moon_gui/static/app/services/moon/policy/policy.service.js
diff --git a/moonv4/moon_gui/static/app/services/moon/rule/metadata.service.js b/moonv4/moon_gui/static/app/services/moon/rule/metadata.service.js
index 8c68b2ef..8c68b2ef 100644..100755
--- a/moonv4/moon_gui/static/app/services/moon/rule/metadata.service.js
+++ b/moonv4/moon_gui/static/app/services/moon/rule/metadata.service.js
diff --git a/moonv4/moon_gui/static/app/services/moon/rule/metarule.service.js b/moonv4/moon_gui/static/app/services/moon/rule/metarule.service.js
index 2679fc5b..2679fc5b 100644..100755
--- a/moonv4/moon_gui/static/app/services/moon/rule/metarule.service.js
+++ b/moonv4/moon_gui/static/app/services/moon/rule/metarule.service.js
diff --git a/moonv4/moon_gui/static/app/services/partner/authentication.service.js b/moonv4/moon_gui/static/app/services/partner/authentication.service.js
index b6d3f36d..b6d3f36d 100644..100755
--- a/moonv4/moon_gui/static/app/services/partner/authentication.service.js
+++ b/moonv4/moon_gui/static/app/services/partner/authentication.service.js
diff --git a/moonv4/moon_gui/static/app/services/partner/nova.service.js b/moonv4/moon_gui/static/app/services/partner/nova.service.js
index 38e2a0fc..38e2a0fc 100644..100755
--- a/moonv4/moon_gui/static/app/services/partner/nova.service.js
+++ b/moonv4/moon_gui/static/app/services/partner/nova.service.js
diff --git a/moonv4/moon_gui/static/app/services/partner/project.service.js b/moonv4/moon_gui/static/app/services/partner/project.service.js
index 4ec27f2e..4ec27f2e 100644..100755
--- a/moonv4/moon_gui/static/app/services/partner/project.service.js
+++ b/moonv4/moon_gui/static/app/services/partner/project.service.js
diff --git a/moonv4/moon_interface/Dockerfile b/moonv4/moon_interface/Dockerfile
index de5447b6..268aba48 100644
--- a/moonv4/moon_interface/Dockerfile
+++ b/moonv4/moon_interface/Dockerfile
@@ -6,6 +6,7 @@ RUN pip3 install moon_utilities moon_db pip --upgrade
ADD . /root
WORKDIR /root/
RUN pip3 install -r requirements.txt --upgrade
+#RUN pip3 install /root/dist/* --upgrade
RUN pip3 install .
CMD ["python3", "-m", "moon_interface"] \ No newline at end of file
diff --git a/moonv4/moon_interface/LICENSE b/moonv4/moon_interface/LICENSE
index 4143aac2..d6456956 100644
--- a/moonv4/moon_interface/LICENSE
+++ b/moonv4/moon_interface/LICENSE
@@ -174,31 +174,29 @@
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
---- License for python-keystoneclient versions prior to 2.1 ---
-
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
-
- 1. Redistributions of source code must retain the above copyright notice,
- this list of conditions and the following disclaimer.
-
- 2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-
- 3. Neither the name of this project nor the names of its contributors may
- be used to endorse or promote products derived from this software without
- specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
-FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
-SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
-CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
-OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ END OF TERMS AND CONDITIONS
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright [yyyy] [name of copyright owner]
+
+ 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.
diff --git a/moonv4/moon_interface/moon_interface/__main__.py b/moonv4/moon_interface/moon_interface/__main__.py
index 2dac7b1d..517fdd60 100644
--- a/moonv4/moon_interface/moon_interface/__main__.py
+++ b/moonv4/moon_interface/moon_interface/__main__.py
@@ -1,3 +1,4 @@
from moon_interface.server import main
-main()
+server = main()
+server.run()
diff --git a/moonv4/moon_interface/moon_interface/api/assignments.py b/moonv4/moon_interface/moon_interface/api/assignments.py
deleted file mode 100644
index 855a9049..00000000
--- a/moonv4/moon_interface/moon_interface/api/assignments.py
+++ /dev/null
@@ -1,264 +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'.
-"""
-Assignments allow to connect data with elements of perimeter
-
-"""
-
-from flask import request
-from flask_restful import Resource
-from oslo_log import log as logging
-from moon_utilities.security_functions import call
-from moon_utilities.security_functions import check_auth
-
-__version__ = "0.2.0"
-
-LOG = logging.getLogger("moon.interface.api." + __name__)
-
-
-class SubjectAssignments(Resource):
- """
- Endpoint for subject assignment requests
- """
-
- __urls__ = (
- "/policies/<string:uuid>/subject_assignments",
- "/policies/<string:uuid>/subject_assignments/",
- "/policies/<string:uuid>/subject_assignments/<string:perimeter_id>",
- "/policies/<string:uuid>/subject_assignments/<string:perimeter_id>/<string:category_id>",
- "/policies/<string:uuid>/subject_assignments/<string:perimeter_id>/<string:category_id>/<string:data_id>",
- )
-
- @check_auth
- def get(self, uuid=None, 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 user_id: user ID who do the request
- :return: {
- "subject_data_id": {
- "policy_id": "ID of the policy",
- "subject_id": "ID of the subject",
- "category_id": "ID of the category",
- "assignments": "Assignments list (list of data_id)",
- }
- }
- :internal_api: get_subject_assignments
- """
- return call(ctx={"id": uuid, "method": "get_subject_assignments", "perimeter_id": perimeter_id, "category_id": category_id, "user_id": user_id},
- args={"data_id": data_id})
-
- @check_auth
- def post(self, uuid=None, perimeter_id=None, category_id=None, data_id=None, user_id=None):
- """Create a subject assignment.
-
- :param uuid: uuid of the policy
- :param perimeter_id: uuid of the subject (not used here)
- :param category_id: uuid of the subject category (not used here)
- :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"
- }
- :return: {
- "subject_data_id": {
- "policy_id": "ID of the policy",
- "subject_id": "ID of the subject",
- "category_id": "ID of the category",
- "assignments": "Assignments list (list of data_id)",
- }
- }
- :internal_api: update_subject_assignment
- """
- return call("security_router",
- ctx={"id": uuid, "method": "update_subject_assignment", "user_id": user_id}, args=request.json)
-
- @check_auth
- def delete(self, uuid=None, perimeter_id=None, category_id=None, data_id=None, user_id=None):
- """Delete a subject assignment 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 user_id: user ID who do the request
- :return: {
- "result": "True or False",
- "message": "optional message"
- }
- :internal_api: delete_subject_assignment
- """
- return call("security_router",
- ctx={"id": uuid, "method": "delete_subject_assignment", "perimeter_id": perimeter_id, "category_id": category_id, "user_id": user_id},
- args={"data_id": data_id})
-
-
-class ObjectAssignments(Resource):
- """
- Endpoint for object assignment requests
- """
-
- __urls__ = (
- "/policies/<string:uuid>/object_assignments",
- "/policies/<string:uuid>/object_assignments/",
- "/policies/<string:uuid>/object_assignments/<string:perimeter_id>",
- "/policies/<string:uuid>/object_assignments/<string:perimeter_id>/<string:category_id>",
- "/policies/<string:uuid>/object_assignments/<string:perimeter_id>/<string:category_id>/<string:data_id>",
- )
-
- @check_auth
- def get(self, uuid=None, 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 user_id: user ID who do the request
- :return: {
- "object_data_id": {
- "policy_id": "ID of the policy",
- "object_id": "ID of the object",
- "category_id": "ID of the category",
- "assignments": "Assignments list (list of data_id)",
- }
- }
- :internal_api: get_object_assignments
- """
- return call("security_router",
- ctx={"id": uuid, "method": "get_object_assignments", "perimeter_id": perimeter_id, "category_id": category_id, "user_id": user_id},
- args={"data_id": data_id})
-
- @check_auth
- def post(self, uuid=None, perimeter_id=None, category_id=None, data_id=None, user_id=None):
- """Create an object assignment.
-
- :param uuid: uuid of the policy
- :param perimeter_id: uuid of the object (not used here)
- :param category_id: uuid of the object category (not used here)
- :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"
- }
- :return: {
- "object_data_id": {
- "policy_id": "ID of the policy",
- "object_id": "ID of the object",
- "category_id": "ID of the category",
- "assignments": "Assignments list (list of data_id)",
- }
- }
- :internal_api: update_object_assignment
- """
- return call("security_router",
- ctx={"id": uuid, "method": "update_object_assignment", "user_id": user_id}, args=request.json)
-
- @check_auth
- def delete(self, uuid=None, perimeter_id=None, category_id=None, data_id=None, user_id=None):
- """Delete a object assignment 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 user_id: user ID who do the request
- :return: {
- "result": "True or False",
- "message": "optional message"
- }
- :internal_api: delete_object_assignment
- """
- return call("security_router",
- ctx={"id": uuid, "method": "delete_object_assignment", "perimeter_id": perimeter_id, "category_id": category_id, "user_id": user_id},
- args={"data_id": data_id})
-
-
-class ActionAssignments(Resource):
- """
- Endpoint for action assignment requests
- """
-
- __urls__ = (
- "/policies/<string:uuid>/action_assignments",
- "/policies/<string:uuid>/action_assignments/",
- "/policies/<string:uuid>/action_assignments/<string:perimeter_id>",
- "/policies/<string:uuid>/action_assignments/<string:perimeter_id>/<string:category_id>",
- "/policies/<string:uuid>/action_assignments/<string:perimeter_id>/<string:category_id>/<string:data_id>",
- )
-
- @check_auth
- def get(self, uuid=None, perimeter_id=None, category_id=None, data_id=None, user_id=None):
- """Retrieve all action assignment or a specific one for a given policy
-
- :param uuid: uuid of the policy
- :param perimeter_id: uuid of the action
- :param category_id: uuid of the action category
- :param data_id: uuid of the action scope
- :param user_id: user ID who do the request
- :return: {
- "action_data_id": {
- "policy_id": "ID of the policy",
- "object_id": "ID of the action",
- "category_id": "ID of the category",
- "assignments": "Assignments list (list of data_id)",
- }
- }
- :internal_api: get_action_assignments
- """
- return call("security_router", ctx={"id": uuid, "method": "get_action_assignments", "perimeter_id": perimeter_id, "category_id": category_id, "user_id": user_id},
- args={"data_id": data_id})
-
- @check_auth
- def post(self, uuid=None, perimeter_id=None, category_id=None, data_id=None, user_id=None):
- """Create an action assignment.
-
- :param uuid: uuid of the policy
- :param perimeter_id: uuid of the action (not used here)
- :param category_id: uuid of the action category (not used here)
- :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"
- }
- :return: {
- "action_data_id": {
- "policy_id": "ID of the policy",
- "object_id": "ID of the action",
- "category_id": "ID of the category",
- "assignments": "Assignments list (list of data_id)",
- }
- }
- :internal_api: update_action_assignment
- """
- return call("security_router", ctx={"id": uuid, "method": "update_action_assignment", "user_id": user_id},
- args=request.json)
-
- @check_auth
- def delete(self, uuid=None, perimeter_id=None, category_id=None, data_id=None, user_id=None):
- """Delete a action assignment for a given policy
-
- :param uuid: uuid of the policy
- :param perimeter_id: uuid of the action
- :param category_id: uuid of the action category
- :param data_id: uuid of the action scope
- :param user_id: user ID who do the request
- :return: {
- "result": "True or False",
- "message": "optional message"
- }
- :internal_api: delete_action_assignment
- """
- return call("security_router", ctx={"id": uuid, "method": "delete_action_assignment", "perimeter_id": perimeter_id, "category_id": category_id, "user_id": user_id},
- args={"data_id": data_id})
diff --git a/moonv4/moon_interface/moon_interface/api/authz.py b/moonv4/moon_interface/moon_interface/api/authz.py
index 69de0f80..c9f4697f 100644
--- a/moonv4/moon_interface/moon_interface/api/authz.py
+++ b/moonv4/moon_interface/moon_interface/api/authz.py
@@ -6,23 +6,120 @@
Authz is the endpoint to get authorization response
"""
-from uuid import uuid4
-import time
+from flask import request
from flask_restful import Resource
-from oslo_log import log as logging
-from moon_utilities.security_functions import call
+import logging
+import pickle
+import requests
+import time
+from uuid import uuid4
+
+from moon_interface.authz_requests import AuthzRequest
__version__ = "0.1.0"
LOG = logging.getLogger("moon.interface.api." + __name__)
+def pdp_in_cache(cache, uuid):
+ """Check if a PDP exist with this Keystone Project ID in the cache of this component
+
+ :param cache: Cache to use
+ :param uuid: Keystone Project ID
+ :return: True or False
+ """
+ for item_uuid, item_value in cache.pdp.items():
+ if uuid == item_value['keystone_project_id']:
+ return item_uuid, item_value
+ return None, None
+
+
+def pdp_in_manager(cache, uuid):
+ """Check if a PDP exist with this Keystone Project ID in the Manager component
+
+ :param cache: Cache to use
+ :param uuid: Keystone Project ID
+ :return: True or False
+ """
+ cache.update()
+ return pdp_in_cache(cache, uuid)
+
+
+def container_exist(cache, uuid):
+ """Check if a PDP exist with this Keystone Project ID in the Manager component
+
+ :param cache: Cache to use
+ :param uuid: Keystone Project ID
+ :return: True or False
+ """
+ for key, value in cache.containers.items():
+ if "keystone_project_id" not in value:
+ continue
+ if value["keystone_project_id"] == uuid:
+ try:
+ req = requests.head("http://{}:{}/".format(
+ value.get("hostname"),
+ value.get("port")[0].get("PublicPort")))
+ LOG.info("container_exist {}".format(req.status_code))
+ if req.status_code in (200, 201):
+ return value
+ return
+ except requests.exceptions.ConnectionError:
+ pass
+ # maybe hostname is not working so trying with IP address
+ try:
+ req = requests.head("http://{}:{}/".format(
+ value.get("ip"),
+ value.get("port")[0].get("PublicPort")))
+ if req.status_code in (200, 201):
+ return value
+ return
+ except requests.exceptions.ConnectionError:
+ return
+
+
+def create_authz_request(cache, interface_name, manager_url, uuid, subject_name, object_name, action_name):
+ """Create the authorization request and make the first call to the Authz function
+
+ :param cache: Cache to use
+ :param interface_name: hostname of the interface
+ :param manager_url: URL of the manager
+ :param uuid: Keystone Project ID
+ :param subject_name: name of the subject
+ :param object_name: name of the object
+ :param action_name: name of the action
+ :return: Authorisation request
+ """
+ req_id = uuid4().hex
+ ctx = {
+ "project_id": uuid,
+ "subject_name": subject_name,
+ "object_name": object_name,
+ "action_name": action_name,
+ "request_id": req_id,
+ "interface_name": interface_name,
+ "manager_url": manager_url,
+ "cookie": uuid4().hex
+ }
+ cache.authz_requests[req_id] = AuthzRequest(ctx)
+ return cache.authz_requests[req_id]
+
+
class Authz(Resource):
"""
Endpoint for authz requests
"""
- __urls__ = ("/authz/<string:uuid>/<string:subject_name>/<string:object_name>/<string:action_name>", )
+ __urls__ = (
+ "/authz/<string:uuid>",
+ "/authz/<string:uuid>/<string:subject_name>/<string:object_name>/<string:action_name>",
+ )
+
+ def __init__(self, **kwargs):
+ self.CACHE = kwargs.get("cache")
+ self.INTERFACE_NAME = kwargs.get("interface_name", "interface")
+ self.MANAGER_URL = kwargs.get("manager_url", "http://manager:8080")
+ self.TIMEOUT = 5
def get(self, uuid=None, subject_name=None, object_name=None, action_name=None):
"""Get a response on an authorization request
@@ -51,17 +148,46 @@ class Authz(Resource):
}
:internal_api: authz
"""
- # Note (asteroide): user_id default to admin to be able to read the database
- # it would be better to have a read-only user.
- start_time = time.time()
- result = call("security_router", ctx={"id": uuid,
- "call_master": False,
- "method": "authz",
- "subject_name": subject_name,
- "object_name": object_name,
- "action_name": action_name,
- "user_id": "admin",
- "request_id": uuid4().hex}, args={})
- end_time = time.time()
- result['time'] = {"start": start_time, "end": end_time}
- return result
+ pdp_id, pdp_value = pdp_in_cache(self.CACHE, uuid)
+ if not pdp_id:
+ pdp_id, pdp_value = pdp_in_manager(self.CACHE, uuid)
+ if not pdp_id:
+ return {
+ "result": False,
+ "message": "Unknown Project ID or "
+ "Project ID is not bind to a PDP."}, 403
+ authz_request = create_authz_request(
+ cache=self.CACHE,
+ uuid=uuid,
+ interface_name=self.INTERFACE_NAME,
+ manager_url=self.MANAGER_URL,
+ subject_name=subject_name,
+ object_name=object_name,
+ action_name=action_name)
+ cpt = 0
+ while True:
+ if cpt > self.TIMEOUT*10:
+ return {"result": False,
+ "message": "Authz request had timed out."}, 500
+ if authz_request.is_authz():
+ if authz_request.final_result == "Grant":
+ return {"result": True, "message": ""}, 200
+ return {"result": False, "message": ""}, 401
+ cpt += 1
+ time.sleep(0.1)
+
+ def patch(self, uuid=None, subject_name=None, object_name=None, action_name=None):
+ """Get a response on an authorization request
+
+ :param uuid: uuid of the authorization request
+ :param subject_name: not used
+ :param object_name: not used
+ :param action_name: not used
+ :request body: a Context object
+ :return: {}
+ :internal_api: authz
+ """
+ if uuid in self.CACHE.authz_requests:
+ self.CACHE.authz_requests[uuid].set_result(pickle.loads(request.data))
+ return "", 201
+ return {"result": False, "message": "The request ID is unknown"}, 500
diff --git a/moonv4/moon_interface/moon_interface/api/data.py b/moonv4/moon_interface/moon_interface/api/data.py
deleted file mode 100644
index 6d959095..00000000
--- a/moonv4/moon_interface/moon_interface/api/data.py
+++ /dev/null
@@ -1,259 +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'.
-"""
-Data are elements used to create rules
-
-"""
-
-from flask import request
-from flask_restful import Resource
-from oslo_log import log as logging
-from moon_utilities.security_functions import call
-from moon_utilities.security_functions import check_auth
-
-__version__ = "0.2.0"
-
-LOG = logging.getLogger("moon.interface.api." + __name__)
-
-
-class SubjectData(Resource):
- """
- Endpoint for subject data requests
- """
-
- __urls__ = (
- "/policies/<string:uuid>/subject_data",
- "/policies/<string:uuid>/subject_data/",
- "/policies/<string:uuid>/subject_data/<string:category_id>",
- "/policies/<string:uuid>/subject_data/<string:category_id>/<string:data_id>",
- )
-
- @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 for a given policy
-
- :param uuid: uuid of the policy
- :param category_id: uuid of the subject category
- :param data_id: uuid of the subject data
- :param user_id: user ID who do the request
- :return: [{
- "policy_id": "policy_id1",
- "category_id": "category_id1",
- "data": {
- "subject_data_id": {
- "name": "name of the data",
- "description": "description of the data"
- }
- }
- }]
- :internal_api: get_subject_data
- """
- return call("security_router", ctx={"id": uuid, "method": "get_subject_data", "category_id": category_id, "user_id": user_id},
- args={"data_id": data_id})
-
- @check_auth
- def post(self, uuid=None, 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 user_id: user ID who do the request
- :request body: {
- "name": "name of the data",
- "description": "description of the data"
- }
- :return: {
- "policy_id": "policy_id1",
- "category_id": "category_id1",
- "data": {
- "subject_data_id": {
- "name": "name of the data",
- "description": "description of the data"
- }
- }
- }
- :internal_api: add_subject_data
- """
- return call("security_router", ctx={"id": uuid, "method": "add_subject_data", "category_id": category_id, "user_id": user_id},
- args=request.json)
-
- @check_auth
- def delete(self, uuid=None, category_id=None, data_id=None, user_id=None):
- """Delete a subject for a given policy
-
- :param uuid: uuid of the policy
- :param category_id: uuid of the subject category
- :param data_id: uuid of the subject data
- :param user_id: user ID who do the request
- :return: [{
- "result": "True or False",
- "message": "optional message"
- }]
- :internal_api: delete_subject_data
- """
- return call("security_router", ctx={"id": uuid, "method": "delete_subject_data", "category_id": category_id, "user_id": user_id},
- args={"data_id": data_id})
-
-
-class ObjectData(Resource):
- """
- Endpoint for object data requests
- """
-
- __urls__ = (
- "/policies/<string:uuid>/object_data",
- "/policies/<string:uuid>/object_data/",
- "/policies/<string:uuid>/object_data/<string:category_id>",
- "/policies/<string:uuid>/object_data/<string:category_id>/<string:data_id>",
- )
-
- @check_auth
- def get(self, uuid=None, 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
-
- :param uuid: uuid of the policy
- :param category_id: uuid of the object category
- :param data_id: uuid of the object data
- :param user_id: user ID who do the request
- :return: [{
- "policy_id": "policy_id1",
- "category_id": "category_id1",
- "data": {
- "object_data_id": {
- "name": "name of the data",
- "description": "description of the data"
- }
- }
- }]
- :internal_api: get_object_data
- """
- return call("security_router", ctx={"id": uuid, "method": "get_object_data", "category_id": category_id, "user_id": user_id},
- args={"data_id": data_id})
-
- @check_auth
- def post(self, uuid=None, 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 user_id: user ID who do the request
- :request body: {
- "name": "name of the data",
- "description": "description of the data"
- }
- :return: {
- "policy_id": "policy_id1",
- "category_id": "category_id1",
- "data": {
- "object_data_id": {
- "name": "name of the data",
- "description": "description of the data"
- }
- }
- }
- :internal_api: add_object_data
- """
- return call("security_router", ctx={"id": uuid, "method": "add_object_data", "category_id": category_id, "user_id": user_id}, args=request.json)
-
- @check_auth
- def delete(self, uuid=None, category_id=None, data_id=None, user_id=None):
- """Delete a object for a given policy
-
- :param uuid: uuid of the policy
- :param category_id: uuid of the object category
- :param data_id: uuid of the object data
- :param user_id: user ID who do the request
- :return: {
- "result": "True or False",
- "message": "optional message"
- }
- :internal_api: delete_object_data
- """
- return call("security_router", ctx={"id": uuid, "method": "delete_object_data", "category_id": category_id, "user_id": user_id},
- args={"data_id": data_id})
-
-
-class ActionData(Resource):
- """
- Endpoint for action data requests
- """
-
- __urls__ = (
- "/policies/<string:uuid>/action_data",
- "/policies/<string:uuid>/action_data/",
- "/policies/<string:uuid>/action_data/<string:category_id>",
- "/policies/<string:uuid>/action_data/<string:category_id>/<string:data_id>",
- )
-
- @check_auth
- def get(self, uuid=None, 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
-
- :param uuid: uuid of the policy
- :param category_id: uuid of the action category
- :param data_id: uuid of the action data
- :param user_id: user ID who do the request
- :return: [{
- "policy_id": "policy_id1",
- "category_id": "category_id1",
- "data": {
- "action_data_id": {
- "name": "name of the data",
- "description": "description of the data"
- }
- }
- }]
- :internal_api: get_action_data
- """
- return call("security_router", ctx={"id": uuid, "method": "get_action_data", "category_id": category_id, "user_id": user_id},
- args={"data_id": data_id})
-
- @check_auth
- def post(self, uuid=None, category_id=None, data_id=None, user_id=None):
- """Create or update a action.
-
- :param uuid: uuid of the policy
- :param category_id: uuid of the action category
- :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"
- }
- :return: {
- "policy_id": "policy_id1",
- "category_id": "category_id1",
- "data": {
- "action_data_id": {
- "name": "name of the data",
- "description": "description of the data"
- }
- }
- }
- :internal_api: add_action_data
- """
- return call("security_router", ctx={"id": uuid, "method": "add_action_data", "category_id": category_id, "user_id": user_id},
- args=request.json)
-
- @check_auth
- def delete(self, uuid=None, category_id=None, data_id=None, user_id=None):
- """Delete a action for a given policy
-
- :param uuid: uuid of the policy
- :param category_id: uuid of the action category
- :param data_id: uuid of the action data
- :param user_id: user ID who do the request
- :return: {
- "result": "True or False",
- "message": "optional message"
- }
- :internal_api: delete_action_data
- """
- return call("security_router", ctx={"id": uuid, "method": "delete_action_data", "category_id": category_id, "user_id": user_id},
- args={"data_id": data_id})
-
-
diff --git a/moonv4/moon_interface/moon_interface/api/generic.py b/moonv4/moon_interface/moon_interface/api/generic.py
index 80e8abff..702f33cf 100644
--- a/moonv4/moon_interface/moon_interface/api/generic.py
+++ b/moonv4/moon_interface/moon_interface/api/generic.py
@@ -7,8 +7,7 @@ Those API are helping API used to manage the Moon platform.
"""
from flask_restful import Resource, request
-from oslo_log import log as logging
-from moon_utilities.security_functions import call
+import logging
import moon_interface.api
from moon_utilities.security_functions import check_auth
@@ -36,7 +35,7 @@ class Status(Resource):
}
}
"""
- return call("security_router", method="get_status", ctx={"component_id": component_id})
+ raise NotImplemented
class Logs(Resource):
@@ -71,7 +70,7 @@ class Logs(Resource):
args["to"] = to_str
args["event_number"] = event_number
- return call("security_router", method="get_logs", ctx={"component_id": component_id}, args=args)
+ raise NotImplemented
class API(Resource):
@@ -130,22 +129,3 @@ class API(Resource):
return {"error": "Unknown endpoint_id {}".format(endpoint_id)}
return {group_id: api_desc[group_id]}
return api_desc
-
-
-class InternalAPI(Resource):
- """
- Endpoint for status requests
- """
-
- __urls__ = ("/internal_api", "/internal_api/", "/internal_api/<string:component_id>")
-
- def get(self, component_id=None, user_id=""):
- api_list = ("orchestrator", "security_router")
- if not component_id:
- return {"api": api_list}
- if component_id in api_list:
- api_desc = dict()
- api_desc["name"] = component_id
- api_desc["endpoints"] = call("security_router", component_id, {}, "list_api")
- return api_desc
-
diff --git a/moonv4/moon_interface/moon_interface/api/meta_data.py b/moonv4/moon_interface/moon_interface/api/meta_data.py
deleted file mode 100644
index 3c933759..00000000
--- a/moonv4/moon_interface/moon_interface/api/meta_data.py
+++ /dev/null
@@ -1,204 +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'.
-"""
-Meta Data are elements used to create Meta data (skeleton of security policies)
-
-"""
-
-from flask import request
-from flask_restful import Resource
-from oslo_log import log as logging
-from moon_utilities.security_functions import call
-from moon_utilities.security_functions import check_auth
-
-__version__ = "0.2.0"
-
-LOG = logging.getLogger("moon.interface.api." + __name__)
-
-
-class SubjectCategories(Resource):
- """
- Endpoint for subject categories requests
- """
-
- __urls__ = (
- "/subject_categories",
- "/subject_categories/",
- "/subject_categories/<string:category_id>",
- )
-
- @check_auth
- def get(self, category_id=None, user_id=None):
- """Retrieve all subject categories or a specific one
-
- :param category_id: uuid of the subject category
- :param user_id: user ID who do the request
- :return: {
- "subject_category_id": {
- "name": "name of the category",
- "description": "description of the category"
- }
- }
- :internal_api: get_subject_categories
- """
- return call("security_router", ctx={"method": "get_subject_categories", "user_id": user_id}, args={"category_id": category_id})
-
- @check_auth
- def post(self, category_id=None, user_id=None):
- """Create or update a subject category.
-
- :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"
- }
- :return: {
- "subject_category_id": {
- "name": "name of the category",
- "description": "description of the category"
- }
- }
- :internal_api: add_subject_category
- """
- return call("security_router", ctx={"method": "set_subject_category", "user_id": user_id}, args=request.json)
-
- @check_auth
- def delete(self, category_id=None, user_id=None):
- """Delete a subject category
-
- :param category_id: uuid of the subject category to delete
- :param user_id: user ID who do the request
- :return: {
- "result": "True or False",
- "message": "optional message"
- }
- :internal_api: delete_subject_category
- """
- return call("security_router", ctx={"method": "delete_subject_category", "user_id": user_id}, args={"category_id": category_id})
-
-
-class ObjectCategories(Resource):
- """
- Endpoint for object categories requests
- """
-
- __urls__ = (
- "/object_categories",
- "/object_categories/",
- "/object_categories/<string:category_id>",
- )
-
- @check_auth
- def get(self, category_id=None, user_id=None):
- """Retrieve all object categories or a specific one
-
- :param category_id: uuid of the object category
- :param user_id: user ID who do the request
- :return: {
- "object_category_id": {
- "name": "name of the category",
- "description": "description of the category"
- }
- }
- :internal_api: get_object_categories
- """
- return call("security_router", ctx={"method": "get_object_categories", "user_id": user_id}, args={"category_id": category_id})
-
- @check_auth
- def post(self, category_id=None, user_id=None):
- """Create or update a object category.
-
- :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"
- }
- :return: {
- "object_category_id": {
- "name": "name of the category",
- "description": "description of the category"
- }
- }
- :internal_api: add_object_category
- """
- return call("security_router", ctx={"method": "set_object_category", "user_id": user_id}, args=request.json)
-
- @check_auth
- def delete(self, category_id=None, user_id=None):
- """Delete an object category
-
- :param category_id: uuid of the object category to delete
- :param user_id: user ID who do the request
- :return: {
- "result": "True or False",
- "message": "optional message"
- }
- :internal_api: delete_object_category
- """
- return call("security_router", ctx={"method": "delete_object_category", "user_id": user_id}, args={"category_id": category_id})
-
-
-class ActionCategories(Resource):
- """
- Endpoint for action categories requests
- """
-
- __urls__ = (
- "/action_categories",
- "/action_categories/",
- "/action_categories/<string:category_id>",
- )
-
- @check_auth
- def get(self, category_id=None, user_id=None):
- """Retrieve all action categories or a specific one
-
- :param category_id: uuid of the action category
- :param user_id: user ID who do the request
- :return: {
- "action_category_id": {
- "name": "name of the category",
- "description": "description of the category"
- }
- }
- :internal_api: get_action_categories
- """
- return call("security_router", ctx={"method": "get_action_categories", "user_id": user_id}, args={"category_id": category_id})
-
- @check_auth
- def post(self, category_id=None, user_id=None):
- """Create or update an action category.
-
- :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"
- }
- :return: {
- "action_category_id": {
- "name": "name of the category",
- "description": "description of the category"
- }
- }
- :internal_api: add_action_category
- """
- return call("security_router", ctx={"method": "set_action_category", "user_id": user_id}, args=request.json)
-
- @check_auth
- def delete(self, category_id=None, user_id=None):
- """Delete an action
-
- :param category_id: uuid of the action category to delete
- :param user_id: user ID who do the request
- :return: {
- "result": "True or False",
- "message": "optional message"
- }
- :internal_api: delete_action_category
- """
- return call("security_router", ctx={"method": "delete_action_category", "user_id": user_id}, args={"category_id": category_id})
diff --git a/moonv4/moon_interface/moon_interface/api/meta_rules.py b/moonv4/moon_interface/moon_interface/api/meta_rules.py
deleted file mode 100644
index 85072243..00000000
--- a/moonv4/moon_interface/moon_interface/api/meta_rules.py
+++ /dev/null
@@ -1,138 +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'.
-"""
-Meta rules are skeleton for security policies
-
-"""
-
-from flask import request
-from flask_restful import Resource
-from oslo_log import log as logging
-from moon_utilities.security_functions import call
-from moon_utilities.security_functions import check_auth
-
-__version__ = "0.1.0"
-
-LOG = logging.getLogger("moon.interface.api." + __name__)
-
-
-class MetaRules(Resource):
- """
- Endpoint for meta rules requests
- """
-
- __urls__ = ("/meta_rules",
- "/meta_rules/",
- "/meta_rules/<string:meta_rule_id>",
- "/meta_rules/<string:meta_rule_id>/")
-
- @check_auth
- def get(self, meta_rule_id=None, user_id=None):
- """Retrieve all sub meta rules
-
- :param meta_rule_id: Meta rule algorithm ID
- :param user_id: user ID who do the request
- :return: {
- "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"],
- "action_categories": ["action_category_id1"]
- },
- }
- }
- :internal_api: get_meta_rules
- """
- return call("security_router", ctx={"method": "get_meta_rules",
- "user_id": user_id,
- "meta_rule_id": meta_rule_id}, args={})
-
- @check_auth
- def post(self, meta_rule_id=None, user_id=None):
- """Add a meta rule
-
- :param meta_rule_id: Meta rule ID
- :param user_id: user ID who do the request
- :request body: post = {
- "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": {
- "name": "name of the meta rule",
- "subject_categories": ["subject_category_id1", "subject_category_id2"],
- "object_categories": ["object_category_id1"],
- "action_categories": ["action_category_id1"]
- },
- }
- }
- :internal_api: add_meta_rules
- """
- return call("security_router", ctx={"method": "add_meta_rules",
- "user_id": user_id,
- "meta_rule_id": meta_rule_id}, args=request.json)
-
- @check_auth
- def patch(self, meta_rule_id=None, user_id=None):
- """Update a meta rule
-
- :param meta_rule_id: Meta rule ID
- :param user_id: user ID who do the request
- :request body: patch = {
- "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": {
- "name": "name of the meta rule",
- "subject_categories": ["subject_category_id1", "subject_category_id2"],
- "object_categories": ["object_category_id1"],
- "action_categories": ["action_category_id1"]
- },
- }
- }
- :internal_api: set_meta_rules
- """
- return call("security_router", ctx={"method": "set_meta_rules",
- "user_id": user_id,
- "meta_rule_id": meta_rule_id}, args=request.json)
-
- @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": {
- "name": "name of the meta rule",
- "subject_categories": ["subject_category_id1", "subject_category_id2"],
- "object_categories": ["object_category_id1"],
- "action_categories": ["action_category_id1"]
- },
- }
- }
- :internal_api: delete_meta_rules
- """
- return call("security_router", ctx={"method": "delete_meta_rules",
- "user_id": user_id,
- "meta_rule_id": meta_rule_id}, args=request.json)
-
-
diff --git a/moonv4/moon_interface/moon_interface/api/models.py b/moonv4/moon_interface/moon_interface/api/models.py
deleted file mode 100644
index f905db63..00000000
--- a/moonv4/moon_interface/moon_interface/api/models.py
+++ /dev/null
@@ -1,101 +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'.
-"""
-Models aggregate multiple meta rules
-"""
-
-from flask import request
-from flask_restful import Resource
-from oslo_log import log as logging
-from moon_utilities.security_functions import call
-from moon_utilities.security_functions import check_auth
-
-__version__ = "0.1.0"
-
-LOG = logging.getLogger("moon.interface.api." + __name__)
-
-
-class Models(Resource):
- """
- Endpoint for model requests
- """
-
- __urls__ = (
- "/models",
- "/models/",
- "/models/<string:uuid>",
- "/models/<string:uuid>/",
- )
-
- @check_auth
- def get(self, uuid=None, user_id=None):
- """Retrieve all models
-
- :param uuid: uuid of the model
- :param user_id: user ID who do the request
- :return: {
- "model_id1": {
- "name": "...",
- "description": "...",
- "meta_rules": ["meta_rule_id1", ]
- }
- }
- :internal_api: get_models
- """
- return call("security_router", ctx={"id": uuid, "method": "get_models", "user_id": user_id}, args={})
-
- @check_auth
- def post(self, uuid=None, user_id=None):
- """Create model.
-
- :param uuid: uuid of the model (not used here)
- :param user_id: user ID who do the request
- :request body: {
- "name": "...",
- "description": "...",
- "meta_rules": ["meta_rule_id1", ]
- }
- :return: {
- "model_id1": {
- "name": "...",
- "description": "...",
- "meta_rules": ["meta_rule_id1", ]
- }
- }
- :internal_api: add_model
- """
- return call("security_router", ctx={"id": uuid, "method": "add_model", "user_id": user_id}, args=request.json)
-
- @check_auth
- def delete(self, uuid=None, user_id=None):
- """Delete a model
-
- :param uuid: uuid of the model to delete
- :param user_id: user ID who do the request
- :return: {
- "result": "True or False",
- "message": "optional message"
- }
- :internal_api: delete_model
- """
- return call("security_router", ctx={"id": uuid, "method": "delete_model", "user_id": user_id}, args={})
-
- @check_auth
- def patch(self, uuid=None, user_id=None):
- """Update a model
-
- :param uuid: uuid of the model to update
- :param user_id: user ID who do the request
- :return: {
- "model_id1": {
- "name": "...",
- "description": "...",
- "meta_rules": ["meta_rule_id1", ]
- }
- }
- :internal_api: update_model
- """
- return call("security_router", ctx={"id": uuid, "method": "update_model", "user_id": user_id}, args=request.json)
-
diff --git a/moonv4/moon_interface/moon_interface/api/pdp.py b/moonv4/moon_interface/moon_interface/api/pdp.py
deleted file mode 100644
index 5316227b..00000000
--- a/moonv4/moon_interface/moon_interface/api/pdp.py
+++ /dev/null
@@ -1,106 +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'.
-"""
-PDP are Policy Decision Point.
-
-"""
-
-from flask import request
-from flask_restful import Resource
-from oslo_log import log as logging
-from moon_utilities.security_functions import call
-from moon_utilities.security_functions import check_auth
-
-__version__ = "0.1.0"
-
-LOG = logging.getLogger("moon.interface.api." + __name__)
-
-
-class PDP(Resource):
- """
- Endpoint for pdp requests
- """
-
- __urls__ = (
- "/pdp",
- "/pdp/",
- "/pdp/<string:uuid>",
- "/pdp/<string:uuid>/",
- )
-
- @check_auth
- def get(self, uuid=None, user_id=None):
- """Retrieve all pdp
-
- :param uuid: uuid of the pdp
- :param user_id: user ID who do the request
- :return: {
- "pdp_id1": {
- "name": "...",
- "security_pipeline": [...],
- "keystone_project_id": "keystone_project_id1",
- "description": "...",
- }
- }
- :internal_api: get_pdp
- """
- return call("security_router", ctx={"id": uuid, "method": "get_pdp", "user_id": user_id}, args={})
-
- @check_auth
- def post(self, uuid=None, user_id=None):
- """Create pdp.
-
- :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": "...",
- }
- :return: {
- "pdp_id1": {
- "name": "...",
- "security_pipeline": [...],
- "keystone_project_id": "keystone_project_id1",
- "description": "...",
- }
- }
- :internal_api: add_pdp
- """
- return call("security_router", ctx={"id": uuid, "method": "add_pdp", "user_id": user_id}, args=request.json)
-
- @check_auth
- def delete(self, uuid=None, 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"
- }
- :internal_api: delete_pdp
- """
- return call("security_router", ctx={"id": uuid, "method": "delete_pdp", "user_id": user_id}, args={})
-
- @check_auth
- def patch(self, uuid=None, 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": "...",
- }
- }
- :internal_api: update_pdp
- """
- return call("security_router", ctx={"id": uuid, "method": "update_pdp", "user_id": user_id}, args=request.json)
-
diff --git a/moonv4/moon_interface/moon_interface/api/perimeter.py b/moonv4/moon_interface/moon_interface/api/perimeter.py
deleted file mode 100644
index 177161f6..00000000
--- a/moonv4/moon_interface/moon_interface/api/perimeter.py
+++ /dev/null
@@ -1,312 +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'.
-"""
-* Subjects are the source of an action on an object (examples : users, virtual machines)
-* Objects are the destination of an action (examples virtual machines, virtual Routers)
-* Actions are what subject wants to do on an object
-"""
-
-from flask import request
-from flask_restful import Resource
-from oslo_log import log as logging
-from moon_utilities.security_functions import call
-from moon_utilities.security_functions import check_auth
-
-__version__ = "0.2.0"
-
-LOG = logging.getLogger("moon.interface.api." + __name__)
-
-
-class Subjects(Resource):
- """
- Endpoint for subjects requests
- """
-
- __urls__ = (
- "/subjects",
- "/subjects/",
- "/subjects/<string:perimeter_id>",
- "/policies/<string:uuid>/subjects",
- "/policies/<string:uuid>/subjects/",
- "/policies/<string:uuid>/subjects/<string:perimeter_id>",
- )
-
- @check_auth
- def get(self, uuid=None, perimeter_id=None, user_id=None):
- """Retrieve all subjects or a specific one if perimeter_id is given for a given policy
-
- :param uuid: uuid of the policy
- :param perimeter_id: uuid of the subject
- :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": "a description"
- }
- }
- :internal_api: get_subjects
- """
- return call("security_router", ctx={"id": uuid, "method": "get_subjects", "user_id": user_id}, args={"perimeter_id": perimeter_id})
-
- @check_auth
- def post(self, uuid=None, 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"
- }
- :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"
- }
- }
- :internal_api: set_subject
- """
- return call("security_router", ctx={"id": uuid, "method": "set_subject", "user_id": user_id, "perimeter_id": None},
- args=request.json)
-
- @check_auth
- def patch(self, uuid=None, 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"
- }
- :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"
- }
- }
- :internal_api: set_subject
- """
- return call("security_router", ctx={"id": uuid, "method": "set_subject", "user_id": user_id, "perimeter_id": perimeter_id},
- args=request.json)
-
- @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 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"
- }
- }
- :internal_api: delete_subject
- """
- return call("security_router", ctx={"id": uuid, "method": "delete_subject", "user_id": user_id}, args={"perimeter_id": perimeter_id})
-
-
-class Objects(Resource):
- """
- Endpoint for objects requests
- """
-
- __urls__ = (
- "/objects",
- "/objects/",
- "/objects/<string:perimeter_id>",
- "/policies/<string:uuid>/objects",
- "/policies/<string:uuid>/objects/",
- "/policies/<string:uuid>/objects/<string:perimeter_id>",
- )
-
- @check_auth
- def get(self, uuid=None, perimeter_id=None, user_id=None):
- """Retrieve all objects or a specific one if perimeter_id is given for a given policy
-
- :param uuid: uuid of the policy
- :param perimeter_id: uuid of the object
- :param user_id: user ID who do the request
- :return: {
- "object_id": {
- "name": "name of the object",
- "description": "description of the object"
- }
- }
- :internal_api: get_objects
- """
- return call("security_router", ctx={"id": uuid, "method": "get_objects", "user_id": user_id}, args={"perimeter_id": perimeter_id})
-
- @check_auth
- def post(self, uuid=None, 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"
- }
- :return: {
- "object_id": {
- "name": "name of the object",
- "description": "description of the object"
- }
- }
- :internal_api: set_object
- """
- return call("security_router", ctx={"id": uuid, "method": "set_object", "user_id": user_id, "perimeter_id": None},
- args=request.json)
-
- @check_auth
- def patch(self, uuid=None, 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"
- }
- :return: {
- "object_id": {
- "name": "name of the object",
- "description": "description of the object"
- }
- }
- :internal_api: set_object
- """
- return call("security_router", ctx={"id": uuid, "method": "set_object", "user_id": user_id, "perimeter_id": perimeter_id},
- args=request.json)
-
- @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 user_id: user ID who do the request
- :return: {
- "object_id": {
- "name": "name of the object",
- "description": "description of the object"
- }
- }
- :internal_api: delete_object
- """
- return call("security_router", ctx={"id": uuid, "method": "delete_object", "user_id": user_id}, args={"perimeter_id": perimeter_id})
-
-
-class Actions(Resource):
- """
- Endpoint for actions requests
- """
-
- __urls__ = (
- "/actions",
- "/actions/",
- "/actions/<string:perimeter_id>",
- "/policies/<string:uuid>/actions",
- "/policies/<string:uuid>/actions/",
- "/policies/<string:uuid>/actions/<string:perimeter_id>",
- )
-
- @check_auth
- def get(self, uuid=None, perimeter_id=None, user_id=None):
- """Retrieve all actions or a specific one if perimeter_id is given for a given policy
-
- :param uuid: uuid of the policy
- :param perimeter_id: uuid of the action
- :param user_id: user ID who do the request
- :return: {
- "action_id": {
- "name": "name of the action",
- "description": "description of the action"
- }
- }
- :internal_api: get_actions
- """
- return call("security_router", ctx={"id": uuid, "method": "get_actions", "user_id": user_id}, args={"perimeter_id": perimeter_id})
-
- @check_auth
- def post(self, uuid=None, 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"
- }
- :return: {
- "action_id": {
- "name": "name of the action",
- "description": "description of the action"
- }
- }
- :internal_api: set_action
- """
- return call("security_router", ctx={"id": uuid, "method": "set_action", "user_id": user_id, "perimeter_id": None},
- args=request.json)
-
- @check_auth
- def patch(self, uuid=None, 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"
- }
- :return: {
- "action_id": {
- "name": "name of the action",
- "description": "description of the action"
- }
- }
- :internal_api: set_action
- """
- return call("security_router", ctx={"id": uuid, "method": "set_action", "user_id": user_id, "perimeter_id": perimeter_id},
- args=request.json)
-
- @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 user_id: user ID who do the request
- :return: {
- "action_id": {
- "name": "name of the action",
- "description": "description of the action"
- }
- }
- :internal_api: delete_action
- """
- return call("security_router", ctx={"id": uuid, "method": "delete_action", "user_id": user_id}, args={"perimeter_id": perimeter_id})
diff --git a/moonv4/moon_interface/moon_interface/api/policies.py b/moonv4/moon_interface/moon_interface/api/policies.py
deleted file mode 100644
index 5a84b612..00000000
--- a/moonv4/moon_interface/moon_interface/api/policies.py
+++ /dev/null
@@ -1,106 +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'.
-"""
-Policies are instances of security models and implement security policies
-
-"""
-
-from flask import request
-from flask_restful import Resource
-from oslo_log import log as logging
-from moon_utilities.security_functions import call
-from moon_utilities.security_functions import check_auth
-
-__version__ = "0.1.0"
-
-LOG = logging.getLogger("moon.interface.api." + __name__)
-
-
-class Policies(Resource):
- """
- Endpoint for policy requests
- """
-
- __urls__ = (
- "/policies",
- "/policies/",
- "/policies/<string:uuid>",
- "/policies/<string:uuid>/",
- )
-
- @check_auth
- def get(self, uuid=None, user_id=None):
- """Retrieve all policies
-
- :param uuid: uuid of the policy
- :param user_id: user ID who do the request
- :return: {
- "policy_id1": {
- "name": "...",
- "model_id": "...",
- "genre": "...",
- "description": "...",
- }
- }
- :internal_api: get_policies
- """
- return call("security_router", ctx={"id": uuid, "method": "get_policies", "user_id": user_id}, args={})
-
- @check_auth
- def post(self, uuid=None, user_id=None):
- """Create policy.
-
- :param uuid: uuid of the policy (not used here)
- :param user_id: user ID who do the request
- :request body: {
- "name": "...",
- "model_id": "...",
- "genre": "...",
- "description": "...",
- }
- :return: {
- "policy_id1": {
- "name": "...",
- "model_id": "...",
- "genre": "...",
- "description": "...",
- }
- }
- :internal_api: add_policy
- """
- return call("security_router", ctx={"id": uuid, "method": "add_policy", "user_id": user_id}, args=request.json)
-
- @check_auth
- def delete(self, uuid=None, user_id=None):
- """Delete a policy
-
- :param uuid: uuid of the policy to delete
- :param user_id: user ID who do the request
- :return: {
- "result": "True or False",
- "message": "optional message"
- }
- :internal_api: delete_policy
- """
- return call("security_router", ctx={"id": uuid, "method": "delete_policy", "user_id": user_id}, args={})
-
- @check_auth
- def patch(self, uuid=None, user_id=None):
- """Update a policy
-
- :param uuid: uuid of the policy to update
- :param user_id: user ID who do the request
- :return: {
- "policy_id1": {
- "name": "...",
- "model_id": "...",
- "genre": "...",
- "description": "...",
- }
- }
- :internal_api: update_policy
- """
- return call("security_router", ctx={"id": uuid, "method": "update_policy", "user_id": user_id}, args=request.json)
-
diff --git a/moonv4/moon_interface/moon_interface/api/rules.py b/moonv4/moon_interface/moon_interface/api/rules.py
deleted file mode 100644
index 1111729c..00000000
--- a/moonv4/moon_interface/moon_interface/api/rules.py
+++ /dev/null
@@ -1,114 +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'.
-"""
-Rules (TODO)
-"""
-
-from flask import request
-from flask_restful import Resource
-from oslo_log import log as logging
-from moon_utilities.security_functions import call
-from moon_utilities.security_functions import check_auth
-
-__version__ = "0.1.0"
-
-LOG = logging.getLogger("moon.interface.api." + __name__)
-
-
-class Rules(Resource):
- """
- Endpoint for rules requests
- """
-
- __urls__ = ("/policies/<string:uuid>/rules",
- "/policies/<string:uuid>/rules/",
- "/policies/<string:uuid>/rules/<string:rule_id>",
- "/policies/<string:uuid>/rules/<string:rule_id>/",
- )
-
- @check_auth
- def get(self, uuid=None, rule_id=None, user_id=None):
- """Retrieve all rules or a specific one
-
- :param uuid: policy ID
- :param rule_id: rule ID
- :param user_id: user ID who do the request
- :return: {
- "rules": [
- "policy_id": "policy_id1",
- "meta_rule_id": "meta_rule_id1",
- "rule_id1": ["subject_data_id1", "object_data_id1", "action_data_id1"],
- "rule_id2": ["subject_data_id2", "object_data_id2", "action_data_id2"],
- ]
- }
- :internal_api: get_rules
- """
- return call("security_router", ctx={"id": uuid,
- "method": "get_rules",
- "user_id": user_id,
- "rule_id": rule_id}, args={})
-
- @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 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": (
- {"decision": "grant"},
- )
- "enabled": True
- }
- :return: {
- "rules": [
- "meta_rule_id": "meta_rule_id1",
- "rule_id1": {
- "rule": ["subject_data_id1", "object_data_id1", "action_data_id1"],
- "instructions": (
- {"decision": "grant"}, # "grant" to immediately exit,
- # "continue" to wait for the result of next policy
- # "deny" to deny the request
- )
- }
- "rule_id2": {
- "rule": ["subject_data_id2", "object_data_id2", "action_data_id2"],
- "instructions": (
- {
- "update": {
- "operation": "add", # operations may be "add" or "delete"
- "target": "rbac:role:admin" # add the role admin to the current user
- }
- },
- {"chain": {"name": "rbac"}} # chain with the policy named rbac
- )
- }
- ]
- }
- :internal_api: add_rule
- """
- return call("security_router", ctx={"id": uuid,
- "method": "add_rule",
- "user_id": user_id,
- "rule_id": rule_id}, args=request.json)
-
- @check_auth
- def delete(self, uuid=None, rule_id=None, user_id=None):
- """Delete one rule linked to a specific sub meta rule
-
- :param uuid: policy ID
- :param rule_id: rule ID
- :param user_id: user ID who do the request
- :return: { "result": true }
- :internal_api: delete_rule
- """
- return call("security_router", ctx={"id": uuid,
- "method": "delete_rule",
- "user_id": user_id,
- "rule_id": rule_id}, args={})
-
diff --git a/moonv4/moon_interface/moon_interface/authz_requests.py b/moonv4/moon_interface/moon_interface/authz_requests.py
new file mode 100644
index 00000000..c09ee957
--- /dev/null
+++ b/moonv4/moon_interface/moon_interface/authz_requests.py
@@ -0,0 +1,159 @@
+# Copyright 2015 Open Platform for NFV Project, Inc. and its contributors
+# This software is distributed under the terms and conditions of the 'Apache-2.0'
+# license which can be found in the file 'LICENSE' in this package distribution
+# or at 'http://www.apache.org/licenses/LICENSE-2.0'.
+
+import logging
+import itertools
+import pickle
+import requests
+from moon_utilities import configuration, exceptions
+from moon_utilities.security_functions import Context
+from moon_utilities.cache import Cache
+
+LOG = logging.getLogger("moon.interface.authz_requests")
+
+
+CACHE = Cache()
+CACHE.update()
+
+
+class AuthzRequest:
+
+ result = None
+ final_result = "Deny"
+ req_max_delay = 2
+
+ def __init__(self, ctx, args=None):
+ self.context = Context(ctx, CACHE)
+ self.args = args
+ self.request_id = ctx["request_id"]
+ if ctx['project_id'] not in CACHE.container_chaining:
+ raise exceptions.KeystoneProjectError("Unknown Project ID {}".format(ctx['project_id']))
+ self.container_chaining = CACHE.container_chaining[ctx['project_id']]
+ if len(self.container_chaining) == 0:
+ raise exceptions.MoonError('Void container chaining')
+ self.pdp_container = self.container_chaining[0]["container_id"]
+ self.run()
+
+ def run(self):
+ self.context.delete_cache()
+ req = None
+ try:
+ req = requests.post("http://{}:{}/authz".format(
+ self.container_chaining[0]["hostip"],
+ self.container_chaining[0]["port"],
+ ), data=pickle.dumps(self.context))
+ if req.status_code != 200:
+ raise exceptions.AuthzException(
+ "Receive bad response from Authz function "
+ "(with IP address - {})".format(
+ req.status_code
+ ))
+ except requests.exceptions.ConnectionError:
+ LOG.error("Cannot connect to {}".format(
+ "http://{}:{}/authz".format(
+ self.container_chaining[0]["hostip"],
+ self.container_chaining[0]["port"]
+ )))
+ except ValueError:
+ try:
+ req = requests.post("http://{}:{}/authz".format(
+ self.container_chaining[0]["hostname"],
+ self.container_chaining[0]["port"],
+ ), data=pickle.dumps(self.context))
+ if req.status_code != 200:
+ raise exceptions.AuthzException(
+ "Receive bad response from Authz function "
+ "(with hostname - {})".format(
+ req.status_code
+ ))
+ except requests.exceptions.ConnectionError:
+ LOG.error("Cannot connect to {}".format(
+ "http://{}:{}/authz".format(
+ self.container_chaining[0]["hostname"],
+ self.container_chaining[0]["port"]
+ )))
+ raise exceptions.AuthzException(
+ "Cannot connect to Authz function")
+ self.context.set_cache(CACHE)
+ if req and len(self.container_chaining) == 1:
+ self.result = pickle.loads(req.content)
+
+ # def __exec_next_state(self, rule_found):
+ # index = self.context.index
+ # current_meta_rule = self.context.headers[index]
+ # current_container = self.__get_container_from_meta_rule(current_meta_rule)
+ # current_container_genre = current_container["genre"]
+ # try:
+ # next_meta_rule = self.context.headers[index + 1]
+ # except IndexError:
+ # next_meta_rule = None
+ # if current_container_genre == "authz":
+ # if rule_found:
+ # return True
+ # pass
+ # if next_meta_rule:
+ # # next will be session if current is deny and session is unset
+ # if self.payload["authz_context"]['pdp_set'][next_meta_rule]['effect'] == "unset":
+ # return notify(
+ # request_id=self.payload["authz_context"]["request_id"],
+ # container_id=self.__get_container_from_meta_rule(next_meta_rule)['container_id'],
+ # payload=self.payload)
+ # # next will be delegation if current is deny and session is passed or deny and delegation is unset
+ # else:
+ # LOG.error("Delegation is not developed!")
+ #
+ # else:
+ # # else next will be None and the request is sent to router
+ # return self.__return_to_router()
+ # elif current_container_genre == "session":
+ # pass
+ # # next will be next container in headers if current is passed
+ # if self.payload["authz_context"]['pdp_set'][current_meta_rule]['effect'] == "passed":
+ # return notify(
+ # request_id=self.payload["authz_context"]["request_id"],
+ # container_id=self.__get_container_from_meta_rule(next_meta_rule)['container_id'],
+ # payload=self.payload)
+ # # next will be None if current is grant and the request is sent to router
+ # else:
+ # return self.__return_to_router()
+ # elif current_container_genre == "delegation":
+ # LOG.error("Delegation is not developed!")
+ # # next will be authz if current is deny
+ # # next will be None if current is grant and the request is sent to router
+
+ def set_result(self, result):
+ self.result = result
+
+ def is_authz(self):
+ if not self.result:
+ return False
+ authz_results = []
+ for key in self.result.pdp_set:
+ if "effect" in self.result.pdp_set[key]:
+ if self.result.pdp_set[key]["effect"] == "grant":
+ # the pdp is a authorization PDP and grant the request
+ authz_results.append(True)
+ elif self.result.pdp_set[key]["effect"] == "passed":
+ # the pdp is not a authorization PDP (session or delegation) and had run normally
+ authz_results.append(True)
+ elif self.result.pdp_set[key]["effect"] == "unset":
+ # the pdp is not a authorization PDP (session or delegation) and had not yep run
+ authz_results.append(True)
+ else:
+ # the pdp is (or not) a authorization PDP and had run badly
+ authz_results.append(False)
+ if list(itertools.accumulate(authz_results, lambda x, y: x & y))[-1]:
+ self.result.pdp_set["effect"] = "grant"
+ if self.result:
+ if self.result.pdp_set["effect"] == "grant":
+ self.final_result = "Grant"
+ return True
+ self.final_result = "Deny"
+ return True
+
+ # def notify(self, request_id, container_id, payload):
+ # LOG.info("notify {} {} {}".format(request_id, container_id, payload))
+ # # TODO: send the notification and wait for the result
+ # # req = requests.get()
diff --git a/moonv4/moon_interface/moon_interface/containers.py b/moonv4/moon_interface/moon_interface/containers.py
new file mode 100644
index 00000000..1ca76a2d
--- /dev/null
+++ b/moonv4/moon_interface/moon_interface/containers.py
@@ -0,0 +1,102 @@
+# Copyright 2017 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 docker
+import logging
+import re
+import requests
+import time
+from moon_utilities import configuration, exceptions
+
+__version__ = "0.1.0"
+
+LOG = logging.getLogger("moon.interface.container")
+
+
+class DockerManager:
+
+ def __init__(self):
+ docker_conf = configuration.get_configuration("docker")['docker']
+ self.docker = docker.DockerClient(base_url=docker_conf['url'])
+
+ def create_container(self, data):
+ """Create the container through the docker client
+
+ :param data: {
+ "name": "authz",
+ "hostname": "authz123456789",
+ "port": {
+ "PrivatePort": 8090,
+ "Type": "tcp",
+ "IP": "0.0.0.0",
+ "PublicPort": 8090
+ },
+ "keystone_project_id": "keystone_project_id1",
+ "pdp_id": "123456789",
+ "container_name": "wukongsun/moon_authz:v4.1"
+ }
+ :return: container output
+ """
+ output = self.docker.containers.run(
+ image=data.get("container_name"),
+ hostname=data.get("hostname", data.get("name"))[:63],
+ name=data.get("name"),
+ network='moon',
+ ports={'{}/{}'.format(
+ data.get("port").get("PrivatePort"),
+ data.get("port").get("Type")
+ ): int(data.get("port").get("PrivatePort"))},
+ environment={
+ "UUID": data.get("hostname"),
+ "BIND": data.get("port").get("IP"),
+ "TYPE": data.get("plugin_name"),
+ "PORT": data.get("port").get("PrivatePort"),
+ "PDP_ID": data.get("pdp_id"),
+ "META_RULE_ID": data.get("meta_rule_id"),
+ "KEYSTONE_PROJECT_ID": data.get("keystone_project_id"),
+ },
+ detach=True
+ )
+ try:
+ req = requests.head("http://{}:{}/".format(data.get("hostname"), data.get("port").get("PublicPort")))
+ except requests.exceptions.ConnectionError:
+ pass
+ else:
+ if req.status_code != 200:
+ raise exceptions.DockerError("Container {} is not running!".format(data.get("hostname")))
+ output.ip = "0.0.0.0"
+ return output
+
+ # Note: host is not reachable through hostname so trying to find th IP address
+ res = output.exec_run("ip addr")
+ find = re.findall("inet (\d+\.\d+\.\d+\.\d+)", res.decode("utf-8"))
+ ip = "127.0.0.1"
+ for ip in find:
+ if ip.startswith("127"):
+ continue
+ break
+ cpt = 0
+ while True:
+ try:
+ req = requests.head("http://{}:{}/".format(ip, data.get("port").get("PublicPort")))
+ except requests.exceptions.ConnectionError:
+ pass
+ else:
+ if req.status_code not in (200, 201):
+ LOG.error("url={}".format("http://{}:{}/".format(ip, data.get("port").get("PublicPort"))))
+ LOG.error("req={}".format(req))
+ raise exceptions.DockerError("Container {} is not running!".format(data.get("hostname")))
+ output.ip = ip
+ return output
+ finally:
+ cpt += 1
+ time.sleep(0.1)
+ if cpt > 20:
+ break
+ output.ip = ip
+ return output
+
+ def delete_container(self, uuid):
+ raise NotImplementedError
diff --git a/moonv4/moon_interface/moon_interface/http_server.py b/moonv4/moon_interface/moon_interface/http_server.py
index 046337a2..387699f8 100644
--- a/moonv4/moon_interface/moon_interface/http_server.py
+++ b/moonv4/moon_interface/moon_interface/http_server.py
@@ -3,23 +3,15 @@
# 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
+from flask import Flask, jsonify
from flask_cors import CORS, cross_origin
from flask_restful import Resource, Api
import logging
from moon_interface import __version__
from moon_interface.api.generic import Status, Logs, API
-from moon_interface.api.models import Models
-from moon_interface.api.policies import Policies
-from moon_interface.api.pdp import PDP
-from moon_interface.api.meta_rules import MetaRules
-from moon_interface.api.meta_data import SubjectCategories, ObjectCategories, ActionCategories
-from moon_interface.api.perimeter import Subjects, Objects, Actions
-from moon_interface.api.data import SubjectData, ObjectData, ActionData
-from moon_interface.api.assignments import SubjectAssignments, ObjectAssignments, ActionAssignments
-from moon_interface.api.rules import Rules
from moon_interface.api.authz import Authz
-from moon_utilities import exceptions
+from moon_interface.authz_requests import CACHE
+from moon_utilities import configuration, exceptions
logger = logging.getLogger("moon.interface.http")
@@ -68,13 +60,7 @@ class Server:
raise NotImplementedError()
__API__ = (
- Status, Logs, API,
- MetaRules, SubjectCategories, ObjectCategories, ActionCategories,
- Subjects, Objects, Actions,
- SubjectAssignments, ObjectAssignments, ActionAssignments,
- SubjectData, ObjectData, ActionData,
- Rules, Authz,
- Models, Policies, PDP
+ Status, Logs, API
)
@@ -106,24 +92,28 @@ 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.port = port
+ 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.__set_route()
- # self.__hook_errors()
+ self.__hook_errors()
- @self.app.errorhandler(exceptions.AuthException)
- def _auth_exception(error):
- return {"error": "Unauthorized"}, 401
+ # @self.app.errorhandler(exceptions.AuthException)
+ # def _auth_exception(error):
+ # return {"error": "Unauthorized"}, 401
def __hook_errors(self):
- # FIXME (dthom): it doesn't work
+
def get_404_json(e):
- return {"error": "Error", "code": 404, "description": 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 {"error": "Error", "code": 400, "description": 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)
@@ -132,7 +122,15 @@ class HTTPServer(Server):
for api in __API__:
self.api.add_resource(api, *api.__urls__)
+ self.api.add_resource(Authz, *Authz.__urls__,
+ resource_class_kwargs={
+ "cache": CACHE,
+ "interface_name": self.host,
+ "manager_url": "http://{}:{}".format(self.manager_hostname, self.manager_port),
+ }
+ )
def run(self):
- self.app.run(debug=True, host=self._host, port=self._port) # nosec
+ self.app.run(host=self._host, port=self._port) # nosec
+ # self.app.run(debug=True, host=self._host, port=self._port) # nosec
diff --git a/moonv4/moon_interface/moon_interface/server.py b/moonv4/moon_interface/moon_interface/server.py
index 711aa00a..7043e2f9 100644
--- a/moonv4/moon_interface/moon_interface/server.py
+++ b/moonv4/moon_interface/moon_interface/server.py
@@ -14,7 +14,6 @@ def main():
configuration.init_logging()
try:
conf = configuration.get_configuration("components/interface")
- LOG.debug("interface.conf={}".format(conf))
hostname = conf["components/interface"].get("hostname", "interface")
port = conf["components/interface"].get("port", 80)
bind = conf["components/interface"].get("bind", "127.0.0.1")
@@ -25,8 +24,11 @@ def main():
configuration.add_component(uuid="interface", name=hostname, port=port, bind=bind)
LOG.info("Starting server with IP {} on port {} bind to {}".format(hostname, port, bind))
server = HTTPServer(host=bind, port=port)
- server.run()
+ # LOG.info("Starting server")
+ # server = HTTPServer(host="0.0.0.0", port=8081)
+ return server
if __name__ == '__main__':
- main()
+ server = main()
+ server.run()
diff --git a/moonv4/moon_interface/requirements.txt b/moonv4/moon_interface/requirements.txt
index ee4b455e..36332aa4 100644
--- a/moonv4/moon_interface/requirements.txt
+++ b/moonv4/moon_interface/requirements.txt
@@ -1,9 +1,4 @@
-kombu !=4.0.1,!=4.0.0
-oslo.messaging
-oslo.config
-vine
flask
flask_restful
flask_cors
-babel
moon_utilities \ No newline at end of file
diff --git a/moonv4/moon_interface/tests/apitests/README.md b/moonv4/moon_interface/tests/apitests/README.md
deleted file mode 100644
index ef74a1e3..00000000
--- a/moonv4/moon_interface/tests/apitests/README.md
+++ /dev/null
@@ -1,33 +0,0 @@
-Test directory
-==============
-
-API tests
----------
-To test all interfaces, you can use :
-
-```bash
-$ cd moonv4/moon_interface/tests/apitests
-$ pytest
-============================================================================= test session starts ==============================================================================
-platform linux -- Python 3.5.2, pytest-3.0.7, py-1.4.33, pluggy-0.4.0
-rootdir: /home/vdsq3226/projets/opnfv/moonv4/moon_interface, inifile:
-collected 15 items
-
-test_models.py .....
-test_pdp.py .
-test_policies.py .........
-
-```
-
-Populate default variables for a particular demonstration
----------------------------------------------------------
-
-```bash
-$ cd moonv4/moon_interface/tests/apitests
-$ python3 populate_default_values.py scenario/rbac.py -v
-Loading: scenario/rbac.py
-2017-03-31 09:57:17,243 WARNING Creating model RBAC
-2017-03-31 09:57:17,507 WARNING Creating policy Multi policy example
-2017-03-31 09:57:18,690 WARNING Creating PDP pdp1
-
-``` \ No newline at end of file
diff --git a/moonv4/moon_interface/tests/apitests/plot_json.py b/moonv4/moon_interface/tests/apitests/plot_json.py
deleted file mode 100644
index f67f1d27..00000000
--- a/moonv4/moon_interface/tests/apitests/plot_json.py
+++ /dev/null
@@ -1,852 +0,0 @@
-import os
-import argparse
-import logging
-import json
-import glob
-import time
-import datetime
-import itertools
-import plotly
-from plotly.graph_objs import Scatter, Layout, Bar
-import plotly.figure_factory as ff
-
-
-logger = None
-
-
-def init():
- global logger
- commands = {
- "graph": write_graph,
- "digraph": write_distgraph,
- "average": write_average_graph,
- "latency": write_latency,
- "request_average": write_request_average,
- "throughput": write_throughput,
- "global_throughput": write_global_throughput,
- "parallel_throughput": write_parallel_throughput,
- }
- parser = argparse.ArgumentParser()
- parser.add_argument("command",
- help="Command to throw ({})".format(", ".join(commands.keys())))
- parser.add_argument("input", nargs="+", help="files to use with the form \"file1.json,file2.json,...\"")
- 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("--write", "-w", help="Write test data to a JSON file", default="/tmp/data.json")
- parser.add_argument("--legend", "-l", help="Set the legend (by default get from the file names)")
- parser.add_argument("--titles", "-t",
- help="Set the general title, x title and y title (ex: Title 1,Title X,Title Y)")
- # 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)
- parser.add_argument("--write-image", help="Write the graph to file IMAGE", dest="write_image")
- parser.add_argument("--write-html", help="Write the graph to HTML file HTML", dest="write_html", default="data.html")
- parser.add_argument("--plot-result",
- help="Use specific data like Grant or Deny responses "
- "('*' for all or 'Grant,Deny' to separate granted and denied responses)",
- dest="plot_result",
- default="*")
- args = parser.parse_args()
-
- FORMAT = '%(levelname)s %(message)s'
-
- if args.verbose:
- logging.basicConfig(
- format=FORMAT,
- level=logging.INFO)
- elif args.debug:
- logging.basicConfig(
- format=FORMAT,
- level=logging.DEBUG)
- else:
- logging.basicConfig(
- format=FORMAT,
- level=logging.WARNING)
-
- logger = logging.getLogger(__name__)
-
- # args.input = args.input[0]
- result_input = []
- for _input in args.input:
- if "*" in _input:
- filenames = glob.glob(_input)
- filenames.sort()
- result_input.append(",".join(filenames))
- else:
- result_input.append(_input)
- args.input = result_input
-
- if not args.legend:
- _legends = []
- for data in args.input:
- for filename in data.split(","):
- _legends.append(os.path.basename(filename).replace(".json", ""))
- args.legend = ",".join(_legends)
-
- return args, commands
-
-
-def __get_legends(legend_str, default_length=10):
- if "|" in legend_str:
- secondary_legend = legend_str.split("|")[1].split(",")
- else:
- secondary_legend = ["average"] * default_length
- _legends = legend_str.split("|")[0].split(",")
- return _legends, secondary_legend
-
-
-def get_delta_v1(time_data, result=None):
- time_delta = list()
- x_data = list()
- time_delta_sum1 = 0
- cpt = 0
- for key in time_data:
- if not result or 'result' not in time_data[key] or time_data[key]['result'].lower() == result.lower() or result == "*":
- time_delta.append(time_data[key]['delta'])
- time_delta_sum1 += time_data[key]['delta']
- if 'index' in time_data[key]:
- print("in index {}".format(time_data[key]['index']))
- x_data.append(time_data[key]['index'])
- else:
- x_data.append(cpt)
- cpt += 1
- time_delta_average1 = time_delta_sum1 / len(time_data.keys())
- return time_delta, time_delta_average1, x_data
-
-
-def get_delta_v2(time_data, result=None):
- time_delta = list()
- x_data = list()
- time_delta_sum1 = 0
- cpt = 0
- for item in time_data:
- if not result or 'result' not in item or item['result'].lower() == result.lower() or result == "*":
- time_delta.append(item['delta'])
- time_delta_sum1 += item['delta']
- x_data.append(cpt)
- cpt += 1
- time_delta_average1 = time_delta_sum1 / len(time_data)
- return time_delta, time_delta_average1, x_data
-
-
-def get_delta(time_data, result=None):
- if type(time_data) is dict:
- return get_delta_v1(time_data, result=result)
- if type(time_data) is list:
- return get_delta_v2(time_data, result=result)
- raise Exception("Time data has not a correct profile")
-
-
-def get_latency_v1(time_data, result=None):
- time_delta = list()
- time_delta_sum1 = 0
- for key in time_data:
- if not result or 'result' not in time_data[key] or time_data[key]['result'].lower() == result.lower() or result == "*":
- time_delta.append(1/time_data[key]['delta'])
- time_delta_sum1 += time_data[key]['delta']
- logger.debug("Adding {} {}".format(1/time_data[key]['delta'], time_data[key]['delta']))
- time_delta_average1 = time_delta_sum1 / len(time_data.keys())
- return time_delta, 1/time_delta_average1
-
-
-def get_latency_v2(time_data, result=None):
- time_delta = list()
- time_delta_sum1 = 0
- time_list = list()
- for item in time_data:
- if not result or 'result' not in item or item['result'].lower() == result.lower() or result == "*":
- time_delta.append(1/item['delta'])
- time_delta_sum1 += item['delta']
- time_list.append(item['end'])
- time_delta_average1 = time_delta_sum1 / len(time_data)
- return time_delta, 1/time_delta_average1, time_list
-
-
-def get_latency(time_data, result=None):
- if type(time_data) is dict:
- return get_latency_v1(time_data, result=result)
- if type(time_data) is list:
- return get_latency_v2(time_data, result=result)
- raise Exception("Time data has not a correct profile")
-
-
-def get_request_per_second_v1(time_data):
- result = {}
- _min = None
- _max = 0
- for key in time_data:
- start = str(time_data[key]['start']).split(".")[0]
- end = str(time_data[key]['end']).split(".")[0]
- middle = str(int((int(end) + int(start)) / 2))
- middle = end
- if not _min:
- _min = int(middle)
- if int(middle) < _min:
- _min = int(middle)
- if int(middle) > _max:
- _max = int(middle)
- if middle not in result:
- result[middle] = 1
- else:
- result[middle] += 1
- for cpt in range(_min+1, _max):
- if str(cpt) not in result:
- result[str(cpt)] = 0
- # result[str(cpt)] = (result[str(cpt - 1)] + result[str(cpt)]) / 2
- # result[str(cpt - 1)] = result[str(cpt)]
- return result
-
-
-def get_request_per_second_v2(time_data):
- result = {}
- _min = None
- _max = 0
- for item in time_data:
- start = str(item['start']).split(".")[0]
- end = str(item['end']).split(".")[0]
- middle = str(int((int(end) + int(start)) / 2))
- middle = end
- if not _min:
- _min = int(middle)
- if int(middle) < _min:
- _min = int(middle)
- if int(middle) > _max:
- _max = int(middle)
- if middle not in result:
- result[middle] = 1
- else:
- result[middle] += 1
- for cpt in range(_min+1, _max):
- if str(cpt) not in result:
- result[str(cpt)] = 0
- # result[str(cpt)] = (result[str(cpt - 1)] + result[str(cpt)]) / 2
- # result[str(cpt - 1)] = result[str(cpt)]
- return result
-
-
-def get_request_per_second(time_data):
- if type(time_data) is dict:
- return get_request_per_second_v1(time_data)
- if type(time_data) is list:
- return get_request_per_second_v2(time_data)
- raise Exception("Time data has not a correct profile")
-
-
-def write_graph(legend=None, input=None, image_file=None, html_file=None, plot_result="", title=None):
- logger.info("Writing graph")
- cpt_max = 0
- logger.debug("legend={}".format(legend))
- for data in input:
- cpt_max += len(data.split(","))
- legends, secondary_legend = __get_legends(legend, cpt_max)
- logger.debug("legends={}".format(legends))
- result_data = []
- cpt_input = 0
- for data in input:
- for _input in data.split(","):
- try:
- current_legend = legends.pop(0)
- except IndexError:
- current_legend = ""
- time_data = json.load(open(_input))
- time_delta, time_delta_average2, x_data = get_delta(time_data)
- for item in time_data:
- if type(time_data) is dict:
- time_delta.append(time_data[item]['delta'])
- else:
- time_delta.append(item['delta'])
- data = Scatter(
- x=x_data,
- y=time_delta,
- name=current_legend,
- line=dict(
- color="rgb({},{},{})".format(0, cpt_input * 255 / cpt_max, cpt_input * 255 / cpt_max),
- # shape='spline'
- )
- )
- result_data.append(data)
- data_a = Scatter(
- x=list(range(len(time_data))),
- y=[time_delta_average2 for x in range(len(time_data))],
- name=current_legend + " average",
- line=dict(
- color="rgb({},{},{})".format(255, cpt_input * 255 / cpt_max, cpt_input * 255 / cpt_max),
- # shape='spline'
- )
- )
- result_data.append(data_a)
- cpt_input += 1
-
- if image_file:
- plotly.offline.plot(
- {
- "data": result_data,
- "layout": Layout(
- title="Request times delta",
- xaxis=dict(title='Requests'),
- yaxis=dict(title='Request duration'),
- )
- },
- filename=html_file,
- image="svg",
- image_filename=image_file,
- image_height=1000,
- image_width=1200
- )
- else:
- plotly.offline.plot(
- {
- "data": result_data,
- "layout": Layout(
- title="Request times delta",
- xaxis=dict(title='Requests'),
- yaxis=dict(title='Request duration'),
- )
- },
- filename=html_file,
- )
- return 0
-
-
-def write_distgraph(legend=None, input=None, image_file=None, html_file=None, plot_result="", title=None):
-
- logger.info("Writing graph")
- _legends, secondary_legend = __get_legends(legend, len(input))
- result_data = []
- legends = []
-
- # FIXME: deals with multiple input
- input = input[0]
- for _input in input.split(","):
- logger.info("Analysing input {}".format(_input))
- current_legend = _legends.pop(0)
- for result in plot_result.split(","):
- time_data2 = json.load(open(_input))
- time_delta2, time_delta_average2, x_data = get_delta(time_data2, result=result)
- result_data.append(time_delta2)
- if result == "*":
- legends.append(current_legend)
- else:
- legends.append("{} ({})".format(current_legend, result))
-
- # Create distplot with custom bin_size
- if len(legends) < len(result_data):
- for _cpt in range(len(result_data)-len(legends)):
- legends.append("NC")
- fig = ff.create_distplot(result_data, legends, show_hist=False)
-
- # Plot!
- plotly.offline.plot(
- fig,
- # image="svg",
- # image_filename=image_file,
- # image_height=1000,
- # image_width=1200,
- filename=html_file
- )
- return 0
-
-
-def write_average_graph(legend=None, input=None, image_file=None, html_file=None, plot_result="", title=None):
-
- logger.info("Writing average graph")
- _legends, secondary_legend = __get_legends(legend, len(input))
- all_data = []
- legends = []
- legend_done = False
- html_file = "latency_" + html_file
-
- cpt_input = 0
- cpt_max = len(input)
- for data in input:
- result_data = []
- for _input in data.split(","):
- logger.info("Analysing input {}".format(_input))
- if not legend_done:
- current_legend = _legends.pop(0)
- for result in plot_result.split(","):
- time_data2 = json.load(open(_input))
- time_delta2, time_delta_average2 = get_delta(time_data2, result=result)
- result_data.append(time_delta_average2)
- if not legend_done and result == "*":
- legends.append(current_legend)
- elif not legend_done:
- legends.append("{} ({})".format(current_legend, result))
-
- if not legend_done:
- if len(legends) < len(result_data):
- for _cpt in range(len(result_data)-len(legends)):
- legends.append("NC")
-
- data = Scatter(
- x=legends,
- y=result_data,
- name=secondary_legend.pop(0),
- line=dict(
- color="rgb({},{},{})".format(158, cpt_input * 255 / cpt_max, cpt_input * 255 / cpt_max)
- )
- )
- all_data.append(data)
- legend_done = True
- cpt_input += 1
- if image_file:
- plotly.offline.plot(
- {
- "data": all_data,
- "layout": Layout(
- title="Latency",
- xaxis=dict(title='Request per second'),
- yaxis=dict(title='Request latency'),
- )
- },
- filename=html_file,
- image="svg",
- image_filename=image_file,
- image_height=1000,
- image_width=1200
- )
- else:
- plotly.offline.plot(
- {
- "data": all_data,
- "layout": Layout(
- title="Latency",
- xaxis=dict(title='Requests'),
- yaxis=dict(title='Request latency'),
- )
- },
- filename=html_file,
- )
- return 0
-
-
-def __get_titles(title):
- if title:
- titles = title.split(",")
- try:
- title_generic = titles[0]
- except IndexError:
- title_generic = ""
- try:
- title_x = titles[1]
- except IndexError:
- title_x = ""
- try:
- title_y = titles[2]
- except IndexError:
- title_y = ""
- else:
- title_generic = ""
- title_x = ""
- title_y = ""
- return title_generic, title_x, title_y
-
-
-def __get_time_axis(data):
- result_data = []
- start_time = None
- for item in data:
- if not start_time:
- start_time = item
- item = item - start_time
- millis = int(str(item).split('.')[-1][:6])
- t = time.gmtime(int(item))
- result_data.append(
- datetime.datetime(t.tm_year, t.tm_mon, t.tm_mday, t.tm_hour, t.tm_min, t.tm_sec, millis)
- )
- return result_data
-
-
-def write_latency(legend=None, input=None, image_file=None, html_file=None, plot_result="", title=None):
-
- logger.info("Writing latency graph")
- _legends, secondary_legend = __get_legends(legend, len(input))
- all_data = []
- legends = []
- legend_done = False
- html_file = "latency_" + html_file
- title_generic, title_x, title_y = __get_titles(title)
- cpt_input = 0
- cpt_max = len(input)
- for data in input:
- result_data = []
- for _input in data.split(","):
- logger.info("Analysing input {}".format(_input))
- if not legend_done:
- current_legend = _legends.pop(0)
- for result in plot_result.split(","):
- time_data2 = json.load(open(_input))
- time_delta2, time_delta_average2, x_data = get_latency(time_data2, result=result)
- result_data.append(time_delta_average2)
- if not legend_done and result == "*":
- legends.append(current_legend)
- elif not legend_done:
- legends.append("{} ({})".format(current_legend, result))
-
- if not legend_done:
- if len(legends) < len(result_data):
- for _cpt in range(len(result_data)-len(legends)):
- legends.append("NC")
-
- data = Scatter(
- x=legends,
- y=result_data,
- name=secondary_legend.pop(0),
- line=dict(
- color="rgb({},{},{})".format(158, cpt_input * 255 / cpt_max, cpt_input * 255 / cpt_max)
- )
- )
- all_data.append(data)
- legend_done = True
- cpt_input += 1
- if image_file:
- plotly.offline.plot(
- {
- "data": all_data,
- "layout": Layout(
- title=title_generic,
- xaxis=dict(title=title_x),
- yaxis=dict(title=title_y),
- )
- },
- filename=html_file,
- image="svg",
- image_filename=image_file,
- image_height=1000,
- image_width=1200
- )
- else:
- plotly.offline.plot(
- {
- "data": all_data,
- "layout": Layout(
- title=title_generic,
- xaxis=dict(title=title_x),
- yaxis=dict(title=title_y),
- font=dict(
- size=25
- )
- )
- },
- filename=html_file,
- )
- return 0
-
-
-def write_request_average(legend=None, input=None, image_file=None, html_file=None, plot_result="", title=None):
- logger.info("Writing average graph")
- _legends, secondary_legend = __get_legends(legend, len(input))
- result_data = []
- html_file = "request_average_" + html_file
-
- # FIXME: deals with multiple input
- input = input[0]
- for _input in input.split(","):
- logger.info("Analysing input {}".format(_input))
- current_legend = _legends.pop(0)
- time_data = json.load(open(_input))
- result = get_request_per_second(time_data)
- time_keys = list(result.keys())
- time_keys.sort()
- time_value = list(map(lambda x: result[x], time_keys))
- datetime_keys = list()
- for _time in time_keys:
- t = time.gmtime(int(_time))
- datetime_keys.append(datetime.datetime(t.tm_year, t.tm_mon, t.tm_mday, t.tm_hour, t.tm_min, t.tm_sec))
- data = Bar(
- x=datetime_keys,
- y=time_value,
- name=current_legend,
- )
- result_data.append(data)
- plotly.offline.plot(
- {
- "data": result_data,
- "layout": Layout(
- title="Request per second",
- xaxis=dict(title='Time'),
- yaxis=dict(title='Request number'),
- )
- },
- filename=html_file,
- )
-
-
-def write_throughput(legend=None, input=None, image_file=None, html_file=None, plot_result="", title=None):
- logger.info("Writing throughput graph")
- _legends, secondary_legend = __get_legends(legend, len(input))
- result_data = []
- html_file = "request_throughput_" + html_file
- title_generic, title_x, title_y = __get_titles(title)
-
- cpt_input = 0
- cpt_request = 0
- cpt_max = 0
- average_data_x = []
- average_data_y = []
- for _i in input:
- cpt_max += len(_i.split(","))
-
- for data in input:
- for _input in data.split(","):
- logger.info("Analysing input {}".format(_input))
- current_legend = _legends.pop(0)
- time_data = json.load(open(_input))
- result = get_request_per_second(time_data)
- time_keys = list(result.keys())
- time_keys.sort()
- time_value = list(map(lambda x: result[x], time_keys))
- index_list = list(map(lambda x: cpt_request + x, range(len(time_keys))))
- cpt_request += len(index_list)
- import itertools
- average_data_y.extend(
- [list(itertools.accumulate(result.values()))[-1]/len(result.values())]*len(result.values())
- )
- average_data_x.extend(index_list)
- data = Scatter(
- x=index_list,
- y=time_value,
- name=current_legend,
- line=dict(
- color="rgb({},{},{})".format(0, cpt_input*255/cpt_max, cpt_input*255/cpt_max)
- ),
- mode="lines+markers"
- )
- result_data.append(data)
- cpt_input += 1
- data = Scatter(
- x=average_data_x,
- y=average_data_y,
- name="Average",
- line=dict(
- color="rgb({},{},{})".format(255, 0, 0)
- ),
- mode="lines"
- )
- logger.debug(average_data_x)
- logger.debug(average_data_y)
- result_data.append(data)
- plotly.offline.plot(
- {
- "data": result_data,
- "layout": Layout(
- title=title_generic,
- xaxis=dict(title=title_x),
- yaxis=dict(title=title_y),
- font=dict(
- size=15
- )
- )
- },
- filename=html_file,
- )
-
-
-def write_global_throughput(legend=None, input=None, image_file=None, html_file=None, plot_result="", title=None):
- logger.info("Writing global throughput graph")
- _legends, secondary_legend = __get_legends(legend, len(input))
- result_data = []
- # html_file = "request_throughput_" + html_file
- title_generic, title_x, title_y = __get_titles(title)
-
- cpt_input = 0
- cpt_global = 0
- cpt_max = 0
- average_data_x = []
- final_time_data = None
- average_data_y = []
- continuous_data_x = []
- continuous_data_y = []
- for _i in input:
- cpt_max += len(_i.split(","))
-
- for data in input:
- for _input in data.split(","):
- logger.info("Analysing input {}".format(_input))
- # current_legend = _legends.pop(0)
- _time_data = json.load(open(_input))
- result, average, time_data = get_latency(_time_data, plot_result)
- if not final_time_data:
- final_time_data = time_data
- continuous_data_y.extend(result)
- cpt_global += len(result)
- _cpt = 0
- for item in result:
- if len(average_data_y) <= _cpt:
- average_data_y.append([item, ])
- average_data_x.append(_cpt)
- else:
- _list = average_data_y[_cpt]
- _list.append(item)
- average_data_y[_cpt] = _list
- _cpt += 1
- # time_keys = list(map(lambda x: x['url'], result))
- # time_keys.sort()
- # time_value = list(map(lambda x: result[x], time_keys))
- # index_list = list(map(lambda x: cpt_request + x, range(len(time_keys))))
- # cpt_request += len(index_list)
- # average_data_y.extend(
- # [list(itertools.accumulate(result.values()))[-1]/len(result.values())]*len(result.values())
- # )
- # average_data_x.extend(index_list)
- cpt_input += 1
- data_continuous = Scatter(
- x=list(range(len(continuous_data_y))),
- y=continuous_data_y,
- name="continuous_data_y",
- line=dict(
- color="rgb({},{},{})".format(0, 0, 255)
- ),
- mode="lines"
- )
- for index, item in enumerate(average_data_y):
- av = list(itertools.accumulate(item))[-1]/len(item)
- average_data_y[index] = av
-
- average_data = []
- for cpt in range(len(time_data)):
- average_data.append([average_data_y[cpt], time_data[cpt]])
-
- sorted(average_data, key=lambda x: x[1])
-
- average_data_x = []
- start_time = None
- for item in map(lambda x: x[1], average_data):
- if not start_time:
- start_time = item
- item = item - start_time
- millis = int(str(item).split('.')[-1][:6])
- t = time.gmtime(int(item))
- average_data_x.append(
- datetime.datetime(t.tm_year, t.tm_mon, t.tm_mday, t.tm_hour, t.tm_min, t.tm_sec, millis)
- )
-
- data_average = Scatter(
- x=average_data_x,
- y=list(map(lambda x: x[0], average_data)),
- name="Average",
- line=dict(
- color="rgb({},{},{})".format(0, 0, 255)
- ),
- mode="lines"
- )
- plotly.offline.plot(
- {
- "data": [data_average, ],
- "layout": Layout(
- title=title_generic,
- xaxis=dict(title=title_x),
- yaxis=dict(title=title_y),
- font=dict(
- size=15
- )
- )
- },
- filename="average_throughput_" + html_file,
- )
- plotly.offline.plot(
- {
- "data": [data_continuous, ],
- "layout": Layout(
- title=title_generic,
- xaxis=dict(title=title_x),
- yaxis=dict(title=title_y),
- font=dict(
- size=15
- )
- )
- },
- filename="continuous_throughput_" + html_file,
- )
-
-
-def write_parallel_throughput(legend=None, input=None, image_file=None, html_file=None, plot_result="", title=None):
- logger.info("Writing global throughput graph")
- _legends, secondary_legend = __get_legends(legend, len(input))
- result_data = []
- title_generic, title_x, title_y = __get_titles(title)
-
- cpt_input = 0
- cpt_global = 0
- cpt_max = 0
- overhead_data = []
- MAX = 60
- for _i in input:
- cpt_max += len(_i.split(","))
- for data in input:
- for _input in data.split(","):
- logger.info("Analysing input {}".format(_input))
- current_legend = _legends.pop(0)
- _time_data = json.load(open(_input))
- result, average, time_data = get_latency(_time_data, plot_result)
- result = result[:MAX]
- cpt_global += len(result)
- if not overhead_data:
- for _data in result:
- overhead_data.append(list())
- for _index, _data in enumerate(result):
- _item = overhead_data[_index]
- _item.append(_data)
- overhead_data[_index] = _item
-
- data_continuous = Scatter(
- x=__get_time_axis(time_data),
- # x=list(range(len(result))),
- y=result,
- name=current_legend,
- line=dict(
- color="rgb({},{},{})".format(0, cpt_input * 255 / cpt_max, cpt_input * 255 / cpt_max)
- ),
- mode="lines"
- )
- cpt_input += 1
- result_data.append(data_continuous)
-
- for _index, _data in enumerate(overhead_data):
- if len(_data) == 2:
- _item = overhead_data[_index]
- overhead_data[_index] = 1-_item[1]/_item[0]
- data_overhead = Scatter(
- x=__get_time_axis(time_data),
- # x=list(range(len(result))),
- y=overhead_data,
- name="Overhead",
- line=dict(
- color="rgb({},{},{})".format(255, 0, 0)
- ),
- mode="lines"
- )
- # result_data.append(data_overhead)
- plotly.offline.plot(
- {
- "data": result_data,
- "layout": Layout(
- title=title_generic,
- xaxis=dict(title=title_x),
- yaxis=dict(title=title_y),
- font=dict(
- size=20
- )
- )
- },
- filename="parallel_throughput_" + html_file,
- )
-
-
-def main():
- args, commands = init()
- if args.command in commands:
- commands[args.command](
- legend=args.legend,
- input=args.input,
- image_file=args.write_image,
- html_file=args.write_html,
- plot_result=args.plot_result,
- title=args.titles
- )
- else:
- logger.error("Unkwnon command: {}".format(args.command))
-
-
-if __name__ == "__main__":
- main()
diff --git a/moonv4/moon_interface/tests/apitests/scenario/delegation.py b/moonv4/moon_interface/tests/apitests/scenario/delegation.py
deleted file mode 100644
index 839e74ce..00000000
--- a/moonv4/moon_interface/tests/apitests/scenario/delegation.py
+++ /dev/null
@@ -1,40 +0,0 @@
-
-pdp_name = "pdp1"
-policy_name = "Delegation policy example"
-model_name = "Delegation"
-
-subjects = {"user0": "", }
-objects = {"user1": "", }
-actions = {"delegate": ""}
-
-subject_categories = {"subjectid": "", }
-object_categories = {"delegated": "", }
-action_categories = {"delegation-action": "", }
-
-subject_data = {"subjectid": {"user0": ""}}
-object_data = {"delegated": {"user1": ""}}
-action_data = {"delegation-action": {"delegate": ""}}
-
-subject_assignments = {"user0": {"subjectid": "user0"}}
-object_assignments = {"user1": {"delegated": "user1"}}
-action_assignments = {"delegate": {"delegation-action": "delegate"}}
-
-meta_rule = {
- "session": {"id": "", "value": ("subjectid", "delegated", "delegation-action")},
-}
-
-rules = {
- "session": (
- {
- "rule": ("user0", "user1", "delegate"),
- "instructions": (
- {
- "update": {"request:subject": "user1"} # update the current user with "user1"
- },
- {"chain": {"security_pipeline": "rbac"}}
- )
- },
- )
-}
-
-
diff --git a/moonv4/moon_interface/tests/apitests/scenario/rbac_large.py b/moonv4/moon_interface/tests/apitests/scenario/rbac_large.py
deleted file mode 100644
index ef5dd9b2..00000000
--- a/moonv4/moon_interface/tests/apitests/scenario/rbac_large.py
+++ /dev/null
@@ -1,233 +0,0 @@
-
-pdp_name = "pdp1"
-policy_name = "RBAC policy example"
-model_name = "RBAC"
-policy_genre = "authz"
-
-subjects = {
- "user0": "",
- "user1": "",
- "user2": "",
- "user3": "",
- "user4": "",
- "user5": "",
- "user6": "",
- "user7": "",
- "user8": "",
- "user9": "",
-}
-objects = {
- "vm0": "",
- "vm1": "",
- "vm2": "",
- "vm3": "",
- "vm4": "",
- "vm5": "",
- "vm6": "",
- "vm7": "",
- "vm8": "",
- "vm9": "",
-}
-actions = {
- "start": "",
- "stop": "",
- "pause": "",
- "unpause": "",
- "destroy": "",
-}
-
-subject_categories = {"role": "", }
-object_categories = {"id": "", }
-action_categories = {"action-type": "", }
-
-subject_data = {"role": {
- "admin": "",
- "employee": "",
- "dev1": "",
- "dev2": "",
- "*": ""
-}}
-object_data = {"id": {
- "vm0": "",
- "vm1": "",
- "vm2": "",
- "vm3": "",
- "vm4": "",
- "vm5": "",
- "vm6": "",
- "vm7": "",
- "vm8": "",
- "vm9": "",
- "*": ""
-}}
-action_data = {"action-type": {
- "vm-read": "",
- "vm-write": "",
- "*": ""
-}}
-
-subject_assignments = {
- "user0": ({"role": "employee"}, {"role": "*"}),
- "user1": ({"role": "employee"}, {"role": "*"}),
- "user2": ({"role": "dev1"}, {"role": "*"}),
- "user3": ({"role": "dev1"}, {"role": "*"}),
- "user4": ({"role": "dev1"}, {"role": "*"}),
- "user5": ({"role": "dev1"}, {"role": "*"}),
- "user6": ({"role": "dev2"}, {"role": "*"}),
- "user7": ({"role": "dev2"}, {"role": "*"}),
- "user8": ({"role": "dev2"}, {"role": "*"}),
- "user9": ({"role": "dev2"}, {"role": "*"}),
-}
-object_assignments = {
- "vm0": ({"id": "vm0"}, {"id": "*"}),
- "vm1": ({"id": "vm1"}, {"id": "*"}),
- "vm2": ({"id": "vm2"}, {"id": "*"}),
- "vm3": ({"id": "vm3"}, {"id": "*"}),
- "vm4": ({"id": "vm4"}, {"id": "*"}),
- "vm5": ({"id": "vm5"}, {"id": "*"}),
- "vm6": ({"id": "vm6"}, {"id": "*"}),
- "vm7": ({"id": "vm7"}, {"id": "*"}),
- "vm8": ({"id": "vm8"}, {"id": "*"}),
- "vm9": ({"id": "vm9"}, {"id": "*"}),
-}
-action_assignments = {
- "start": ({"action-type": "vm-write"}, {"action-type": "*"}),
- "stop": ({"action-type": "vm-write"}, {"action-type": "*"}),
- "pause": ({"action-type": "vm-read"}, {"action-type": "*"}),
- "unpause": ({"action-type": "vm-read"}, {"action-type": "*"}),
- "destroy": ({"action-type": "vm-write"}, {"action-type": "*"}),
-}
-
-meta_rule = {
- "rbac": {"id": "", "value": ("role", "id", "action-type")},
-}
-
-rules = {
- "rbac": (
- {
- "rule": ("admin", "vm0", "vm-read"),
- "instructions": (
- {"decision": "grant"},
- )
- },
- {
- "rule": ("admin", "vm0", "vm-write"),
- "instructions": (
- {"decision": "grant"},
- )
- },
- # Rules for grant all employee to do read actions to all VM except vm0
- {
- "rule": ("employee", "vm1", "vm-read"),
- "instructions": (
- {"decision": "grant"},
- )
- },
- {
- "rule": ("employee", "vm2", "vm-read"),
- "instructions": (
- {"decision": "grant"},
- )
- },
- {
- "rule": ("employee", "vm3", "vm-read"),
- "instructions": (
- {"decision": "grant"},
- )
- },
- {
- "rule": ("employee", "vm4", "vm-read"),
- "instructions": (
- {"decision": "grant"},
- )
- },
- {
- "rule": ("employee", "vm5", "vm-read"),
- "instructions": (
- {"decision": "grant"},
- )
- },
- {
- "rule": ("employee", "vm6", "vm-read"),
- "instructions": (
- {"decision": "grant"},
- )
- },
- {
- "rule": ("employee", "vm7", "vm-read"),
- "instructions": (
- {"decision": "grant"},
- )
- },
- {
- "rule": ("employee", "vm8", "vm-read"),
- "instructions": (
- {"decision": "grant"},
- )
- },
- {
- "rule": ("employee", "vm9", "vm-read"),
- "instructions": (
- {"decision": "grant"},
- )
- },
- # Rules for grant all dev1 to do read actions to some VM
- {
- "rule": ("dev1", "vm1", "vm-write"),
- "instructions": (
- {"decision": "grant"},
- )
- },
- {
- "rule": ("dev1", "vm2", "vm-write"),
- "instructions": (
- {"decision": "grant"},
- )
- },
- {
- "rule": ("dev1", "vm3", "vm-write"),
- "instructions": (
- {"decision": "grant"},
- )
- },
- {
- "rule": ("dev1", "vm4", "vm-write"),
- "instructions": (
- {"decision": "grant"},
- )
- },
- # Rules for grant all dev2 to do read actions to some VM
- {
- "rule": ("dev2", "vm5", "vm-write"),
- "instructions": (
- {"decision": "grant"},
- )
- },
- {
- "rule": ("dev2", "vm6", "vm-write"),
- "instructions": (
- {"decision": "grant"},
- )
- },
- {
- "rule": ("dev2", "vm7", "vm-write"),
- "instructions": (
- {"decision": "grant"},
- )
- },
- {
- "rule": ("dev2", "vm8", "vm-write"),
- "instructions": (
- {"decision": "grant"},
- )
- },
- {
- "rule": ("dev2", "vm9", "vm-write"),
- "instructions": (
- {"decision": "grant"},
- )
- },
- )
-}
-
-
diff --git a/moonv4/moon_interface/tests/apitests/scenario/rbac_mls.py b/moonv4/moon_interface/tests/apitests/scenario/rbac_mls.py
deleted file mode 100644
index 8a5362ea..00000000
--- a/moonv4/moon_interface/tests/apitests/scenario/rbac_mls.py
+++ /dev/null
@@ -1,50 +0,0 @@
-
-pdp_name = "pdp1"
-policy_name = "Multi policy example"
-model_name = "RBAC"
-
-subjects = {"user0": "", "user1": "", "user2": "", }
-objects = {"vm0": "", "vm1": "", }
-actions = {"start": "", "stop": ""}
-
-subject_categories = {"role": "", "subject-security-level": "", }
-object_categories = {"id": "", "object-security-level": "", }
-action_categories = {"action-type": "", }
-
-subject_data = {
- "role": {"admin": "", "employee": ""},
- "subject-security-level": {"low": "", "medium": "", "high": ""},
-}
-object_data = {
- "id": {"vm1": "", "vm2": ""},
- "object-security-level": {"low": "", "medium": "", "high": ""},
-}
-action_data = {"action-type": {"vm-action": "", "storage-action": "", }}
-
-subject_assignments = {
- "user0": {"role": "admin", "subject-security-level": "high"},
- "user1": {"role": "employee", "subject-security-level": "medium"},
-}
-object_assignments = {
- "vm0": {"id": "vm1", "object-security-level": "medium"},
- "vm1": {"id": "vm2", "object-security-level": "low"},
-}
-action_assignments = {
- "start": {"action-type": "vm-action"},
- "stop": {"action-type": "vm-action"}
-}
-
-meta_rule = {
- "rbac": {"id": "", "value": ("role", "id", "action-type")},
- "mls": {"id": "", "value": ("subject-security-level", "object-security-level", "action-type")},
-}
-
-rules = {
- "rbac": (
- ("admin", "vm1", "vm-action"),
- ),
- "mls": (
- ("high", "medium", "vm-action"),
- ("medium", "low", "vm-action"),
- )
-}
diff --git a/moonv4/moon_interface/tests/apitests/scenario/session.py b/moonv4/moon_interface/tests/apitests/scenario/session.py
deleted file mode 100644
index 97d7aec3..00000000
--- a/moonv4/moon_interface/tests/apitests/scenario/session.py
+++ /dev/null
@@ -1,60 +0,0 @@
-
-pdp_name = "pdp1"
-policy_name = "Session policy example"
-model_name = "Session"
-policy_genre = "session"
-
-subjects = {"user0": "", "user1": "", }
-objects = {"admin": "", "employee": "", }
-actions = {"activate": "", "deactivate": ""}
-
-subject_categories = {"subjectid": "", }
-object_categories = {"role": "", }
-action_categories = {"session-action": "", }
-
-subject_data = {"subjectid": {"user0": "", "user1": ""}}
-object_data = {"role": {"admin": "", "employee": "", "*": ""}}
-action_data = {"session-action": {"activate": "", "deactivate": "", "*": ""}}
-
-subject_assignments = {"user0": ({"subjectid": "user0"}, ), "user1": ({"subjectid": "user1"}, ), }
-object_assignments = {"admin": ({"role": "admin"}, {"role": "*"}),
- "employee": ({"role": "employee"}, {"role": "employee"})
- }
-action_assignments = {"activate": ({"session-action": "activate"}, {"session-action": "*"}, ),
- "deactivate": ({"session-action": "deactivate"}, {"session-action": "*"}, )
- }
-
-meta_rule = {
- "session": {"id": "", "value": ("subjectid", "role", "session-action")},
-}
-
-rules = {
- "session": (
- {
- "rule": ("user0", "employee", "*"),
- "instructions": (
- {
- "update": {
- "operation": "add",
- "target": "rbac:role:admin" # add the role admin to the current user
- }
- },
- {"chain": {"name": "rbac"}} # chain with the meta_rule named rbac
- )
- },
- {
- "rule": ("user1", "employee", "*"),
- "instructions": (
- {
- "update": {
- "operation": "delete",
- "target": "rbac:role:employee" # delete the role employee from the current user
- }
- },
- {"chain": {"name": "rbac"}} # chain with the meta_rule named rbac
- )
- },
- )
-}
-
-
diff --git a/moonv4/moon_interface/tests/apitests/scenario/session_large.py b/moonv4/moon_interface/tests/apitests/scenario/session_large.py
deleted file mode 100644
index 5b4a64b6..00000000
--- a/moonv4/moon_interface/tests/apitests/scenario/session_large.py
+++ /dev/null
@@ -1,389 +0,0 @@
-
-pdp_name = "pdp1"
-policy_name = "Session policy example"
-model_name = "Session"
-policy_genre = "session"
-
-subjects = {
- "user0": "",
- "user1": "",
- "user2": "",
- "user3": "",
- "user4": "",
- "user5": "",
- "user6": "",
- "user7": "",
- "user8": "",
- "user9": "",
-}
-objects = {"admin": "", "employee": "", "dev1": "", "dev2": "", }
-actions = {"activate": "", "deactivate": ""}
-
-subject_categories = {"subjectid": "", }
-object_categories = {"role": "", }
-action_categories = {"session-action": "", }
-
-subject_data = {"subjectid": {
- "user0": "",
- "user1": "",
- "user2": "",
- "user3": "",
- "user4": "",
- "user5": "",
- "user6": "",
- "user7": "",
- "user8": "",
- "user9": "",
-}}
-object_data = {"role": {
- "admin": "",
- "employee": "",
- "dev1": "",
- "dev2": "",
- "*": ""
-}}
-action_data = {"session-action": {"activate": "", "deactivate": "", "*": ""}}
-
-subject_assignments = {
- "user0": ({"subjectid": "user0"}, ),
- "user1": ({"subjectid": "user1"}, ),
- "user2": ({"subjectid": "user2"}, ),
- "user3": ({"subjectid": "user3"}, ),
- "user4": ({"subjectid": "user4"}, ),
- "user5": ({"subjectid": "user5"}, ),
- "user6": ({"subjectid": "user6"}, ),
- "user7": ({"subjectid": "user7"}, ),
- "user8": ({"subjectid": "user8"}, ),
- "user9": ({"subjectid": "user9"}, ),
-}
-object_assignments = {"admin": ({"role": "admin"}, {"role": "*"}),
- "employee": ({"role": "employee"}, {"role": "*"}),
- "dev1": ({"role": "employee"}, {"role": "dev1"}, {"role": "*"}),
- "dev2": ({"role": "employee"}, {"role": "dev2"}, {"role": "*"}),
- }
-action_assignments = {"activate": ({"session-action": "activate"}, {"session-action": "*"}, ),
- "deactivate": ({"session-action": "deactivate"}, {"session-action": "*"}, )
- }
-
-meta_rule = {
- "session": {"id": "", "value": ("subjectid", "role", "session-action")},
-}
-
-rules = {
- "session": (
- {
- "rule": ("user0", "employee", "*"),
- "instructions": (
- {
- "update": {
- "operation": "add",
- "target": "rbac:role:admin" # add the role admin to the current user
- }
- },
- {"chain": {"name": "rbac"}} # chain with the meta_rule named rbac
- )
- },
- {
- "rule": ("user1", "employee", "*"),
- "instructions": (
- {
- "update": {
- "operation": "delete",
- "target": "rbac:role:employee" # delete the role employee from the current user
- }
- },
- {"chain": {"name": "rbac"}} # chain with the meta_rule named rbac
- )
- },
- {
- "rule": ("user2", "employee", "*"),
- "instructions": (
- {
- "update": {
- "operation": "add",
- "target": "rbac:role:admin" # add the role admin to the current user
- }
- },
- {"chain": {"name": "rbac"}} # chain with the meta_rule named rbac
- )
- },
- {
- "rule": ("user2", "dev1", "*"),
- "instructions": (
- {
- "update": {
- "operation": "add",
- "target": "rbac:role:admin" # add the role admin to the current user
- }
- },
- {"chain": {"name": "rbac"}} # chain with the meta_rule named rbac
- )
- },
- {
- "rule": ("user2", "dev2", "*"),
- "instructions": (
- {
- "update": {
- "operation": "add",
- "target": "rbac:role:admin" # add the role admin to the current user
- }
- },
- {"chain": {"name": "rbac"}} # chain with the meta_rule named rbac
- )
- },
- {
- "rule": ("user3", "employee", "*"),
- "instructions": (
- {
- "update": {
- "operation": "add",
- "target": "rbac:role:admin" # add the role admin to the current user
- }
- },
- {"chain": {"name": "rbac"}} # chain with the meta_rule named rbac
- )
- },
- {
- "rule": ("user3", "dev1", "*"),
- "instructions": (
- {
- "update": {
- "operation": "add",
- "target": "rbac:role:admin" # add the role admin to the current user
- }
- },
- {"chain": {"name": "rbac"}} # chain with the meta_rule named rbac
- )
- },
- {
- "rule": ("user3", "dev2", "*"),
- "instructions": (
- {
- "update": {
- "operation": "add",
- "target": "rbac:role:admin" # add the role admin to the current user
- }
- },
- {"chain": {"name": "rbac"}} # chain with the meta_rule named rbac
- )
- },
- {
- "rule": ("user4", "employee", "*"),
- "instructions": (
- {
- "update": {
- "operation": "add",
- "target": "rbac:role:admin" # add the role admin to the current user
- }
- },
- {"chain": {"name": "rbac"}} # chain with the meta_rule named rbac
- )
- },
- {
- "rule": ("user4", "dev1", "*"),
- "instructions": (
- {
- "update": {
- "operation": "add",
- "target": "rbac:role:admin" # add the role admin to the current user
- }
- },
- {"chain": {"name": "rbac"}} # chain with the meta_rule named rbac
- )
- },
- {
- "rule": ("user4", "dev2", "*"),
- "instructions": (
- {
- "update": {
- "operation": "add",
- "target": "rbac:role:admin" # add the role admin to the current user
- }
- },
- {"chain": {"name": "rbac"}} # chain with the meta_rule named rbac
- )
- },
- {
- "rule": ("user5", "employee", "*"),
- "instructions": (
- {
- "update": {
- "operation": "add",
- "target": "rbac:role:admin" # add the role admin to the current user
- }
- },
- {"chain": {"name": "rbac"}} # chain with the meta_rule named rbac
- )
- },
- {
- "rule": ("user5", "dev1", "*"),
- "instructions": (
- {
- "update": {
- "operation": "add",
- "target": "rbac:role:admin" # add the role admin to the current user
- }
- },
- {"chain": {"name": "rbac"}} # chain with the meta_rule named rbac
- )
- },
- {
- "rule": ("user5", "dev2", "*"),
- "instructions": (
- {
- "update": {
- "operation": "add",
- "target": "rbac:role:admin" # add the role admin to the current user
- }
- },
- {"chain": {"name": "rbac"}} # chain with the meta_rule named rbac
- )
- },
- {
- "rule": ("user6", "employee", "*"),
- "instructions": (
- {
- "update": {
- "operation": "add",
- "target": "rbac:role:admin" # add the role admin to the current user
- }
- },
- {"chain": {"name": "rbac"}} # chain with the meta_rule named rbac
- )
- },
- {
- "rule": ("user6", "dev1", "*"),
- "instructions": (
- {
- "update": {
- "operation": "add",
- "target": "rbac:role:admin" # add the role admin to the current user
- }
- },
- {"chain": {"name": "rbac"}} # chain with the meta_rule named rbac
- )
- },
- {
- "rule": ("user6", "dev2", "*"),
- "instructions": (
- {
- "update": {
- "operation": "add",
- "target": "rbac:role:admin" # add the role admin to the current user
- }
- },
- {"chain": {"name": "rbac"}} # chain with the meta_rule named rbac
- )
- },
- {
- "rule": ("user7", "employee", "*"),
- "instructions": (
- {
- "update": {
- "operation": "add",
- "target": "rbac:role:admin" # add the role admin to the current user
- }
- },
- {"chain": {"name": "rbac"}} # chain with the meta_rule named rbac
- )
- },
- {
- "rule": ("user7", "dev1", "*"),
- "instructions": (
- {
- "update": {
- "operation": "add",
- "target": "rbac:role:admin" # add the role admin to the current user
- }
- },
- {"chain": {"name": "rbac"}} # chain with the meta_rule named rbac
- )
- },
- {
- "rule": ("user7", "dev2", "*"),
- "instructions": (
- {
- "update": {
- "operation": "add",
- "target": "rbac:role:admin" # add the role admin to the current user
- }
- },
- {"chain": {"name": "rbac"}} # chain with the meta_rule named rbac
- )
- },
- {
- "rule": ("user8", "employee", "*"),
- "instructions": (
- {
- "update": {
- "operation": "add",
- "target": "rbac:role:admin" # add the role admin to the current user
- }
- },
- {"chain": {"name": "rbac"}} # chain with the meta_rule named rbac
- )
- },
- {
- "rule": ("user8", "dev1", "*"),
- "instructions": (
- {
- "update": {
- "operation": "add",
- "target": "rbac:role:admin" # add the role admin to the current user
- }
- },
- {"chain": {"name": "rbac"}} # chain with the meta_rule named rbac
- )
- },
- {
- "rule": ("user8", "dev2", "*"),
- "instructions": (
- {
- "update": {
- "operation": "add",
- "target": "rbac:role:admin" # add the role admin to the current user
- }
- },
- {"chain": {"name": "rbac"}} # chain with the meta_rule named rbac
- )
- },
- {
- "rule": ("user9", "employee", "*"),
- "instructions": (
- {
- "update": {
- "operation": "add",
- "target": "rbac:role:admin" # add the role admin to the current user
- }
- },
- {"chain": {"name": "rbac"}} # chain with the meta_rule named rbac
- )
- },
- {
- "rule": ("user9", "dev1", "*"),
- "instructions": (
- {
- "update": {
- "operation": "add",
- "target": "rbac:role:admin" # add the role admin to the current user
- }
- },
- {"chain": {"name": "rbac"}} # chain with the meta_rule named rbac
- )
- },
- {
- "rule": ("user9", "dev2", "*"),
- "instructions": (
- {
- "update": {
- "operation": "add",
- "target": "rbac:role:admin" # add the role admin to the current user
- }
- },
- {"chain": {"name": "rbac"}} # chain with the meta_rule named rbac
- )
- },
- )
-}
-
-
diff --git a/moonv4/moon_interface/tests/apitests/set_authz.py b/moonv4/moon_interface/tests/apitests/set_authz.py
deleted file mode 100644
index 270c9de2..00000000
--- a/moonv4/moon_interface/tests/apitests/set_authz.py
+++ /dev/null
@@ -1,388 +0,0 @@
-import sys
-import argparse
-import logging
-import copy
-import threading
-from importlib.machinery import SourceFileLoader
-import itertools
-import requests
-import time
-import json
-import random
-import plotly
-from plotly.graph_objs import Scatter, Layout
-import plotly.figure_factory as ff
-from uuid import uuid4
-from utils.pdp import check_pdp
-
-
-logger = None
-HOST = None
-PORT = None
-HOST_AUTHZ = None
-PORT_AUTHZ = None
-
-lock = threading.Lock()
-
-
-def init():
- global logger, HOST, PORT, HOST_AUTHZ, PORT_AUTHZ
- parser = argparse.ArgumentParser()
- parser.add_argument('filename', help='scenario filename', nargs=1)
- parser.add_argument("--verbose", "-v", action='store_true', help="verbose mode")
- parser.add_argument("--debug", action='store_true', help="debug mode")
- parser.add_argument("--dry-run", "-n", action='store_true', help="Dry run", dest="dry_run")
- parser.add_argument("--host",
- help="Set the name of the host to test (default: 172.18.0.11).",
- default="172.18.0.11")
- parser.add_argument("--host-authz",
- help="Set the name of the host to test authorization (default: 172.18.0.11).",
- default="172.18.0.11",
- dest="host_authz")
- parser.add_argument("--port", "-p",
- help="Set the port of the host to test (default: 38001).",
- default="38001")
- parser.add_argument("--port-authz",
- help="Set the port of the host to test authorization (default: 38001).",
- default="38001",
- dest="port_authz")
- parser.add_argument("--test-only", "-t", action='store_true', dest='testonly', help="Do not generate graphs")
- 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("--input", "-i", help="Get data from a JSON input file")
- parser.add_argument("--legend", "-l", help="Set the legend (default: 'rbac,rbac+session')",
- default='rbac,rbac+session')
- # parser.add_argument("--distgraph", "-d",
- # help="Show a distribution graph instead of a linear graph",
- # action='store_true')
- 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)
- parser.add_argument("--write-image", help="Write the graph to file IMAGE", dest="write_image")
- parser.add_argument("--write-html", help="Write the graph to HTML file HTML", dest="write_html", default="data.html")
- 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)
-
- logger = logging.getLogger(__name__)
-
- requests_log = logging.getLogger("requests.packages.urllib3")
- requests_log.setLevel(logging.WARNING)
- requests_log.propagate = True
-
- if args.stress_test:
- args.testonly = True
-
- if args.filename:
- logger.info("Loading: {}".format(args.filename[0]))
-
- HOST = args.host
- PORT = args.port
- HOST_AUTHZ = args.host_authz
- PORT_AUTHZ = args.port_authz
- return args
-
-
-def get_scenario(args):
- m = SourceFileLoader("scenario", args.filename[0])
- return m.load_module()
-
-
-def get_keystone_id(pdp_name):
- keystone_project_id = None
- logger.error("get_keystone_id url={}".format("http://{}:{}".format(HOST, PORT)))
- for pdp_key, pdp_value in check_pdp(moon_url="http://{}:{}".format(HOST, PORT))["pdps"].items():
- logger.debug(pdp_value)
- if pdp_name:
- if pdp_name != pdp_value["name"]:
- continue
- if pdp_value['security_pipeline'] and pdp_value["keystone_project_id"]:
- logger.debug("Found pdp with keystone_project_id={}".format(pdp_value["keystone_project_id"]))
- keystone_project_id = pdp_value["keystone_project_id"]
-
- if not keystone_project_id:
- logger.error("Cannot find PDP with keystone project ID")
- sys.exit(1)
- return keystone_project_id
-
-
-def _send(url, stress_test=False):
- current_request = dict()
- current_request['url'] = url
- try:
- if stress_test:
- current_request['start'] = time.time()
- # with lock:
- res = requests.get(url)
- current_request['end'] = time.time()
- current_request['delta'] = current_request["end"] - current_request["start"]
- else:
- with lock:
- current_request['start'] = time.time()
- res = requests.get(url)
- current_request['end'] = time.time()
- current_request['delta'] = current_request["end"] - current_request["start"]
- except requests.exceptions.ConnectionError:
- logger.warning("Unable to connect to server")
- return {}
- if res and not stress_test:
- logger.debug(res.status_code)
- logger.debug(res.text)
- if res.status_code == 200:
- # logger.warning("error code 200 for {}".format(self.url))
- logger.info("\033[1m{}\033[m {}".format(url, res.status_code))
- try:
- j = res.json()
- except Exception as e:
- logger.debug(e)
- logger.error(res.text)
- else:
- if j.get("authz"):
- logger.warning("{} \033[32m{}\033[m".format(url, j.get("authz")))
- logger.debug("{}".format(j.get("error", "")))
- current_request['result'] = "Grant"
- else:
- logger.warning("{} \033[31m{}\033[m".format(url, j.get("authz")))
- logger.debug("{}".format(j.get("error", "")))
- current_request['result'] = "Deny"
- return current_request
-
-
-class AsyncGet(threading.Thread):
-
- def __init__(self, url, semaphore=None, *args, **kwargs):
- threading.Thread.__init__(self)
- self.url = url
- self.kwargs = kwargs
- self.sema = semaphore
- self.result = dict()
- self.uuid = uuid4().hex
- self.index = kwargs.get("index", 0)
-
- def run(self):
- self.result = _send(self.url, self.kwargs.get("stress_test", False))
- self.result['index'] = self.index
-
-
-def send_requests(scenario, keystone_project_id, request_second=1, limit=500,
- dry_run=None, stress_test=False):
- # sema = threading.BoundedSemaphore(value=request_second)
- backgrounds = []
- time_data = list()
- start_timing = time.time()
- request_cpt = 0
- indexes = []
- # rules = itertools.product(scenario.subjects.keys(), scenario.objects.keys(), scenario.actions.keys())
- SUBJECTS = tuple(scenario.subjects.keys())
- OBJECTS = tuple(scenario.objects.keys())
- ACTIONS = tuple(scenario.actions.keys())
- # for rule in rules:
- while request_cpt <= limit:
- rule = (random.choice(SUBJECTS), random.choice(OBJECTS), random.choice(ACTIONS))
- url = "http://{}:{}/authz/{}/{}".format(HOST_AUTHZ, PORT_AUTHZ, keystone_project_id, "/".join(rule))
- indexes.append(url)
- if dry_run:
- logger.info(url)
- continue
- request_cpt += 1
- if stress_test:
- time_data.append(copy.deepcopy(_send(url, stress_test=stress_test)))
- else:
- background = AsyncGet(url, stress_test=stress_test, index=request_cpt)
- backgrounds.append(background)
- background.start()
- # if limit and limit < request_cpt:
- # break
- if request_cpt % request_second == 0:
- if time.time()-start_timing < 1:
- while True:
- if time.time()-start_timing > 1:
- break
- start_timing = time.time()
- if not stress_test:
- for background in backgrounds:
- background.join()
- if background.result:
- time_data.append(copy.deepcopy(background.result))
- return time_data
-
-
-def save_data(filename, time_data):
- json.dump(time_data, open(filename, "w"))
-
-
-def get_delta(time_data):
- time_delta = list()
- time_delta_sum1 = 0
- for item in time_data:
- time_delta.append(item['delta'])
- time_delta_sum1 += item['delta']
- time_delta_average1 = time_delta_sum1 / len(time_data)
- return time_delta, time_delta_average1
-
-
-def write_graph(time_data, legend=None, input=None, image_file=None, html_file=None):
- logger.info("Writing graph")
- legends = legend.split(",")
- result_data = []
- time_delta, time_delta_average1 = get_delta(time_data)
- time_delta_average2 = None
- # if input:
- # for _input in input.split(","):
- # current_legend = legends.pop(0)
- # time_data2 = json.load(open(_input))
- # time_delta2, time_delta_average2 = get_delta(time_data2)
- # for item in time_data:
- # if key in time_data2:
- # time_delta2.append(time_data2[key]['delta'])
- # else:
- # time_delta2.append(None)
- # data2 = Scatter(
- # x=list(range(len(time_data))),
- # y=time_delta2,
- # name=current_legend,
- # line=dict(
- # color='rgb(255, 192, 118)',
- # shape='spline')
- # )
- # result_data.append(data2)
- # data2_a = Scatter(
- # x=list(range(len(time_data))),
- # y=[time_delta_average2 for x in range(len(time_data))],
- # name=current_legend + " average",
- # line=dict(
- # color='rgb(255, 152, 33)',
- # shape='spline')
- # )
- # result_data.append(data2_a)
- current_legend = legends.pop(0)
- data1 = Scatter(
- x=list(range(len(time_data))),
- y=time_delta,
- name=current_legend,
- line=dict(
- color='rgb(123, 118, 255)')
- )
- result_data.append(data1)
- data1_a = Scatter(
- x=list(range(len(time_data))),
- y=[time_delta_average1 for x in range(len(time_data))],
- name=current_legend + " average",
- line=dict(
- color='rgb(28, 20, 255)')
- )
- result_data.append(data1_a)
-
- if image_file:
- plotly.offline.plot(
- {
- "data": result_data,
- "layout": Layout(
- title="Request times delta",
- xaxis=dict(title='Requests'),
- yaxis=dict(title='Request duration'),
- )
- },
- filename=html_file,
- image="svg",
- image_filename=image_file,
- image_height=1000,
- image_width=1200
- )
- else:
- plotly.offline.plot(
- {
- "data": result_data,
- "layout": Layout(
- title="Request times delta",
- xaxis=dict(title='Requests'),
- yaxis=dict(title='Request duration'),
- )
- },
- filename=html_file,
- )
- if time_delta_average2:
- logger.info("Average: {} and {}".format(time_delta_average1, time_delta_average2))
- return 1-time_delta_average2/time_delta_average1
- return 0
-
-
-# def write_distgraph(time_data, legend=None, input=None, image_file=None, html_file=None):
-#
-# logger.info("Writing graph")
-# legends = legend.split(",")
-# result_data = []
-#
-# time_delta_average2 = None
-#
-# if input:
-# for _input in input.split(","):
-# logger.info("Analysing input {}".format(_input))
-# time_data2 = json.load(open(_input))
-# time_delta2, time_delta_average2 = get_delta(time_data2)
-# result_data.append(time_delta2)
-#
-# time_delta, time_delta_average1 = get_delta(time_data)
-# result_data.append(time_delta)
-#
-# # Create distplot with custom bin_size
-# if len(legends) < len(result_data):
-# for _cpt in range(len(result_data)-len(legends)):
-# legends.append("NC")
-# fig = ff.create_distplot(result_data, legends, bin_size=.2)
-#
-# # Plot!
-# plotly.offline.plot(
-# fig,
-# image="svg",
-# image_filename=image_file,
-# image_height=1000,
-# image_width=1200,
-# filename=html_file
-# )
-# if time_delta_average2:
-# logger.info("Average: {} and {}".format(time_delta_average1, time_delta_average2))
-# return 1-time_delta_average2/time_delta_average1
-# return 0
-
-
-def main():
- args = init()
- scenario = get_scenario(args)
- keystone_project_id = get_keystone_id(args.pdp)
- time_data = send_requests(
- scenario,
- keystone_project_id,
- request_second=args.request_second,
- limit=args.limit,
- dry_run=args.dry_run,
- stress_test=args.stress_test
- )
- if not args.dry_run:
- save_data(args.write, time_data)
- if not args.testonly:
- # if args.distgraph:
- # overhead = write_distgraph(time_data, legend=args.legend, input=args.input, image_file=args.write_image,
- # html_file=args.write_html)
- # else:
- overhead = write_graph(time_data, legend=args.legend, input=args.input, image_file=args.write_image,
- html_file=args.write_html)
- logger.info("Overhead: {:.2%}".format(overhead))
-
-
-if __name__ == "__main__":
- main()
diff --git a/moonv4/moon_interface/tests/apitests/test_models.py b/moonv4/moon_interface/tests/apitests/test_models.py
deleted file mode 100644
index 0da40ce5..00000000
--- a/moonv4/moon_interface/tests/apitests/test_models.py
+++ /dev/null
@@ -1,37 +0,0 @@
-from utils.models import *
-
-
-def test_models():
- check_model()
- model_id = add_model()
- check_model(model_id)
- delete_model(model_id)
-
-
-def test_meta_data_subject():
- category_id = add_subject_category()
- check_subject_category(category_id)
- # TODO (asteroide): must implement the deletion of linked data
- # delete_subject_category(category_id)
-
-
-def test_meta_data_object():
- category_id = add_object_category()
- check_object_category(category_id)
- # TODO (asteroide): must implement the deletion of linked data
- # delete_object_category(category_id)
-
-
-def test_meta_data_action():
- category_id = add_action_category()
- check_action_category(category_id)
- # TODO (asteroide): must implement the deletion of linked data
- # delete_action_category(category_id)
-
-
-def test_meta_rule():
- meta_rule_id, scat_id, ocat_id, acat_id = add_categories_and_meta_rule()
- check_meta_rule(meta_rule_id, scat_id, ocat_id, acat_id)
- delete_meta_rule(meta_rule_id)
-
-
diff --git a/moonv4/moon_interface/tests/apitests/test_pdp.py b/moonv4/moon_interface/tests/apitests/test_pdp.py
deleted file mode 100644
index 6cd5365b..00000000
--- a/moonv4/moon_interface/tests/apitests/test_pdp.py
+++ /dev/null
@@ -1,16 +0,0 @@
-from utils.pdp import *
-
-
-def test_pdp():
- 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
- check_pdp()
- pdp_id = add_pdp()
- check_pdp(pdp_id)
- map_to_keystone(pdp_id=pdp_id, keystone_project_id=admin_project_id)
- check_pdp(pdp_id=pdp_id, keystone_project_id=admin_project_id)
- delete_pdp(pdp_id)
diff --git a/moonv4/moon_interface/tests/apitests/test_policies.py b/moonv4/moon_interface/tests/apitests/test_policies.py
deleted file mode 100644
index 8f26d72d..00000000
--- a/moonv4/moon_interface/tests/apitests/test_policies.py
+++ /dev/null
@@ -1,157 +0,0 @@
-from utils.policies import *
-from utils.models import *
-
-
-def test_policies():
- check_policy()
- policy_id = add_policy()
- check_policy(policy_id)
- delete_policy(policy_id)
-
-
-def test_subjects():
- policy_id = add_policy()
- subject_id = add_subject()
-
- update_subject(subject_id=subject_id, policy_id=policy_id)
-
- check_subject(subject_id=subject_id, policy_id=policy_id)
-
- delete_subject(subject_id, policy_id=policy_id)
- delete_subject(subject_id)
-
-
-def test_objects():
- policy_id = add_policy()
- object_id = add_object()
-
- update_object(object_id=object_id, policy_id=policy_id)
- check_object(object_id=object_id, policy_id=policy_id)
-
- delete_object(object_id=object_id, policy_id=policy_id)
- delete_object(object_id=object_id)
-
-
-def test_actions():
- policy_id = add_policy()
- action_id = add_action()
-
- update_action(action_id=action_id, policy_id=policy_id)
- check_action(action_id=action_id, policy_id=policy_id)
-
- delete_action(action_id=action_id, policy_id=policy_id)
- delete_action(action_id=action_id)
-
-
-def test_subject_data():
- policy_id = add_policy()
-
- model_id = add_model()
-
- update_policy(policy_id, model_id)
-
- meta_rule_id, subject_cat_id, object_cat_id, action_cat_id = add_categories_and_meta_rule()
- add_meta_rule_to_model(model_id, meta_rule_id)
-
- subject_data_id = add_subject_data(policy_id=policy_id, category_id=subject_cat_id)
- check_subject_data(policy_id=policy_id, data_id=subject_data_id, category_id=subject_cat_id)
- delete_subject_data(policy_id=policy_id, data_id=subject_data_id, category_id=subject_cat_id)
-
-
-def test_object_data():
- policy_id = add_policy()
-
- model_id = add_model()
-
- update_policy(policy_id, model_id)
-
- meta_rule_id, object_cat_id, object_cat_id, action_cat_id = add_categories_and_meta_rule()
- add_meta_rule_to_model(model_id, meta_rule_id)
-
- 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)
-
-
-def test_action_data():
- policy_id = add_policy()
-
- model_id = add_model()
-
- update_policy(policy_id, model_id)
-
- meta_rule_id, action_cat_id, action_cat_id, action_cat_id = add_categories_and_meta_rule()
- add_meta_rule_to_model(model_id, meta_rule_id)
-
- action_data_id = add_action_data(policy_id=policy_id, category_id=action_cat_id)
- check_action_data(policy_id=policy_id, data_id=action_data_id, category_id=action_cat_id)
- delete_action_data(policy_id=policy_id, data_id=action_data_id, category_id=action_cat_id)
-
-
-def test_assignments():
- policy_id = add_policy()
-
- model_id = add_model()
-
- update_policy(policy_id, model_id)
-
- meta_rule_id, subject_cat_id, object_cat_id, action_cat_id = add_categories_and_meta_rule()
- add_meta_rule_to_model(model_id, meta_rule_id)
-
- subject_data_id = add_subject_data(policy_id=policy_id, category_id=subject_cat_id)
- subject_data_id_bis = add_subject_data(policy_id=policy_id, category_id=subject_cat_id)
- object_data_id = add_object_data(policy_id=policy_id, category_id=object_cat_id)
- object_data_id_bis = add_object_data(policy_id=policy_id, category_id=object_cat_id)
- action_data_id = add_action_data(policy_id=policy_id, category_id=action_cat_id)
- action_data_id_bis = add_action_data(policy_id=policy_id, category_id=action_cat_id)
-
- subject_id = add_subject(policy_id)
- object_id = add_object(policy_id)
- action_id = add_action(policy_id)
-
- add_subject_assignments(policy_id, subject_id, subject_cat_id, subject_data_id)
- add_subject_assignments(policy_id, subject_id, subject_cat_id, subject_data_id_bis)
- add_object_assignments(policy_id, object_id, object_cat_id, object_data_id)
- add_object_assignments(policy_id, object_id, object_cat_id, object_data_id_bis)
- add_action_assignments(policy_id, action_id, action_cat_id, action_data_id)
- add_action_assignments(policy_id, action_id, action_cat_id, action_data_id_bis)
-
- check_subject_assignments(policy_id, subject_id, subject_cat_id, subject_data_id)
- check_subject_assignments(policy_id, subject_id, subject_cat_id, subject_data_id_bis)
- check_object_assignments(policy_id, object_id, object_cat_id, object_data_id)
- check_object_assignments(policy_id, object_id, object_cat_id, object_data_id_bis)
- check_action_assignments(policy_id, action_id, action_cat_id, action_data_id)
- check_action_assignments(policy_id, action_id, action_cat_id, action_data_id_bis)
-
- delete_subject_assignment(policy_id, subject_id, subject_cat_id, subject_data_id)
- delete_object_assignment(policy_id, object_id, object_cat_id, object_data_id)
- delete_action_assignment(policy_id, action_id, action_cat_id, action_data_id)
-
-
-def test_rule():
- policy_id = add_policy()
-
- model_id = add_model()
-
- update_policy(policy_id, model_id)
-
- meta_rule_id, subject_cat_id, object_cat_id, action_cat_id = add_categories_and_meta_rule()
- add_meta_rule_to_model(model_id, meta_rule_id)
-
- subject_data_id = add_subject_data(policy_id=policy_id, category_id=subject_cat_id)
- object_data_id = add_object_data(policy_id=policy_id, category_id=object_cat_id)
- action_data_id = add_action_data(policy_id=policy_id, category_id=action_cat_id)
-
- subject_id = add_subject(policy_id)
- object_id = add_object(policy_id)
- action_id = add_action(policy_id)
-
- add_subject_assignments(policy_id, subject_id, subject_cat_id, subject_data_id)
- add_object_assignments(policy_id, object_id, object_cat_id, object_data_id)
- add_action_assignments(policy_id, action_id, action_cat_id, action_data_id)
-
- rule_id = add_rule(policy_id, meta_rule_id, [subject_data_id, object_data_id, action_data_id])
- check_rule(policy_id, meta_rule_id, rule_id, [subject_data_id, object_data_id, action_data_id])
-
- delete_rule(policy_id, rule_id)
-
diff --git a/moonv4/moon_consul/moon_consul/api/__init__.py b/moonv4/moon_interface/tests/unit_python/api/__init__.py
index e69de29b..e69de29b 100644
--- a/moonv4/moon_consul/moon_consul/api/__init__.py
+++ b/moonv4/moon_interface/tests/unit_python/api/__init__.py
diff --git a/moonv4/moon_interface/tests/unit_python/api/test_authz.py b/moonv4/moon_interface/tests/unit_python/api/test_authz.py
new file mode 100644
index 00000000..a63948f8
--- /dev/null
+++ b/moonv4/moon_interface/tests/unit_python/api/test_authz.py
@@ -0,0 +1,23 @@
+import json
+
+
+def get_json(data):
+ return json.loads(data.decode("utf-8"))
+
+
+def test_authz_true(context):
+ import moon_interface.server
+ server = moon_interface.server.main()
+ client = server.app.test_client()
+ req = client.get("/authz/{p_id}/{s_id}/{o_id}/{a_id}".format(
+ p_id=context["project_id"],
+ s_id=context["subject_name"],
+ o_id=context["object_name"],
+ a_id=context["action_name"],
+ ))
+ assert req.status_code == 200
+ data = get_json(req.data)
+ assert data
+ assert "result" in data
+ assert data['result'] == True
+
diff --git a/moonv4/moon_interface/tests/unit_python/conftest.py b/moonv4/moon_interface/tests/unit_python/conftest.py
new file mode 100644
index 00000000..7edcd32d
--- /dev/null
+++ b/moonv4/moon_interface/tests/unit_python/conftest.py
@@ -0,0 +1,678 @@
+import base64
+import json
+import os
+import pickle
+import pytest
+import requests_mock
+from uuid import uuid4
+from requests.packages.urllib3.response import HTTPResponse
+
+CONF = {
+ "openstack": {
+ "keystone": {
+ "url": "http://keystone:5000/v3",
+ "user": "admin",
+ "check_token": False,
+ "password": "p4ssw0rd",
+ "domain": "default",
+ "certificate": False,
+ "project": "admin"
+ }
+ },
+ "components": {
+ "wrapper": {
+ "bind": "0.0.0.0",
+ "port": 8080,
+ "container": "wukongsun/moon_wrapper:v4.3",
+ "timeout": 5,
+ "hostname": "wrapper"
+ },
+ "manager": {
+ "bind": "0.0.0.0",
+ "port": 8082,
+ "container": "wukongsun/moon_manager:v4.3",
+ "hostname": "manager"
+ },
+ "port_start": 31001,
+ "orchestrator": {
+ "bind": "0.0.0.0",
+ "port": 8083,
+ "container": "wukongsun/moon_orchestrator:v4.3",
+ "hostname": "orchestrator"
+ },
+ "interface": {
+ "bind": "0.0.0.0",
+ "port": 8080,
+ "container": "wukongsun/moon_interface:v4.3",
+ "hostname": "interface"
+ }
+ },
+ "plugins": {
+ "session": {
+ "port": 8082,
+ "container": "asteroide/session:latest"
+ },
+ "authz": {
+ "port": 8081,
+ "container": "wukongsun/moon_authz:v4.3"
+ }
+ },
+ "logging": {
+ "handlers": {
+ "file": {
+ "filename": "/tmp/moon.log",
+ "class": "logging.handlers.RotatingFileHandler",
+ "level": "DEBUG",
+ "formatter": "custom",
+ "backupCount": 3,
+ "maxBytes": 1048576
+ },
+ "console": {
+ "class": "logging.StreamHandler",
+ "formatter": "brief",
+ "level": "INFO",
+ "stream": "ext://sys.stdout"
+ }
+ },
+ "formatters": {
+ "brief": {
+ "format": "%(levelname)s %(name)s %(message)-30s"
+ },
+ "custom": {
+ "format": "%(asctime)-15s %(levelname)s %(name)s %(message)s"
+ }
+ },
+ "root": {
+ "handlers": [
+ "console"
+ ],
+ "level": "ERROR"
+ },
+ "version": 1,
+ "loggers": {
+ "moon": {
+ "handlers": [
+ "console",
+ "file"
+ ],
+ "propagate": False,
+ "level": "DEBUG"
+ }
+ }
+ },
+ "slave": {
+ "name": None,
+ "master": {
+ "url": None,
+ "login": None,
+ "password": None
+ }
+ },
+ "docker": {
+ "url": "tcp://172.88.88.1:2376",
+ "network": "moon"
+ },
+ "database": {
+ "url": "sqlite:///database.db",
+ # "url": "mysql+pymysql://moon:p4sswOrd1@db/moon",
+ "driver": "sql"
+ },
+ "messenger": {
+ "url": "rabbit://moon:p4sswOrd1@messenger:5672/moon"
+ }
+}
+
+COMPONENTS = (
+ "logging",
+ "openstack/keystone",
+ "database",
+ "slave",
+ "components/manager",
+ "components/orchestrator",
+ "components/interface",
+)
+
+CONTEXT = {
+ "project_id": "a64beb1cc224474fb4badd43173e7101",
+ "subject_name": "testuser",
+ "object_name": "vm1",
+ "action_name": "boot",
+ "request_id": uuid4().hex,
+ "interface_name": "interface",
+ "manager_url": "http://{}:{}".format(
+ CONF["components"]["manager"]["hostname"],
+ CONF["components"]["manager"]["port"]
+ ),
+ "cookie": uuid4().hex
+ }
+
+
+def get_b64_conf(component=None):
+ if component == "components":
+ return base64.b64encode(
+ json.dumps(CONF["components"]).encode('utf-8')+b"\n").decode('utf-8')
+ elif component in CONF:
+ return base64.b64encode(
+ json.dumps(
+ CONF[component]).encode('utf-8')+b"\n").decode('utf-8')
+ elif not component:
+ return base64.b64encode(
+ json.dumps(CONF).encode('utf-8')+b"\n").decode('utf-8')
+ elif "/" in component:
+ key1, _, key2 = component.partition("/")
+ return base64.b64encode(
+ json.dumps(
+ CONF[key1][key2]).encode('utf-8')+b"\n").decode('utf-8')
+
+
+MOCK_URLS = [
+ ('GET', 'http://consul:8500/v1/kv/components?recurse=true',
+ {'json': {"Key": key, "Value": get_b64_conf(key)}
+ for key in COMPONENTS}
+ ),
+ ('POST', 'http://keystone:5000/v3/auth/tokens',
+ {'headers': {'X-Subject-Token': "111111111"}}),
+ ('DELETE', 'http://keystone:5000/v3/auth/tokens',
+ {'headers': {'X-Subject-Token': "111111111"}}),
+ ('POST', 'http://keystone:5000/v3/users?name=testuser&domain_id=default',
+ {'json': {"users": {}}}),
+ ('GET', 'http://keystone:5000/v3/users?name=testuser&domain_id=default',
+ {'json': {"users": {}}}),
+ ('POST', 'http://keystone:5000/v3/users/',
+ {'json': {"users": [{
+ "id": "1111111111111"
+ }]}}),
+]
+
+
+@pytest.fixture
+def db():
+ return CONF['database']
+
+
+@pytest.fixture
+def context():
+ return CONTEXT
+
+
+def set_env_variables():
+ os.environ['UUID'] = "1111111111"
+ os.environ['TYPE'] = "authz"
+ os.environ['PORT'] = "8081"
+ os.environ['PDP_ID'] = "b3d3e18abf3340e8b635fd49e6634ccd"
+ os.environ['META_RULE_ID'] = "f8f49a779ceb47b3ac810f01ef71b4e0"
+ os.environ['KEYSTONE_PROJECT_ID'] = CONTEXT['project_id']
+
+
+def get_pickled_context():
+ from moon_utilities.security_functions import Context
+ from moon_utilities.cache import Cache
+ CACHE = Cache()
+ CACHE.update()
+ _context = Context(context(), CACHE)
+ _context.increment_index()
+ _context.pdp_set['effect'] = 'grant'
+ _context.pdp_set[os.environ['META_RULE_ID']]['effect'] = 'grant'
+ print(_context.pdp_set)
+ return pickle.dumps(_context)
+
+
+@pytest.fixture(autouse=True)
+def set_consul_and_db(monkeypatch):
+ """ Modify the response from Requests module
+ """
+ set_env_variables()
+ with requests_mock.Mocker(real_http=True) as m:
+ for component in COMPONENTS:
+ m.register_uri(
+ 'GET', 'http://consul:8500/v1/kv/{}'.format(component),
+ json=[{'Key': component, 'Value': get_b64_conf(component)}]
+ )
+ # for _data in MOCK_URLS:
+ # m.register_uri(_data[0], _data[1], **_data[2])
+ m.register_uri(
+ 'GET', 'http://consul:8500/v1/kv/components?recurse=true',
+ json=[
+ {"Key": key, "Value": get_b64_conf(key)} for key in COMPONENTS
+ ],
+ )
+ m.register_uri(
+ 'GET', 'http://consul:8500/v1/kv/plugins/authz',
+ json=[
+ {
+ "LockIndex": 0,
+ "Key": "plugins/authz",
+ "Flags": 0,
+ "Value": "eyJjb250YWluZXIiOiAid3Vrb25nc3VuL21vb25fYXV0aHo6djQuMyIsICJwb3J0IjogODA4MX0=",
+ "CreateIndex": 14,
+ "ModifyIndex": 656
+ }
+ ],
+ )
+ 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"
+ }]}
+ )
+ m.register_uri(
+ 'GET', 'http://orchestrator:8083/pods',
+ json={
+ "pods": {
+ "721760dd-de5f-11e7-8001-3863bbb766f3": [
+ {
+ "pdp_id": "b3d3e18abf3340e8b635fd49e6634ccd",
+ "port": 8080,
+ "genre": "interface",
+ "name": "interface-paltry",
+ "keystone_project_id": "a64beb1cc224474fb4badd43173e7101",
+ "namespace": "moon",
+ "container": "wukongsun/moon_interface:v4.3"
+ },
+ {
+ "pdp_id": "b3d3e18abf3340e8b635fd49e6634ccd",
+ "meta_rule_id": "f8f49a779ceb47b3ac810f01ef71b4e0",
+ "port": 8081,
+ "genre": "authz",
+ "name": "authz-economic",
+ "policy_id": "f8f49a779ceb47b3ac810f01ef71b4e0",
+ "keystone_project_id": "a64beb1cc224474fb4badd43173e7101",
+ "namespace": "moon",
+ "container": "wukongsun/moon_authz:v4.3"
+ }
+ ],
+ "232399a4-de5f-11e7-8001-3863bbb766f3": [
+ {
+ "port": 8080,
+ "namespace": "moon",
+ "name": "wrapper-paltry",
+ "container": "wukongsun/moon_wrapper:v4.3.1"
+ }
+ ]
+ }
+ }
+ )
+ m.register_uri(
+ 'GET', 'http://orchestrator:8083/pods/authz-economic',
+ json={
+ "pods": None
+ }
+ )
+ m.register_uri(
+ 'GET', 'http://manager:8082/pdp',
+ json={
+ "pdps": {
+ "b3d3e18abf3340e8b635fd49e6634ccd": {
+ "description": "test",
+ "security_pipeline": [
+ "f8f49a779ceb47b3ac810f01ef71b4e0"
+ ],
+ "name": "pdp_rbac",
+ "keystone_project_id": "a64beb1cc224474fb4badd43173e7101"
+ }
+ }
+ }
+ )
+ m.register_uri(
+ 'GET', 'http://manager:8082/policies',
+ json={
+ "policies": {
+ "f8f49a779ceb47b3ac810f01ef71b4e0": {
+ "name": "RBAC policy example",
+ "model_id": "cd923d8633ff4978ab0e99938f5153d6",
+ "description": "test",
+ "genre": "authz"
+ }
+ }
+ }
+ )
+ m.register_uri(
+ 'GET', 'http://manager:8082/models',
+ json={
+ "models": {
+ "cd923d8633ff4978ab0e99938f5153d6": {
+ "name": "RBAC",
+ "meta_rules": [
+ "f8f49a779ceb47b3ac810f01ef71b4e0"
+ ],
+ "description": "test"
+ }
+ }
+ }
+ )
+ m.register_uri(
+ 'GET', 'http://manager:8082/meta_rules',
+ json={
+ "meta_rules": {
+ "f8f49a779ceb47b3ac810f01ef71b4e0": {
+ "subject_categories": [
+ "14e6ae0ba34d458b876c791b73aa17bd"
+ ],
+ "action_categories": [
+ "241a2a791554421a91c9f1bc564aa94d"
+ ],
+ "description": "",
+ "name": "rbac",
+ "object_categories": [
+ "6d48500f639d4c2cab2b1f33ef93a1e8"
+ ]
+ }
+ }
+ }
+ )
+ m.register_uri(
+ 'GET', 'http://manager:8082/policies/f8f49a779ceb47b3ac810f01ef71b4e0/subjects',
+ json={
+ "subjects": {
+ "89ba91c18dd54abfbfde7a66936c51a6": {
+ "description": "test",
+ "policy_list": [
+ "f8f49a779ceb47b3ac810f01ef71b4e0",
+ "636cd473324f4c0bbd9102cb5b62a16d"
+ ],
+ "name": "testuser",
+ "email": "mail",
+ "id": "89ba91c18dd54abfbfde7a66936c51a6",
+ "partner_id": ""
+ },
+ "31fd15ad14784a9696fcc887dddbfaf9": {
+ "description": "test",
+ "policy_list": [
+ "f8f49a779ceb47b3ac810f01ef71b4e0",
+ "636cd473324f4c0bbd9102cb5b62a16d"
+ ],
+ "name": "adminuser",
+ "email": "mail",
+ "id": "31fd15ad14784a9696fcc887dddbfaf9",
+ "partner_id": ""
+ }
+ }
+ }
+ )
+ m.register_uri(
+ 'GET', 'http://manager:8082/policies/f8f49a779ceb47b3ac810f01ef71b4e0/objects',
+ json={
+ "objects": {
+ "67b8008a3f8d4f8e847eb628f0f7ca0e": {
+ "name": "vm1",
+ "description": "test",
+ "id": "67b8008a3f8d4f8e847eb628f0f7ca0e",
+ "partner_id": "",
+ "policy_list": [
+ "f8f49a779ceb47b3ac810f01ef71b4e0",
+ "636cd473324f4c0bbd9102cb5b62a16d"
+ ]
+ },
+ "9089b3d2ce5b4e929ffc7e35b55eba1a": {
+ "name": "vm0",
+ "description": "test",
+ "id": "9089b3d2ce5b4e929ffc7e35b55eba1a",
+ "partner_id": "",
+ "policy_list": [
+ "f8f49a779ceb47b3ac810f01ef71b4e0",
+ "636cd473324f4c0bbd9102cb5b62a16d"
+ ]
+ }
+ }
+ }
+ )
+ m.register_uri(
+ 'GET', 'http://manager:8082/policies/f8f49a779ceb47b3ac810f01ef71b4e0/actions',
+ json={
+ "actions": {
+ "cdb3df220dc05a6ea3334b994827b068": {
+ "name": "boot",
+ "description": "test",
+ "id": "cdb3df220dc04a6ea3334b994827b068",
+ "partner_id": "",
+ "policy_list": [
+ "f8f49a779ceb47b3ac810f01ef71b4e0",
+ "636cd473324f4c0bbd9102cb5b62a16d"
+ ]
+ },
+ "cdb3df220dc04a6ea3334b994827b068": {
+ "name": "stop",
+ "description": "test",
+ "id": "cdb3df220dc04a6ea3334b994827b068",
+ "partner_id": "",
+ "policy_list": [
+ "f8f49a779ceb47b3ac810f01ef71b4e0",
+ "636cd473324f4c0bbd9102cb5b62a16d"
+ ]
+ },
+ "9f5112afe9b34a6c894eb87246ccb7aa": {
+ "name": "start",
+ "description": "test",
+ "id": "9f5112afe9b34a6c894eb87246ccb7aa",
+ "partner_id": "",
+ "policy_list": [
+ "f8f49a779ceb47b3ac810f01ef71b4e0",
+ "636cd473324f4c0bbd9102cb5b62a16d"
+ ]
+ }
+ }
+ }
+ )
+ m.register_uri(
+ 'GET', 'http://manager:8082/policies/f8f49a779ceb47b3ac810f01ef71b4e0/subject_assignments',
+ json={
+ "subject_assignments": {
+ "826c1156d0284fc9b4b2ddb279f63c52": {
+ "category_id": "14e6ae0ba34d458b876c791b73aa17bd",
+ "assignments": [
+ "24ea95256c5f4c888c1bb30a187788df",
+ "6b227b77184c48b6a5e2f3ed1de0c02a",
+ "31928b17ec90438ba5a2e50ae7650e63",
+ "4e60f554dd3147af87595fb6b37dcb13",
+ "7a5541b63a024fa88170a6b59f99ccd7",
+ "dd2af27812f742029d289df9687d6126"
+ ],
+ "id": "826c1156d0284fc9b4b2ddb279f63c52",
+ "subject_id": "89ba91c18dd54abfbfde7a66936c51a6",
+ "policy_id": "f8f49a779ceb47b3ac810f01ef71b4e0"
+ },
+ "7407ffc1232944279b0cbcb0847c86f7": {
+ "category_id": "315072d40d774c43a89ff33937ed24eb",
+ "assignments": [
+ "6b227b77184c48b6a5e2f3ed1de0c02a",
+ "31928b17ec90438ba5a2e50ae7650e63",
+ "7a5541b63a024fa88170a6b59f99ccd7",
+ "dd2af27812f742029d289df9687d6126"
+ ],
+ "id": "7407ffc1232944279b0cbcb0847c86f7",
+ "subject_id": "89ba91c18dd54abfbfde7a66936c51a6",
+ "policy_id": "3e65256389b448cb9897917ea235f0bb"
+ }
+ }
+ }
+ )
+ m.register_uri(
+ 'GET', 'http://manager:8082/policies/f8f49a779ceb47b3ac810f01ef71b4e0/object_assignments',
+ json={
+ "object_assignments": {
+ "201ad05fd3f940948b769ab9214fe295": {
+ "object_id": "9089b3d2ce5b4e929ffc7e35b55eba1a",
+ "assignments": [
+ "030fbb34002e4236a7b74eeb5fd71e35",
+ "06bcb8655b9d46a9b90e67ef7c825b50",
+ "34eb45d7f46d4fb6bc4965349b8e4b83",
+ "4b7793dbae434c31a77da9d92de9fa8c"
+ ],
+ "id": "201ad05fd3f940948b769ab9214fe295",
+ "category_id": "6d48500f639d4c2cab2b1f33ef93a1e8",
+ "policy_id": "f8f49a779ceb47b3ac810f01ef71b4e0"
+ },
+ "90c5e86f8be34c0298fbd1973e4fb043": {
+ "object_id": "67b8008a3f8d4f8e847eb628f0f7ca0e",
+ "assignments": [
+ "a098918e915b4b12bccb89f9a3f3b4e4",
+ "06bcb8655b9d46a9b90e67ef7c825b50",
+ "7dc76c6142af47c88b60cc2b0df650ba",
+ "4b7793dbae434c31a77da9d92de9fa8c"
+ ],
+ "id": "90c5e86f8be34c0298fbd1973e4fb043",
+ "category_id": "33aece52d45b4474a20dc48a76800daf",
+ "policy_id": "3e65256389b448cb9897917ea235f0bb"
+ }
+ }
+ }
+ )
+ m.register_uri(
+ 'GET', 'http://manager:8082/policies/f8f49a779ceb47b3ac810f01ef71b4e0/action_assignments',
+ json={
+ "action_assignments": {
+ "2128e3ffbd1c4ef5be515d625745c2d4": {
+ "category_id": "241a2a791554421a91c9f1bc564aa94d",
+ "action_id": "cdb3df220dc05a6ea3334b994827b068",
+ "policy_id": "f8f49a779ceb47b3ac810f01ef71b4e0",
+ "id": "2128e3ffbd1c4ef5be515d625745c2d4",
+ "assignments": [
+ "570c036781e540dc9395b83098c40ba7",
+ "7fe17d7a2e3542719f8349c3f2273182",
+ "015ca6f40338422ba3f692260377d638",
+ "23d44c17bf88480f83e8d57d2aa1ea79"
+ ]
+ },
+ "cffb98852f3a4110af7a0ddfc4e19201": {
+ "category_id": "4a2c5abaeaf644fcaf3ca8df64000d53",
+ "action_id": "cdb3df220dc04a6ea3334b994827b068",
+ "policy_id": "3e65256389b448cb9897917ea235f0bb",
+ "id": "cffb98852f3a4110af7a0ddfc4e19201",
+ "assignments": [
+ "570c036781e540dc9395b83098c40ba7",
+ "7fe17d7a2e3542719f8349c3f2273182",
+ "015ca6f40338422ba3f692260377d638",
+ "23d44c17bf88480f83e8d57d2aa1ea79"
+ ]
+ }
+ }
+ }
+ )
+ m.register_uri(
+ 'GET', 'http://manager:8082/policies/f8f49a779ceb47b3ac810f01ef71b4e0/subject_assignments/89ba91c18dd54abfbfde7a66936c51a6',
+ json={
+ "subject_assignments": {
+ "826c1156d0284fc9b4b2ddb279f63c52": {
+ "category_id": "14e6ae0ba34d458b876c791b73aa17bd",
+ "assignments": [
+ "24ea95256c5f4c888c1bb30a187788df",
+ "6b227b77184c48b6a5e2f3ed1de0c02a",
+ "31928b17ec90438ba5a2e50ae7650e63",
+ "4e60f554dd3147af87595fb6b37dcb13",
+ "7a5541b63a024fa88170a6b59f99ccd7",
+ "dd2af27812f742029d289df9687d6126"
+ ],
+ "id": "826c1156d0284fc9b4b2ddb279f63c52",
+ "subject_id": "89ba91c18dd54abfbfde7a66936c51a6",
+ "policy_id": "f8f49a779ceb47b3ac810f01ef71b4e0"
+ }
+ }
+ }
+ )
+ m.register_uri(
+ 'GET', 'http://manager:8082/policies/f8f49a779ceb47b3ac810f01ef71b4e0/object_assignments/67b8008a3f8d4f8e847eb628f0f7ca0e',
+ json={
+ "object_assignments": {
+ "201ad05fd3f940948b769ab9214fe295": {
+ "object_id": "67b8008a3f8d4f8e847eb628f0f7ca0e",
+ "assignments": [
+ "030fbb34002e4236a7b74eeb5fd71e35",
+ "06bcb8655b9d46a9b90e67ef7c825b50",
+ "34eb45d7f46d4fb6bc4965349b8e4b83",
+ "4b7793dbae434c31a77da9d92de9fa8c"
+ ],
+ "id": "201ad05fd3f940948b769ab9214fe295",
+ "category_id": "6d48500f639d4c2cab2b1f33ef93a1e8",
+ "policy_id": "f8f49a779ceb47b3ac810f01ef71b4e0"
+ }
+ }
+ }
+ )
+ m.register_uri(
+ 'GET', 'http://manager:8082/policies/f8f49a779ceb47b3ac810f01ef71b4e0/action_assignments/cdb3df220dc05a6ea3334b994827b068',
+ json={
+ "action_assignments": {
+ "2128e3ffbd1c4ef5be515d625745c2d4": {
+ "category_id": "241a2a791554421a91c9f1bc564aa94d",
+ "action_id": "cdb3df220dc05a6ea3334b994827b068",
+ "policy_id": "f8f49a779ceb47b3ac810f01ef71b4e0",
+ "id": "2128e3ffbd1c4ef5be515d625745c2d4",
+ "assignments": [
+ "570c036781e540dc9395b83098c40ba7",
+ "7fe17d7a2e3542719f8349c3f2273182",
+ "015ca6f40338422ba3f692260377d638",
+ "23d44c17bf88480f83e8d57d2aa1ea79"
+ ]
+ }
+ }
+ }
+ )
+ m.register_uri(
+ 'GET', 'http://manager:8082/policies/f8f49a779ceb47b3ac810f01ef71b4e0/rules',
+ json={
+ "rules": {
+ "policy_id": "f8f49a779ceb47b3ac810f01ef71b4e0",
+ "rules": [
+ {
+ "policy_id": "f8f49a779ceb47b3ac810f01ef71b4e0",
+ "rule": [
+ "24ea95256c5f4c888c1bb30a187788df",
+ "030fbb34002e4236a7b74eeb5fd71e35",
+ "570c036781e540dc9395b83098c40ba7"
+ ],
+ "enabled": True,
+ "id": "0201a2bcf56943c1904dbac016289b71",
+ "instructions": [
+ {
+ "decision": "grant"
+ }
+ ],
+ "meta_rule_id": "f8f49a779ceb47b3ac810f01ef71b4e0"
+ },
+ {
+ "policy_id": "ecc2451c494e47b5bca7250cd324a360",
+ "rule": [
+ "54f574cd2043468da5d65e4f6ed6e3c9",
+ "6559686961a3490a978f246ac9f85fbf",
+ "ac0d1f600bf447e8bd2f37b7cc47f2dc"
+ ],
+ "enabled": True,
+ "id": "a83fed666af8436192dfd8b3c83a6fde",
+ "instructions": [
+ {
+ "decision": "grant"
+ }
+ ],
+ "meta_rule_id": "f8f49a779ceb47b3ac810f01ef71b4e0"
+ }
+ ]
+ }
+ }
+ )
+ m.register_uri(
+ 'POST', 'http://127.0.0.1:8081/authz',
+ content=get_pickled_context()
+ )
+ # from moon_db.db_manager import init_engine, run
+ # engine = init_engine()
+ # run("upgrade", logging.getLogger("db_manager"), engine)
+ yield m
+ # os.unlink(CONF['database']['url'].replace("sqlite:///", ""))
+
+
diff --git a/moonv4/moon_interface/tests/unit_python/requirements.txt b/moonv4/moon_interface/tests/unit_python/requirements.txt
new file mode 100644
index 00000000..8bd8449f
--- /dev/null
+++ b/moonv4/moon_interface/tests/unit_python/requirements.txt
@@ -0,0 +1,5 @@
+flask
+flask_cors
+flask_restful
+moon_db
+moon_utilities \ No newline at end of file
diff --git a/moonv4/moon_interface/tools/get_keystone_token.py b/moonv4/moon_interface/tools/get_keystone_token.py
index 63b0d0b6..a153f4db 100644
--- a/moonv4/moon_interface/tools/get_keystone_token.py
+++ b/moonv4/moon_interface/tools/get_keystone_token.py
@@ -1,7 +1,6 @@
import requests
from oslo_config import cfg
from oslo_log import log as logging
-from moon_utilities import options # noqa
from moon_utilities import exceptions
CONF = cfg.CONF
diff --git a/moonv4/moon_manager/Dockerfile b/moonv4/moon_manager/Dockerfile
index 3e1a65af..873e3aa2 100644
--- a/moonv4/moon_manager/Dockerfile
+++ b/moonv4/moon_manager/Dockerfile
@@ -6,6 +6,7 @@ RUN pip3 install pip --upgrade
ADD . /root
WORKDIR /root/
RUN pip3 install -r requirements.txt
+#RUN pip3 install /root/dist/* --upgrade
RUN pip3 install .
CMD ["python3", "-m", "moon_manager"] \ No newline at end of file
diff --git a/moonv4/moon_manager/LICENSE b/moonv4/moon_manager/LICENSE
index 4143aac2..d6456956 100644
--- a/moonv4/moon_manager/LICENSE
+++ b/moonv4/moon_manager/LICENSE
@@ -174,31 +174,29 @@
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
---- License for python-keystoneclient versions prior to 2.1 ---
-
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
-
- 1. Redistributions of source code must retain the above copyright notice,
- this list of conditions and the following disclaimer.
-
- 2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-
- 3. Neither the name of this project nor the names of its contributors may
- be used to endorse or promote products derived from this software without
- specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
-FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
-SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
-CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
-OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ END OF TERMS AND CONDITIONS
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright [yyyy] [name of copyright owner]
+
+ 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.
diff --git a/moonv4/moon_manager/moon_manager/__main__.py b/moonv4/moon_manager/moon_manager/__main__.py
index 0b264ce6..7d97f003 100644
--- a/moonv4/moon_manager/moon_manager/__main__.py
+++ b/moonv4/moon_manager/moon_manager/__main__.py
@@ -1,3 +1,4 @@
from moon_manager.server import main
-main()
+server = main()
+server.run()
diff --git a/moonv4/moon_manager/moon_manager/api/assignments.py b/moonv4/moon_manager/moon_manager/api/assignments.py
index bc585304..3bb6ed29 100644
--- a/moonv4/moon_manager/moon_manager/api/assignments.py
+++ b/moonv4/moon_manager/moon_manager/api/assignments.py
@@ -60,7 +60,7 @@ class SubjectAssignments(Resource):
except Exception as e:
LOG.error(e, exc_info=True)
return {"result": False,
- "error": str(e)}
+ "error": str(e)}, 500
return {"subject_assignments": data}
@check_auth
@@ -97,7 +97,7 @@ class SubjectAssignments(Resource):
except Exception as e:
LOG.error(e, exc_info=True)
return {"result": False,
- "error": str(e)}
+ "error": str(e)}, 500
return {"subject_assignments": data}
@check_auth
@@ -122,7 +122,7 @@ class SubjectAssignments(Resource):
except Exception as e:
LOG.error(e, exc_info=True)
return {"result": False,
- "error": str(e)}
+ "error": str(e)}, 500
return {"result": True}
@@ -164,7 +164,7 @@ class ObjectAssignments(Resource):
except Exception as e:
LOG.error(e, exc_info=True)
return {"result": False,
- "error": str(e)}
+ "error": str(e)}, 500
return {"object_assignments": data}
@check_auth
@@ -201,7 +201,7 @@ class ObjectAssignments(Resource):
except Exception as e:
LOG.error(e, exc_info=True)
return {"result": False,
- "error": str(e)}
+ "error": str(e)}, 500
return {"object_assignments": data}
@check_auth
@@ -226,7 +226,7 @@ class ObjectAssignments(Resource):
except Exception as e:
LOG.error(e, exc_info=True)
return {"result": False,
- "error": str(e)}
+ "error": str(e)}, 500
return {"result": True}
@@ -268,7 +268,7 @@ class ActionAssignments(Resource):
except Exception as e:
LOG.error(e, exc_info=True)
return {"result": False,
- "error": str(e)}
+ "error": str(e)}, 500
return {"action_assignments": data}
@check_auth
@@ -305,7 +305,7 @@ class ActionAssignments(Resource):
except Exception as e:
LOG.error(e, exc_info=True)
return {"result": False,
- "error": str(e)}
+ "error": str(e)}, 500
return {"action_assignments": data}
@check_auth
@@ -330,5 +330,5 @@ class ActionAssignments(Resource):
except Exception as e:
LOG.error(e, exc_info=True)
return {"result": False,
- "error": str(e)}
+ "error": str(e)}, 500
return {"result": True}
diff --git a/moonv4/moon_manager/moon_manager/api/containers.py b/moonv4/moon_manager/moon_manager/api/containers.py
new file mode 100644
index 00000000..44e7baac
--- /dev/null
+++ b/moonv4/moon_manager/moon_manager/api/containers.py
@@ -0,0 +1,179 @@
+# 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'.
+"""
+PDP are Policy Decision Point.
+
+"""
+
+import copy
+from docker import Client
+from flask import request
+from flask_restful import Resource
+from oslo_log import log as logging
+from moon_utilities.security_functions import check_auth
+from moon_db.core import PDPManager
+from moon_utilities import configuration, exceptions
+
+docker_conf = configuration.get_configuration("docker")['docker']
+docker = Client(base_url=docker_conf['url'])
+
+__version__ = "0.1.0"
+
+LOG = logging.getLogger("moon.manager.api." + __name__)
+
+
+class Container(Resource):
+ """
+ Endpoint for container requests
+ """
+
+ __urls__ = (
+ "/containers",
+ "/containers/",
+ "/containers/<string:uuid>",
+ "/containers/<string:uuid>/",
+ )
+
+ def __init__(self):
+ self.containers = {}
+ self.update()
+
+ def update(self):
+ for _container in docker.containers():
+ if _container['Id'] not in self.containers:
+ self.containers[_container['Id']] = {
+ "name": _container["Names"],
+ "port": _container["Ports"],
+ }
+
+ @check_auth
+ def get(self, uuid=None, user_id=None):
+ """Retrieve all containers
+
+ :param uuid: uuid of the container
+ :param user_id: user ID who do the request
+ :return: {
+ "containers": {
+ "da0fd80fc1dc146e1b...a2e07d240cde09f0a": {
+ "name": [
+ "/wrapper"
+ ],
+ "port": [
+ {
+ "PrivatePort": 8080,
+ "Type": "tcp",
+ "IP": "0.0.0.0",
+ "PublicPort": 8080
+ }
+ ]
+ },
+ }
+ }
+ :internal_api: get_containers
+ """
+ # try:
+ # data = [{"name": item["Names"], "port": item["Ports"], } for item in docker.containers()]
+ # except Exception as e:
+ # LOG.error(e, exc_info=True)
+ # return {"result": False,
+ # "error": str(e)}
+ return {"containers": self.containers}
+
+ @check_auth
+ def post(self, uuid=None, user_id=None):
+ """Add a new container.
+
+ :param uuid: uuid of the pdp (not used here)
+ :param user_id: user ID who do the request
+ :request body: {
+ "id": "id of the new container",
+ "name": "name of the new container",
+ "hostname": "hostname of the new container",
+ "port": {
+ "PrivatePort": 8080,
+ "Type": "tcp",
+ "IP": "0.0.0.0",
+ "PublicPort": 8080
+ },
+ "keystone_project_id": "keystone_project_id1",
+ "pdp_id": "PDP UUID",
+ "container_name": "wukongsun/moon_authz:v4.1"
+ }
+ :return: {
+ "containers": {
+ "da0fd80fc1dc146e1b...a2e07d240cde09f0a": {
+ "name": [
+ "/wrapper"
+ ],
+ "port": [
+ {
+ "PrivatePort": 8080,
+ "Type": "tcp",
+ "IP": "0.0.0.0",
+ "PublicPort": 8080
+ }
+ ]
+ },
+ }
+ }
+ :internal_api: add_container
+ """
+ try:
+ self.update()
+ self.containers[request.json.get('id')] = copy.deepcopy(request.json)
+ LOG.info("Added a new container {}".format(request.json.get('name')))
+ except Exception as e:
+ LOG.error(e, exc_info=True)
+ return {"result": False,
+ "error": str(e)}, 500
+ return {"containers": self.containers}
+
+ @check_auth
+ def delete(self, uuid=None, 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"
+ }
+ :internal_api: delete_pdp
+ """
+ # try:
+ # data = PDPManager.delete_pdp(user_id=user_id, pdp_id=uuid)
+ # except Exception as e:
+ # LOG.error(e, exc_info=True)
+ # return {"result": False,
+ # "error": str(e)}
+ # return {"result": True}
+ raise NotImplementedError
+
+ @check_auth
+ def patch(self, uuid=None, 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": "...",
+ }
+ }
+ :internal_api: update_pdp
+ """
+ # try:
+ # data = PDPManager.update_pdp(user_id=user_id, pdp_id=uuid, value=request.json)
+ # add_container(uuid=uuid, pipeline=data[uuid]['security_pipeline'])
+ # except Exception as e:
+ # LOG.error(e, exc_info=True)
+ # return {"result": False,
+ # "error": str(e)}
+ # return {"pdps": data}
+ raise NotImplementedError
+
diff --git a/moonv4/moon_manager/moon_manager/api/data.py b/moonv4/moon_manager/moon_manager/api/data.py
index fbf26fd9..85faf415 100644
--- a/moonv4/moon_manager/moon_manager/api/data.py
+++ b/moonv4/moon_manager/moon_manager/api/data.py
@@ -27,12 +27,14 @@ class SubjectData(Resource):
"/policies/<string:uuid>/subject_data",
"/policies/<string:uuid>/subject_data/",
"/policies/<string:uuid>/subject_data/<string:category_id>",
- "/policies/<string:uuid>/subject_data/<string:category_id>/<string:data_id>",
+ "/policies/<string:uuid>/subject_data/<string:category_id>/"
+ "<string:data_id>",
)
@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 for a given policy
+ """Retrieve all subject categories or a specific one if sid is given
+ for a given policy
:param uuid: uuid of the policy
:param category_id: uuid of the subject category
@@ -51,12 +53,14 @@ class SubjectData(Resource):
: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)
+ data = PolicyManager.get_subject_data(user_id=user_id,
+ policy_id=uuid,
+ category_id=category_id,
+ data_id=data_id)
except Exception as e:
LOG.error(e, exc_info=True)
return {"result": False,
- "error": str(e)}
+ "error": str(e)}, 500
return {"subject_data": data}
@check_auth
@@ -84,12 +88,14 @@ class SubjectData(Resource):
:internal_api: add_subject_data
"""
try:
- data = PolicyManager.set_subject_data(user_id=user_id, policy_id=uuid,
- category_id=category_id, value=request.json)
+ data = PolicyManager.set_subject_data(user_id=user_id,
+ policy_id=uuid,
+ category_id=category_id,
+ value=request.json)
except Exception as e:
LOG.error(e, exc_info=True)
return {"result": False,
- "error": str(e)}
+ "error": str(e)}, 500
return {"subject_data": data}
@check_auth
@@ -107,12 +113,13 @@ class SubjectData(Resource):
:internal_api: delete_subject_data
"""
try:
- data = PolicyManager.delete_subject_data(user_id=user_id, policy_id=uuid,
+ data = PolicyManager.delete_subject_data(user_id=user_id,
+ policy_id=uuid,
data_id=data_id)
except Exception as e:
LOG.error(e, exc_info=True)
return {"result": False,
- "error": str(e)}
+ "error": str(e)}, 500
return {"result": True}
@@ -125,12 +132,14 @@ class ObjectData(Resource):
"/policies/<string:uuid>/object_data",
"/policies/<string:uuid>/object_data/",
"/policies/<string:uuid>/object_data/<string:category_id>",
- "/policies/<string:uuid>/object_data/<string:category_id>/<string:data_id>",
+ "/policies/<string:uuid>/object_data/<string:category_id>/"
+ "<string:data_id>",
)
@check_auth
def get(self, uuid=None, 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
+ """Retrieve all object categories or a specific one if sid is given
+ for a given policy
:param uuid: uuid of the policy
:param category_id: uuid of the object category
@@ -149,12 +158,14 @@ class ObjectData(Resource):
: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)
+ data = PolicyManager.get_object_data(user_id=user_id,
+ policy_id=uuid,
+ category_id=category_id,
+ data_id=data_id)
except Exception as e:
LOG.error(e, exc_info=True)
return {"result": False,
- "error": str(e)}
+ "error": str(e)}, 500
return {"object_data": data}
@check_auth
@@ -182,12 +193,14 @@ class ObjectData(Resource):
: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)
+ data = PolicyManager.add_object_data(user_id=user_id,
+ policy_id=uuid,
+ category_id=category_id,
+ value=request.json)
except Exception as e:
LOG.error(e, exc_info=True)
return {"result": False,
- "error": str(e)}
+ "error": str(e)}, 500
return {"object_data": data}
@check_auth
@@ -205,12 +218,13 @@ class ObjectData(Resource):
:internal_api: delete_object_data
"""
try:
- data = PolicyManager.delete_object_data(user_id=user_id, policy_id=uuid,
- data_id=data_id)
+ data = PolicyManager.delete_object_data(user_id=user_id,
+ policy_id=uuid,
+ data_id=data_id)
except Exception as e:
LOG.error(e, exc_info=True)
return {"result": False,
- "error": str(e)}
+ "error": str(e)}, 500
return {"result": True}
@@ -223,12 +237,14 @@ class ActionData(Resource):
"/policies/<string:uuid>/action_data",
"/policies/<string:uuid>/action_data/",
"/policies/<string:uuid>/action_data/<string:category_id>",
- "/policies/<string:uuid>/action_data/<string:category_id>/<string:data_id>",
+ "/policies/<string:uuid>/action_data/<string:category_id>/"
+ "<string:data_id>",
)
@check_auth
def get(self, uuid=None, 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
+ """Retrieve all action categories or a specific one if sid is given
+ for a given policy
:param uuid: uuid of the policy
:param category_id: uuid of the action category
@@ -247,12 +263,14 @@ class ActionData(Resource):
: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)
+ data = PolicyManager.get_action_data(user_id=user_id,
+ policy_id=uuid,
+ category_id=category_id,
+ data_id=data_id)
except Exception as e:
LOG.error(e, exc_info=True)
return {"result": False,
- "error": str(e)}
+ "error": str(e)}, 500
return {"action_data": data}
@check_auth
@@ -280,12 +298,14 @@ class ActionData(Resource):
: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)
+ data = PolicyManager.add_action_data(user_id=user_id,
+ policy_id=uuid,
+ category_id=category_id,
+ value=request.json)
except Exception as e:
LOG.error(e, exc_info=True)
return {"result": False,
- "error": str(e)}
+ "error": str(e)}, 500
return {"action_data": data}
@check_auth
@@ -303,12 +323,13 @@ class ActionData(Resource):
:internal_api: delete_action_data
"""
try:
- data = PolicyManager.delete_action_data(user_id=user_id, policy_id=uuid,
+ data = PolicyManager.delete_action_data(user_id=user_id,
+ policy_id=uuid,
data_id=data_id)
except Exception as e:
LOG.error(e, exc_info=True)
return {"result": False,
- "error": str(e)}
+ "error": str(e)}, 500
return {"result": True}
diff --git a/moonv4/moon_manager/moon_manager/api/generic.py b/moonv4/moon_manager/moon_manager/api/generic.py
index ac4f8f1e..9ff285c8 100644
--- a/moonv4/moon_manager/moon_manager/api/generic.py
+++ b/moonv4/moon_manager/moon_manager/api/generic.py
@@ -107,18 +107,18 @@ class API(Resource):
api_desc = dict()
for api_name in api_list:
api_desc[api_name] = {}
- group_api_obj = eval("moon_interface.api.{}".format(api_name))
+ group_api_obj = eval("moon_manager.api.{}".format(api_name))
api_desc[api_name]["description"] = group_api_obj.__doc__
if "__version__" in dir(group_api_obj):
api_desc[api_name]["version"] = group_api_obj.__version__
object_list = list(filter(lambda x: "__" not in x, dir(group_api_obj)))
- for obj in map(lambda x: eval("moon_interface.api.{}.{}".format(api_name, x)), object_list):
+ for obj in map(lambda x: eval("moon_manager.api.{}.{}".format(api_name, x)), object_list):
if "__urls__" in dir(obj):
api_desc[api_name][obj.__name__] = dict()
api_desc[api_name][obj.__name__]["urls"] = obj.__urls__
api_desc[api_name][obj.__name__]["methods"] = dict()
for _method in filter(lambda x: x in __methods, dir(obj)):
- docstring = eval("moon_interface.api.{}.{}.{}.__doc__".format(api_name, obj.__name__, _method))
+ docstring = eval("moon_manager.api.{}.{}.{}.__doc__".format(api_name, obj.__name__, _method))
api_desc[api_name][obj.__name__]["methods"][_method] = docstring
api_desc[api_name][obj.__name__]["description"] = str(obj.__doc__)
if group_id in api_desc:
diff --git a/moonv4/moon_manager/moon_manager/api/meta_data.py b/moonv4/moon_manager/moon_manager/api/meta_data.py
index 0f9078ed..95cd58cc 100644
--- a/moonv4/moon_manager/moon_manager/api/meta_data.py
+++ b/moonv4/moon_manager/moon_manager/api/meta_data.py
@@ -44,11 +44,12 @@ class SubjectCategories(Resource):
:internal_api: get_subject_categories
"""
try:
- data = ModelManager.get_subject_categories(user_id=user_id, category_id=category_id)
+ data = ModelManager.get_subject_categories(
+ user_id=user_id, category_id=category_id)
except Exception as e:
LOG.error(e, exc_info=True)
return {"result": False,
- "error": str(e)}
+ "error": str(e)}, 500
return {"subject_categories": data}
@check_auth
@@ -70,11 +71,12 @@ class SubjectCategories(Resource):
:internal_api: add_subject_category
"""
try:
- data = ModelManager.add_subject_category(user_id=user_id, value=request.json)
+ data = ModelManager.add_subject_category(
+ user_id=user_id, value=request.json)
except Exception as e:
LOG.error(e, exc_info=True)
return {"result": False,
- "error": str(e)}
+ "error": str(e)}, 500
return {"subject_categories": data}
@check_auth
@@ -90,11 +92,12 @@ class SubjectCategories(Resource):
:internal_api: delete_subject_category
"""
try:
- data = ModelManager.delete_subject_category(user_id=user_id, category_id=category_id)
+ data = ModelManager.delete_subject_category(
+ user_id=user_id, category_id=category_id)
except Exception as e:
LOG.error(e, exc_info=True)
return {"result": False,
- "error": str(e)}
+ "error": str(e)}, 500
return {"result": True}
@@ -124,11 +127,12 @@ class ObjectCategories(Resource):
:internal_api: get_object_categories
"""
try:
- data = ModelManager.get_object_categories(user_id=user_id, category_id=category_id)
+ data = ModelManager.get_object_categories(
+ user_id=user_id, category_id=category_id)
except Exception as e:
LOG.error(e, exc_info=True)
return {"result": False,
- "error": str(e)}
+ "error": str(e)}, 500
return {"object_categories": data}
@check_auth
@@ -150,11 +154,12 @@ class ObjectCategories(Resource):
:internal_api: add_object_category
"""
try:
- data = ModelManager.add_object_category(user_id=user_id, value=request.json)
+ data = ModelManager.add_object_category(
+ user_id=user_id, value=request.json)
except Exception as e:
LOG.error(e, exc_info=True)
return {"result": False,
- "error": str(e)}
+ "error": str(e)}, 500
return {"object_categories": data}
@check_auth
@@ -170,11 +175,12 @@ class ObjectCategories(Resource):
:internal_api: delete_object_category
"""
try:
- data = ModelManager.delete_object_category(user_id=user_id, category_id=category_id)
+ data = ModelManager.delete_object_category(
+ user_id=user_id, category_id=category_id)
except Exception as e:
LOG.error(e, exc_info=True)
return {"result": False,
- "error": str(e)}
+ "error": str(e)}, 500
return {"result": True}
@@ -204,11 +210,12 @@ class ActionCategories(Resource):
:internal_api: get_action_categories
"""
try:
- data = ModelManager.get_action_categories(user_id=user_id, category_id=category_id)
+ data = ModelManager.get_action_categories(
+ user_id=user_id, category_id=category_id)
except Exception as e:
LOG.error(e, exc_info=True)
return {"result": False,
- "error": str(e)}
+ "error": str(e)}, 500
return {"action_categories": data}
@check_auth
@@ -230,11 +237,12 @@ class ActionCategories(Resource):
:internal_api: add_action_category
"""
try:
- data = ModelManager.add_action_category(user_id=user_id, value=request.json)
+ data = ModelManager.add_action_category(
+ user_id=user_id, value=request.json)
except Exception as e:
LOG.error(e, exc_info=True)
return {"result": False,
- "error": str(e)}
+ "error": str(e)}, 500
return {"action_categories": data}
@check_auth
@@ -250,9 +258,10 @@ class ActionCategories(Resource):
:internal_api: delete_action_category
"""
try:
- data = ModelManager.delete_action_category(user_id=user_id, category_id=category_id)
+ data = ModelManager.delete_action_category(
+ user_id=user_id, category_id=category_id)
except Exception as e:
LOG.error(e, exc_info=True)
return {"result": False,
- "error": str(e)}
+ "error": str(e)}, 500
return {"result": True}
diff --git a/moonv4/moon_manager/moon_manager/api/meta_rules.py b/moonv4/moon_manager/moon_manager/api/meta_rules.py
index dc3ea0db..45e2b5ee 100644
--- a/moonv4/moon_manager/moon_manager/api/meta_rules.py
+++ b/moonv4/moon_manager/moon_manager/api/meta_rules.py
@@ -39,7 +39,8 @@ class MetaRules(Resource):
"meta_rule_id1": {
"name": "name of the meta rule",
"algorithm": "name of the meta rule algorithm",
- "subject_categories": ["subject_category_id1", "subject_category_id2"],
+ "subject_categories": ["subject_category_id1",
+ "subject_category_id2"],
"object_categories": ["object_category_id1"],
"action_categories": ["action_category_id1"]
},
@@ -48,11 +49,12 @@ class MetaRules(Resource):
:internal_api: get_meta_rules
"""
try:
- data = ModelManager.get_meta_rules(user_id=user_id, meta_rule_id=meta_rule_id)
+ data = ModelManager.get_meta_rules(
+ user_id=user_id, meta_rule_id=meta_rule_id)
except Exception as e:
LOG.error(e, exc_info=True)
return {"result": False,
- "error": str(e)}
+ "error": str(e)}, 500
return {"meta_rules": data}
@check_auth
@@ -63,7 +65,8 @@ class MetaRules(Resource):
:param user_id: user ID who do the request
:request body: post = {
"name": "name of the meta rule",
- "subject_categories": ["subject_category_id1", "subject_category_id2"],
+ "subject_categories": ["subject_category_id1",
+ "subject_category_id2"],
"object_categories": ["object_category_id1"],
"action_categories": ["action_category_id1"]
}
@@ -71,7 +74,8 @@ class MetaRules(Resource):
"meta_rules": {
"meta_rule_id1": {
"name": "name of the meta rule",
- "subject_categories": ["subject_category_id1", "subject_category_id2"],
+ "subject_categories": ["subject_category_id1",
+ "subject_category_id2"],
"object_categories": ["object_category_id1"],
"action_categories": ["action_category_id1"]
},
@@ -80,11 +84,12 @@ 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)
+ data = ModelManager.add_meta_rule(
+ user_id=user_id, meta_rule_id=None, value=request.json)
except Exception as e:
LOG.error(e, exc_info=True)
return {"result": False,
- "error": str(e)}
+ "error": str(e)}, 500
return {"meta_rules": data}
@check_auth
@@ -95,7 +100,8 @@ class MetaRules(Resource):
:param user_id: user ID who do the request
:request body: patch = {
"name": "name of the meta rule",
- "subject_categories": ["subject_category_id1", "subject_category_id2"],
+ "subject_categories": ["subject_category_id1",
+ "subject_category_id2"],
"object_categories": ["object_category_id1"],
"action_categories": ["action_category_id1"]
}
@@ -103,7 +109,8 @@ class MetaRules(Resource):
"meta_rules": {
"meta_rule_id1": {
"name": "name of the meta rule",
- "subject_categories": ["subject_category_id1", "subject_category_id2"],
+ "subject_categories": ["subject_category_id1",
+ "subject_category_id2"],
"object_categories": ["object_category_id1"],
"action_categories": ["action_category_id1"]
},
@@ -112,11 +119,12 @@ 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)
+ data = ModelManager.set_meta_rule(
+ user_id=user_id, meta_rule_id=meta_rule_id, value=request.json)
except Exception as e:
LOG.error(e, exc_info=True)
return {"result": False,
- "error": str(e)}
+ "error": str(e)}, 500
return {"meta_rules": data}
@check_auth
@@ -127,7 +135,8 @@ class MetaRules(Resource):
: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"],
+ "subject_categories": ["subject_category_id1",
+ "subject_category_id2"],
"object_categories": ["object_category_id1"],
"action_categories": ["action_category_id1"]
}
@@ -135,7 +144,8 @@ class MetaRules(Resource):
"meta_rules": {
"meta_rule_id1": {
"name": "name of the meta rule",
- "subject_categories": ["subject_category_id1", "subject_category_id2"],
+ "subject_categories": ["subject_category_id1",
+ "subject_category_id2"],
"object_categories": ["object_category_id1"],
"action_categories": ["action_category_id1"]
},
@@ -144,10 +154,11 @@ class MetaRules(Resource):
:internal_api: delete_meta_rules
"""
try:
- data = ModelManager.delete_meta_rule(user_id=user_id, meta_rule_id=meta_rule_id)
+ data = ModelManager.delete_meta_rule(
+ user_id=user_id, meta_rule_id=meta_rule_id)
except Exception as e:
LOG.error(e, exc_info=True)
return {"result": False,
- "error": str(e)}
+ "error": str(e)}, 500
return {"result": True}
diff --git a/moonv4/moon_manager/moon_manager/api/models.py b/moonv4/moon_manager/moon_manager/api/models.py
index cec899f5..0a050c7f 100644
--- a/moonv4/moon_manager/moon_manager/api/models.py
+++ b/moonv4/moon_manager/moon_manager/api/models.py
@@ -49,7 +49,7 @@ class Models(Resource):
except Exception as e:
LOG.error(e, exc_info=True)
return {"result": False,
- "error": str(e)}
+ "error": str(e)}, 500
return {"models": data}
@check_auth
@@ -73,11 +73,12 @@ class Models(Resource):
:internal_api: add_model
"""
try:
- data = ModelManager.add_model(user_id=user_id, model_id=uuid, value=request.json)
+ data = ModelManager.add_model(
+ user_id=user_id, model_id=uuid, value=request.json)
except Exception as e:
LOG.error(e, exc_info=True)
return {"result": False,
- "error": str(e)}
+ "error": str(e)}, 500
return {"models": data}
@check_auth
@@ -97,7 +98,7 @@ class Models(Resource):
except Exception as e:
LOG.error(e, exc_info=True)
return {"result": False,
- "error": str(e)}
+ "error": str(e)}, 500
return {"result": True}
@check_auth
@@ -116,10 +117,11 @@ class Models(Resource):
:internal_api: update_model
"""
try:
- data = ModelManager.update_model(user_id=user_id, model_id=uuid, value=request.json)
+ data = ModelManager.update_model(
+ user_id=user_id, model_id=uuid, value=request.json)
except Exception as e:
LOG.error(e, exc_info=True)
return {"result": False,
- "error": str(e)}
+ "error": str(e)}, 500
return {"models": data}
diff --git a/moonv4/moon_manager/moon_manager/api/pdp.py b/moonv4/moon_manager/moon_manager/api/pdp.py
index 15f4988f..465f4dba 100644
--- a/moonv4/moon_manager/moon_manager/api/pdp.py
+++ b/moonv4/moon_manager/moon_manager/api/pdp.py
@@ -9,20 +9,48 @@ PDP are Policy Decision Point.
from flask import request
from flask_restful import Resource
-from oslo_log import log as logging
+import logging
+import requests
+import time
from moon_utilities.security_functions import check_auth
from moon_db.core import PDPManager
+from moon_db.core import PolicyManager
+from moon_db.core import ModelManager
+from moon_utilities import configuration
__version__ = "0.1.0"
LOG = logging.getLogger("moon.manager.api." + __name__)
-def add_container(uuid, pipeline):
- # TODO: to implement
- LOG.warning("Add container not implemented!")
- LOG.info(uuid)
- LOG.info(pipeline)
+def delete_pod(uuid):
+ raise NotImplementedError
+
+
+def add_pod(uuid, data):
+ if not data.get("keystone_project_id"):
+ return
+ LOG.info("Add a new pod {}".format(data))
+ if "pdp_id" not in data:
+ data["pdp_id"] = uuid
+ data['policies'] = PolicyManager.get_policies(user_id="admin")
+ data['models'] = ModelManager.get_models(user_id="admin")
+ conf = configuration.get_configuration("components/orchestrator")
+ hostname = conf["components/orchestrator"].get("hostname", "orchestrator")
+ port = conf["components/orchestrator"].get("port", 80)
+ proto = conf["components/orchestrator"].get("protocol", "http")
+ while True:
+ try:
+ req = requests.post(
+ "{}://{}:{}/pods".format(proto, hostname, port),
+ json=data,
+ headers={"content-type": "application/json"})
+ except requests.exceptions.ConnectionError:
+ LOG.warning("Orchestrator is not ready, standby...")
+ time.sleep(1)
+ else:
+ break
+ LOG.info(req.text)
class PDP(Resource):
@@ -58,7 +86,7 @@ class PDP(Resource):
except Exception as e:
LOG.error(e, exc_info=True)
return {"result": False,
- "error": str(e)}
+ "error": str(e)}, 500
return {"pdps": data}
@check_auth
@@ -84,11 +112,19 @@ class PDP(Resource):
:internal_api: add_pdp
"""
try:
- data = PDPManager.add_pdp(user_id=user_id, pdp_id=None, value=request.json)
+ data = dict(request.json)
+ if not data.get("keystone_project_id"):
+ data["keystone_project_id"] = None
+ data = PDPManager.add_pdp(
+ user_id=user_id, pdp_id=None, value=request.json)
+ uuid = list(data.keys())[0]
+ LOG.info("data={}".format(data))
+ LOG.info("uuid={}".format(uuid))
+ add_pod(uuid=uuid, data=data[uuid])
except Exception as e:
LOG.error(e, exc_info=True)
return {"result": False,
- "error": str(e)}
+ "error": str(e)}, 500
return {"pdps": data}
@check_auth
@@ -105,10 +141,11 @@ class PDP(Resource):
"""
try:
data = PDPManager.delete_pdp(user_id=user_id, pdp_id=uuid)
+ delete_pod(uuid)
except Exception as e:
LOG.error(e, exc_info=True)
return {"result": False,
- "error": str(e)}
+ "error": str(e)}, 500
return {"result": True}
@check_auth
@@ -128,11 +165,17 @@ class PDP(Resource):
:internal_api: update_pdp
"""
try:
- data = PDPManager.update_pdp(user_id=user_id, pdp_id=uuid, value=request.json)
- add_container(uuid=uuid, pipeline=data[uuid]['security_pipeline'])
+ _data = dict(request.json)
+ if not _data.get("keystone_project_id"):
+ _data["keystone_project_id"] = None
+ data = PDPManager.update_pdp(
+ user_id=user_id, pdp_id=uuid, value=_data)
+ LOG.info("data={}".format(data))
+ LOG.info("uuid={}".format(uuid))
+ add_pod(uuid=uuid, data=data[uuid])
except Exception as e:
LOG.error(e, exc_info=True)
return {"result": False,
- "error": str(e)}
+ "error": str(e)}, 500
return {"pdps": data}
diff --git a/moonv4/moon_manager/moon_manager/api/perimeter.py b/moonv4/moon_manager/moon_manager/api/perimeter.py
index cc2c0561..2eb80652 100644
--- a/moonv4/moon_manager/moon_manager/api/perimeter.py
+++ b/moonv4/moon_manager/moon_manager/api/perimeter.py
@@ -3,8 +3,10 @@
# license which can be found in the file 'LICENSE' in this package distribution
# or at 'http://www.apache.org/licenses/LICENSE-2.0'.
"""
-* Subjects are the source of an action on an object (examples : users, virtual machines)
-* Objects are the destination of an action (examples virtual machines, virtual Routers)
+* Subjects are the source of an action on an object
+ (examples : users, virtual machines)
+* Objects are the destination of an action
+ (examples virtual machines, virtual Routers)
* Actions are what subject wants to do on an object
"""
@@ -35,7 +37,8 @@ class Subjects(Resource):
@check_auth
def get(self, uuid=None, perimeter_id=None, user_id=None):
- """Retrieve all subjects or a specific one if perimeter_id is given for a given policy
+ """Retrieve all subjects or a specific one if perimeter_id is
+ given for a given policy
:param uuid: uuid of the policy
:param perimeter_id: uuid of the subject
@@ -58,7 +61,7 @@ class Subjects(Resource):
except Exception as e:
LOG.error(e, exc_info=True)
return {"result": False,
- "error": str(e)}
+ "error": str(e)}, 500
return {"subjects": data}
@check_auth
@@ -87,18 +90,20 @@ class Subjects(Resource):
"""
try:
if not perimeter_id:
- data = PolicyManager.get_subjects(user_id=user_id, policy_id=None)
+ 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)
+ data = PolicyManager.add_subject(
+ user_id=user_id, policy_id=uuid,
+ perimeter_id=perimeter_id, value=request.json)
except Exception as e:
LOG.error(e, exc_info=True)
return {"result": False,
- "error": str(e)}
+ "error": str(e)}, 500
return {"subjects": data}
@check_auth
@@ -127,18 +132,20 @@ class Subjects(Resource):
"""
try:
if not perimeter_id:
- data = PolicyManager.get_subjects(user_id=user_id, policy_id=None)
+ 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)
+ data = PolicyManager.add_subject(
+ user_id=user_id, policy_id=uuid,
+ perimeter_id=perimeter_id, value=request.json)
except Exception as e:
LOG.error(e, exc_info=True)
return {"result": False,
- "error": str(e)}
+ "error": str(e)}, 500
return {"subjects": data}
@check_auth
@@ -160,11 +167,12 @@ class Subjects(Resource):
:internal_api: delete_subject
"""
try:
- data = PolicyManager.delete_subject(user_id=user_id, policy_id=uuid, perimeter_id=perimeter_id)
+ data = PolicyManager.delete_subject(
+ user_id=user_id, policy_id=uuid, perimeter_id=perimeter_id)
except Exception as e:
LOG.error(e, exc_info=True)
return {"result": False,
- "error": str(e)}
+ "error": str(e)}, 500
return {"result": True}
@@ -184,7 +192,8 @@ class Objects(Resource):
@check_auth
def get(self, uuid=None, perimeter_id=None, user_id=None):
- """Retrieve all objects or a specific one if perimeter_id is given for a given policy
+ """Retrieve all objects or a specific one if perimeter_id is
+ given for a given policy
:param uuid: uuid of the policy
:param perimeter_id: uuid of the object
@@ -206,7 +215,7 @@ class Objects(Resource):
except Exception as e:
LOG.error(e, exc_info=True)
return {"result": False,
- "error": str(e)}
+ "error": str(e)}, 500
return {"objects": data}
@check_auth
@@ -235,12 +244,13 @@ class Objects(Resource):
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)
+ data = PolicyManager.add_object(
+ user_id=user_id, policy_id=uuid,
+ perimeter_id=perimeter_id, value=request.json)
except Exception as e:
LOG.error(e, exc_info=True)
return {"result": False,
- "error": str(e)}
+ "error": str(e)}, 500
return {"objects": data}
@check_auth
@@ -269,12 +279,13 @@ class Objects(Resource):
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)
+ data = PolicyManager.add_object(
+ user_id=user_id, policy_id=uuid,
+ perimeter_id=perimeter_id, value=request.json)
except Exception as e:
LOG.error(e, exc_info=True)
return {"result": False,
- "error": str(e)}
+ "error": str(e)}, 500
return {"objects": data}
@check_auth
@@ -293,11 +304,12 @@ class Objects(Resource):
:internal_api: delete_object
"""
try:
- data = PolicyManager.delete_object(user_id=user_id, policy_id=uuid, perimeter_id=perimeter_id)
+ data = PolicyManager.delete_object(
+ user_id=user_id, policy_id=uuid, perimeter_id=perimeter_id)
except Exception as e:
LOG.error(e, exc_info=True)
return {"result": False,
- "error": str(e)}
+ "error": str(e)}, 500
return {"result": True}
@@ -317,7 +329,8 @@ class Actions(Resource):
@check_auth
def get(self, uuid=None, perimeter_id=None, user_id=None):
- """Retrieve all actions or a specific one if perimeter_id is given for a given policy
+ """Retrieve all actions or a specific one if perimeter_id
+ is given for a given policy
:param uuid: uuid of the policy
:param perimeter_id: uuid of the action
@@ -331,11 +344,12 @@ class Actions(Resource):
:internal_api: get_actions
"""
try:
- data = PolicyManager.get_actions(user_id=user_id, policy_id=uuid, perimeter_id=perimeter_id)
+ data = PolicyManager.get_actions(
+ user_id=user_id, policy_id=uuid, perimeter_id=perimeter_id)
except Exception as e:
LOG.error(e, exc_info=True)
return {"result": False,
- "error": str(e)}
+ "error": str(e)}, 500
return {"actions": data}
@check_auth
@@ -364,12 +378,13 @@ class Actions(Resource):
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)
+ data = PolicyManager.add_action(
+ user_id=user_id, policy_id=uuid,
+ perimeter_id=perimeter_id, value=request.json)
except Exception as e:
LOG.error(e, exc_info=True)
return {"result": False,
- "error": str(e)}
+ "error": str(e)}, 500
return {"actions": data}
@check_auth
@@ -398,12 +413,13 @@ class Actions(Resource):
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)
+ data = PolicyManager.add_action(
+ user_id=user_id, policy_id=uuid,
+ perimeter_id=perimeter_id, value=request.json)
except Exception as e:
LOG.error(e, exc_info=True)
return {"result": False,
- "error": str(e)}
+ "error": str(e)}, 500
return {"actions": data}
@check_auth
@@ -422,9 +438,10 @@ class Actions(Resource):
:internal_api: delete_action
"""
try:
- data = PolicyManager.delete_action(user_id=user_id, policy_id=uuid, perimeter_id=perimeter_id)
+ data = PolicyManager.delete_action(
+ user_id=user_id, policy_id=uuid, perimeter_id=perimeter_id)
except Exception as e:
LOG.error(e, exc_info=True)
return {"result": False,
- "error": str(e)}
+ "error": str(e)}, 500
return {"result": True}
diff --git a/moonv4/moon_manager/moon_manager/api/policies.py b/moonv4/moon_manager/moon_manager/api/policies.py
index 737b988e..8ef11a0d 100644
--- a/moonv4/moon_manager/moon_manager/api/policies.py
+++ b/moonv4/moon_manager/moon_manager/api/policies.py
@@ -51,7 +51,7 @@ class Policies(Resource):
except Exception as e:
LOG.error(e, exc_info=True)
return {"result": False,
- "error": str(e)}
+ "error": str(e)}, 500
return {"policies": data}
@check_auth
@@ -77,11 +77,12 @@ class Policies(Resource):
:internal_api: add_policy
"""
try:
- data = PolicyManager.add_policy(user_id=user_id, policy_id=uuid, value=request.json)
+ data = PolicyManager.add_policy(
+ user_id=user_id, policy_id=uuid, value=request.json)
except Exception as e:
LOG.error(e, exc_info=True)
return {"result": False,
- "error": str(e)}
+ "error": str(e)}, 500
return {"policies": data}
@check_auth
@@ -101,7 +102,7 @@ class Policies(Resource):
except Exception as e:
LOG.error(e, exc_info=True)
return {"result": False,
- "error": str(e)}
+ "error": str(e)}, 500
return {"result": True}
@check_auth
@@ -121,10 +122,11 @@ class Policies(Resource):
:internal_api: update_policy
"""
try:
- data = PolicyManager.update_policy(user_id=user_id, policy_id=uuid, value=request.json)
+ data = PolicyManager.update_policy(
+ user_id=user_id, policy_id=uuid, value=request.json)
except Exception as e:
LOG.error(e, exc_info=True)
return {"result": False,
- "error": str(e)}
+ "error": str(e)}, 500
return {"policies": data}
diff --git a/moonv4/moon_manager/moon_manager/api/rules.py b/moonv4/moon_manager/moon_manager/api/rules.py
index 8b1cf635..f7771f1a 100644
--- a/moonv4/moon_manager/moon_manager/api/rules.py
+++ b/moonv4/moon_manager/moon_manager/api/rules.py
@@ -9,7 +9,6 @@ Rules (TODO)
from flask import request
from flask_restful import Resource
from oslo_log import log as logging
-from moon_utilities.security_functions import call
from moon_utilities.security_functions import check_auth
from moon_db.core import PolicyManager
@@ -40,8 +39,10 @@ class Rules(Resource):
"rules": [
"policy_id": "policy_id1",
"meta_rule_id": "meta_rule_id1",
- "rule_id1": ["subject_data_id1", "object_data_id1", "action_data_id1"],
- "rule_id2": ["subject_data_id2", "object_data_id2", "action_data_id2"],
+ "rule_id1":
+ ["subject_data_id1", "object_data_id1", "action_data_id1"],
+ "rule_id2":
+ ["subject_data_id2", "object_data_id2", "action_data_id2"],
]
}
:internal_api: get_rules
@@ -53,7 +54,7 @@ class Rules(Resource):
except Exception as e:
LOG.error(e, exc_info=True)
return {"result": False,
- "error": str(e)}
+ "error": str(e)}, 500
return {"rules": data}
@check_auth
@@ -75,23 +76,31 @@ class Rules(Resource):
"rules": [
"meta_rule_id": "meta_rule_id1",
"rule_id1": {
- "rule": ["subject_data_id1", "object_data_id1", "action_data_id1"],
+ "rule": ["subject_data_id1",
+ "object_data_id1",
+ "action_data_id1"],
"instructions": (
- {"decision": "grant"}, # "grant" to immediately exit,
- # "continue" to wait for the result of next policy
- # "deny" to deny the request
+ {"decision": "grant"},
+ # "grant" to immediately exit,
+ # "continue" to wait for the result of next policy
+ # "deny" to deny the request
)
}
"rule_id2": {
- "rule": ["subject_data_id2", "object_data_id2", "action_data_id2"],
+ "rule": ["subject_data_id2",
+ "object_data_id2",
+ "action_data_id2"],
"instructions": (
{
"update": {
- "operation": "add", # operations may be "add" or "delete"
- "target": "rbac:role:admin" # add the role admin to the current user
+ "operation": "add",
+ # operations may be "add" or "delete"
+ "target": "rbac:role:admin"
+ # add the role admin to the current user
}
},
- {"chain": {"name": "rbac"}} # chain with the policy named rbac
+ {"chain": {"name": "rbac"}}
+ # chain with the policy named rbac
)
}
]
@@ -107,7 +116,7 @@ class Rules(Resource):
except Exception as e:
LOG.error(e, exc_info=True)
return {"result": False,
- "error": str(e)}
+ "error": str(e)}, 500
return {"rules": data}
@check_auth
@@ -121,10 +130,11 @@ class Rules(Resource):
:internal_api: delete_rule
"""
try:
- data = PolicyManager.delete_rule(user_id=user_id, policy_id=uuid, rule_id=rule_id)
+ data = PolicyManager.delete_rule(
+ user_id=user_id, policy_id=uuid, rule_id=rule_id)
except Exception as e:
LOG.error(e, exc_info=True)
return {"result": False,
- "error": str(e)}
+ "error": str(e)}, 500
return {"result": True}
diff --git a/moonv4/moon_manager/moon_manager/http_server.py b/moonv4/moon_manager/moon_manager/http_server.py
index bdd429e4..c671ed6f 100644
--- a/moonv4/moon_manager/moon_manager/http_server.py
+++ b/moonv4/moon_manager/moon_manager/http_server.py
@@ -7,6 +7,8 @@ from flask import Flask, jsonify
from flask_cors import CORS, cross_origin
from flask_restful import Resource, Api
import logging
+import sqlalchemy.exc
+import time
from moon_manager import __version__
from moon_manager.api.generic import Status, Logs, API
from moon_manager.api.models import Models
@@ -18,9 +20,12 @@ 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 moon_manager.api.containers import Container
from moon_utilities import configuration, exceptions
+from moon_db.core import PDPManager
-logger = logging.getLogger("moon.manager.http")
+
+LOG = logging.getLogger("moon.manager.http")
class Server:
@@ -72,7 +77,7 @@ __API__ = (
Subjects, Objects, Actions,
SubjectAssignments, ObjectAssignments, ActionAssignments,
SubjectData, ObjectData, ActionData,
- Rules,
+ Rules, #Container,
Models, Policies, PDP
)
@@ -131,6 +136,22 @@ class HTTPServer(Server):
for api in __API__:
self.api.add_resource(api, *api.__urls__)
+ @staticmethod
+ def __check_if_db_is_up():
+ first = True
+ while True:
+ try:
+ PDPManager.get_pdp(user_id="admin", pdp_id=None)
+ except sqlalchemy.exc.ProgrammingError:
+ time.sleep(1)
+ if first:
+ LOG.warning("Waiting for the database...")
+ first = False
+ else:
+ LOG.warning("Database is up, resuming operations...")
+ break
+
def run(self):
+ self.__check_if_db_is_up()
self.app.run(debug=True, host=self._host, port=self._port) # nosec
diff --git a/moonv4/moon_manager/moon_manager/server.py b/moonv4/moon_manager/moon_manager/server.py
index c317e319..f777fac1 100644
--- a/moonv4/moon_manager/moon_manager/server.py
+++ b/moonv4/moon_manager/moon_manager/server.py
@@ -30,8 +30,9 @@ def main():
configuration.add_component(uuid="manager", name=hostname, port=port, bind=bind)
LOG.info("Starting server with IP {} on port {} bind to {}".format(hostname, port, bind))
server = HTTPServer(host=bind, port=port)
- server.run()
+ return server
if __name__ == '__main__':
- main()
+ server = main()
+ server.run()
diff --git a/moonv4/moon_manager/requirements.txt b/moonv4/moon_manager/requirements.txt
index e7be3d0e..6b2af70b 100644
--- a/moonv4/moon_manager/requirements.txt
+++ b/moonv4/moon_manager/requirements.txt
@@ -2,4 +2,5 @@ flask
flask_restful
flask_cors
moon_utilities
-moon_db \ No newline at end of file
+moon_db
+docker-py
diff --git a/moonv4/moon_interface/tests/apitests/utils/__init__.py b/moonv4/moon_manager/tests/unit_python/__init__.py
index e69de29b..e69de29b 100644
--- a/moonv4/moon_interface/tests/apitests/utils/__init__.py
+++ b/moonv4/moon_manager/tests/unit_python/__init__.py
diff --git a/moonv4/moon_router/moon_router/api/__init__.py b/moonv4/moon_manager/tests/unit_python/api/__init__.py
index e69de29b..e69de29b 100644
--- a/moonv4/moon_router/moon_router/api/__init__.py
+++ b/moonv4/moon_manager/tests/unit_python/api/__init__.py
diff --git a/moonv4/moon_manager/tests/unit_python/api/test_perimeter.py b/moonv4/moon_manager/tests/unit_python/api/test_perimeter.py
new file mode 100644
index 00000000..18d3837a
--- /dev/null
+++ b/moonv4/moon_manager/tests/unit_python/api/test_perimeter.py
@@ -0,0 +1,59 @@
+# import moon_manager
+# import moon_manager.api
+import json
+
+
+def get_json(data):
+ return json.loads(data.decode("utf-8"))
+
+
+def get_subjects(client):
+ req = client.get("/subjects")
+ assert req.status_code == 200
+ subjects = get_json(req.data)
+ assert isinstance(subjects, dict)
+ assert "subjects" in subjects
+ return subjects
+
+
+def add_subjects(client, name):
+ data = {
+ "name": name,
+ "description": "description of {}".format(name),
+ "password": "password for {}".format(name),
+ "email": "{}@moon".format(name)
+ }
+ req = client.post("/subjects", data=json.dumps(data),
+ headers={'Content-Type': 'application/json'})
+ assert req.status_code == 200
+ subjects = get_json(req.data)
+ assert isinstance(subjects, dict)
+ key = list(subjects["subjects"].keys())[0]
+ value = list(subjects["subjects"].values())[0]
+ 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
+
+
+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_subject():
+ import moon_manager.server
+ server = moon_manager.server.main()
+ client = server.app.test_client()
+ get_subjects(client)
+ add_subjects(client, "testuser")
+ delete_subject(client, "testuser")
diff --git a/moonv4/moon_manager/tests/unit_python/conftest.py b/moonv4/moon_manager/tests/unit_python/conftest.py
new file mode 100644
index 00000000..d6f518f7
--- /dev/null
+++ b/moonv4/moon_manager/tests/unit_python/conftest.py
@@ -0,0 +1,195 @@
+import base64
+import json
+import logging
+import pytest
+import requests_mock
+
+CONF = {
+ "openstack": {
+ "keystone": {
+ "url": "http://keystone:5000/v3",
+ "user": "admin",
+ "check_token": False,
+ "password": "p4ssw0rd",
+ "domain": "default",
+ "certificate": False,
+ "project": "admin"
+ }
+ },
+ "components": {
+ "wrapper": {
+ "bind": "0.0.0.0",
+ "port": 8080,
+ "container": "wukongsun/moon_wrapper:v4.3",
+ "timeout": 5,
+ "hostname": "wrapper"
+ },
+ "manager": {
+ "bind": "0.0.0.0",
+ "port": 8082,
+ "container": "wukongsun/moon_manager:v4.3",
+ "hostname": "manager"
+ },
+ "port_start": 31001,
+ "orchestrator": {
+ "bind": "0.0.0.0",
+ "port": 8083,
+ "container": "wukongsun/moon_orchestrator:v4.3",
+ "hostname": "interface"
+ },
+ "interface": {
+ "bind": "0.0.0.0",
+ "port": 8080,
+ "container": "wukongsun/moon_interface:v4.3",
+ "hostname": "interface"
+ }
+ },
+ "plugins": {
+ "session": {
+ "port": 8082,
+ "container": "asteroide/session:latest"
+ },
+ "authz": {
+ "port": 8081,
+ "container": "wukongsun/moon_authz:v4.3"
+ }
+ },
+ "logging": {
+ "handlers": {
+ "file": {
+ "filename": "/tmp/moon.log",
+ "class": "logging.handlers.RotatingFileHandler",
+ "level": "DEBUG",
+ "formatter": "custom",
+ "backupCount": 3,
+ "maxBytes": 1048576
+ },
+ "console": {
+ "class": "logging.StreamHandler",
+ "formatter": "brief",
+ "level": "INFO",
+ "stream": "ext://sys.stdout"
+ }
+ },
+ "formatters": {
+ "brief": {
+ "format": "%(levelname)s %(name)s %(message)-30s"
+ },
+ "custom": {
+ "format": "%(asctime)-15s %(levelname)s %(name)s %(message)s"
+ }
+ },
+ "root": {
+ "handlers": [
+ "console"
+ ],
+ "level": "ERROR"
+ },
+ "version": 1,
+ "loggers": {
+ "moon": {
+ "handlers": [
+ "console",
+ "file"
+ ],
+ "propagate": False,
+ "level": "DEBUG"
+ }
+ }
+ },
+ "slave": {
+ "name": None,
+ "master": {
+ "url": None,
+ "login": None,
+ "password": None
+ }
+ },
+ "docker": {
+ "url": "tcp://172.88.88.1:2376",
+ "network": "moon"
+ },
+ "database": {
+ "url": "sqlite:///database.db",
+ # "url": "mysql+pymysql://moon:p4sswOrd1@db/moon",
+ "driver": "sql"
+ },
+ "messenger": {
+ "url": "rabbit://moon:p4sswOrd1@messenger:5672/moon"
+ }
+}
+
+COMPONENTS = (
+ "logging",
+ "openstack/keystone",
+ "database",
+ "slave",
+ "components/manager",
+)
+
+
+def get_b64_conf(component=None):
+ if component in CONF:
+ return base64.b64encode(
+ json.dumps(
+ CONF[component]).encode('utf-8')+b"\n").decode('utf-8')
+ elif "/" in component:
+ key1, _, key2 = component.partition("/")
+ return base64.b64encode(
+ json.dumps(
+ CONF[key1][key2]).encode('utf-8')+b"\n").decode('utf-8')
+ else:
+ return base64.b64encode(
+ json.dumps(CONF).encode('utf-8')+b"\n").decode('utf-8')
+
+
+@pytest.fixture(autouse=True)
+def no_requests(monkeypatch):
+ """ Modify the response from Requests module
+ """
+ with requests_mock.Mocker(real_http=True) as m:
+ for component in COMPONENTS:
+ m.register_uri(
+ 'GET', 'http://consul:8500/v1/kv/{}'.format(component),
+ json=[{'Key': component, 'Value': get_b64_conf(component)}]
+ )
+ 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"
+ }]}
+ )
+ print("Start populating the DB.")
+ from moon_db.db_manager import init_engine, main
+ engine = init_engine()
+ print("engine={}".format(engine))
+ main("upgrade", logging.getLogger("db_manager"), engine)
+ print("End populating the DB.")
+ yield m
+
+
+# @pytest.fixture(autouse=True, scope="session")
+# def manage_database():
+# from moon_db.db_manager import init_engine, run
+# engine = init_engine()
+# run("upgrade", logging.getLogger("db_manager"), engine)
+# yield
+# print("Will close the DB")
+
+
diff --git a/moonv4/moon_manager/tests/unit_python/requirements.txt b/moonv4/moon_manager/tests/unit_python/requirements.txt
new file mode 100644
index 00000000..8bd8449f
--- /dev/null
+++ b/moonv4/moon_manager/tests/unit_python/requirements.txt
@@ -0,0 +1,5 @@
+flask
+flask_cors
+flask_restful
+moon_db
+moon_utilities \ No newline at end of file
diff --git a/moonv4/moon_orchestrator/Dockerfile b/moonv4/moon_orchestrator/Dockerfile
index b68c130f..aafe1784 100644
--- a/moonv4/moon_orchestrator/Dockerfile
+++ b/moonv4/moon_orchestrator/Dockerfile
@@ -9,6 +9,7 @@ RUN pip3 install pip --upgrade
ADD . /root
WORKDIR /root/
RUN pip3 install -r requirements.txt --upgrade
+#RUN pip3 install /root/dist/* --upgrade
RUN pip3 install . --upgrade
-CMD ["python3", "bootstrap.py"] \ No newline at end of file
+CMD ["python3", "-m", "moon_orchestrator"] \ No newline at end of file
diff --git a/moonv4/moon_orchestrator/LICENSE b/moonv4/moon_orchestrator/LICENSE
index 4143aac2..d6456956 100644
--- a/moonv4/moon_orchestrator/LICENSE
+++ b/moonv4/moon_orchestrator/LICENSE
@@ -174,31 +174,29 @@
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
---- License for python-keystoneclient versions prior to 2.1 ---
-
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
-
- 1. Redistributions of source code must retain the above copyright notice,
- this list of conditions and the following disclaimer.
-
- 2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-
- 3. Neither the name of this project nor the names of its contributors may
- be used to endorse or promote products derived from this software without
- specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
-FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
-SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
-CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
-OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ END OF TERMS AND CONDITIONS
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright [yyyy] [name of copyright owner]
+
+ 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.
diff --git a/moonv4/moon_orchestrator/bootstrap.py b/moonv4/moon_orchestrator/bootstrap.py
deleted file mode 100644
index dab78f25..00000000
--- a/moonv4/moon_orchestrator/bootstrap.py
+++ /dev/null
@@ -1,203 +0,0 @@
-import sys
-import time
-import requests
-import yaml
-import logging
-import json
-import base64
-import mysql.connector
-import re
-import subprocess
-import pika
-import pika.credentials
-import pika.exceptions
-
-logging.basicConfig(level=logging.INFO)
-log = logging.getLogger("moon.bootstrap")
-requests_log = logging.getLogger("requests.packages.urllib3")
-requests_log.setLevel(logging.WARNING)
-requests_log.propagate = True
-pika_log = logging.getLogger("pika")
-pika_log.setLevel(logging.ERROR)
-pika_log.propagate = True
-
-CONSUL_HOST = sys.argv[1] if len(sys.argv) > 1 else "consul"
-CONSUL_PORT = sys.argv[2] if len(sys.argv) > 2 else 8500
-HEADERS = {"content-type": "application/json"}
-
-
-def search_config_file():
- data_config = None
- for _file in (
- "moon.conf",
- "conf/moon.conf",
- "../moon.conf",
- "/etc/moon/moon.conf",
- ):
- try:
- data_config = yaml.safe_load(open(_file))
- except FileNotFoundError:
- data_config = None
- continue
- else:
- break
- if not data_config:
- raise Exception("Configuration file not found...")
- return data_config
-
-
-def put(key, value):
- url = "http://{host}:{port}/v1/kv/{key}".format(host=CONSUL_HOST, port=CONSUL_PORT, key=key)
- log.info(url)
- req = requests.put(
- url,
- headers=HEADERS,
- json=value
- )
- if req.status_code != 200:
- raise Exception("Error connecting to Consul ({}, {})".format(req.status_code, req.text))
-
-
-def get(key):
- url = "http://{host}:{port}/v1/kv/{key}".format(host=CONSUL_HOST, port=CONSUL_PORT, key=key)
- req = requests.get(url)
- data = req.json()
- for item in data:
- log.info("{} {} -> {}".format(
- req.status_code,
- item["Key"],
- json.loads(base64.b64decode(item["Value"]).decode("utf-8"))
- ))
- yield json.loads(base64.b64decode(item["Value"]).decode("utf-8"))
-
-
-def populate_consul(data_config):
- while True:
- try:
- req = requests.get("http://{}:{}/ui".format(CONSUL_HOST, CONSUL_PORT))
- except requests.exceptions.ConnectionError:
- log.info("Waiting for Consul ({}:{})".format(CONSUL_HOST, CONSUL_PORT))
- time.sleep(1)
- continue
- else:
- break
- # if req.status_code in (302, 200):
- # break
- # log.info("Waiting for Consul ({}:{})".format(CONSUL_HOST, CONSUL_PORT))
- # time.sleep(1)
- log.info("Consul is up")
-
- req = requests.get("http://{}:{}/v1/kv/database".format(CONSUL_HOST, CONSUL_PORT))
- if req.status_code == 200:
- log.info("Consul is already populated")
- return
-
- put("database", data_config["database"])
- put("messenger", data_config["messenger"])
- put("slave", data_config["slave"])
- put("docker", data_config["docker"])
- put("logging", data_config["logging"])
- put("components_port_start", data_config["components"]["port_start"])
-
- for _key, _value in data_config["components"].items():
- if type(_value) is dict:
- put("components/{}".format(_key), data_config["components"][_key])
-
- for _key, _value in data_config["plugins"].items():
- put("plugins/{}".format(_key), data_config["plugins"][_key])
-
- for _key, _value in data_config["openstack"].items():
- put("openstack/{}".format(_key), data_config["openstack"][_key])
-
-
-def wait_for_database():
- log.info(get("database"))
- for database in get("database"):
- database_url = database['url']
- match = re.search("(?P<proto>^[\\w+]+):\/\/(?P<user>\\w+):(?P<password>.+)@(?P<host>\\w+):*(?P<port>\\d*)",
- database_url)
- config = match.groupdict()
- while True:
- try:
- conn = mysql.connector.connect(
- host=config["host"],
- user=config["user"],
- password=config["password"],
- database="moon"
- )
- conn.close()
- except mysql.connector.errors.InterfaceError:
- log.info("Waiting for Database ({})".format(config["host"]))
- time.sleep(1)
- continue
- else:
- log.info("Database i up, populating it...")
- output = subprocess.run(["moon_db_manager", "upgrade"])
- if output.returncode != 0:
- raise Exception("Error populating the database!")
- break
-
-
-def wait_for_message_queue():
- for messenger in get("messenger"):
- url = messenger['url']
- match = re.search("(?P<proto>^[\\w+]+):\/\/(?P<user>\\w+):(?P<password>.+)@(?P<host>\\w+):?(?P<port>\\d*)/?(?P<virtual_host>\\w+)",
- url)
- config = match.groupdict()
- while True:
- try:
- connection = pika.BlockingConnection(
- pika.ConnectionParameters(
- host=config['host'],
- port=int(config['port']),
- virtual_host=config['virtual_host'],
- credentials=pika.credentials.PlainCredentials(
- config['user'],
- config['password']
- )
- )
- )
- connection.close()
- except (
- pika.exceptions.ProbableAuthenticationError,
- pika.exceptions.ConnectionClosed,
- ConnectionResetError,
- pika.exceptions.IncompatibleProtocolError
- ):
- log.info("Waiting for MessageQueue ({})".format(config["host"]))
- time.sleep(1)
- continue
- else:
- log.info("MessageQueue is up")
- break
-
-
-def wait_for_keystone():
- # TODO: Keystone answers request too quickly
- # even if it is not fully loaded
- # we must test if a token retrieval is possible or not
- # to see if Keystone is truly up and running
- for config in get("openstack/keystone"):
- while True:
- try:
- req = requests.get(config["url"])
- except requests.exceptions.ConnectionError:
- log.info("Waiting for Keystone ({})".format(config["url"]))
- time.sleep(1)
- continue
- else:
- log.info("Keystone is up")
- break
-
-
-def main():
- data_config = search_config_file()
- populate_consul(data_config)
- wait_for_database()
- wait_for_message_queue()
- wait_for_keystone()
- import moon_orchestrator.server
- moon_orchestrator.server.main()
-
-main()
-
diff --git a/moonv4/moon_orchestrator/moon_orchestrator/__main__.py b/moonv4/moon_orchestrator/moon_orchestrator/__main__.py
index b1feff49..9ebc3a7f 100644
--- a/moonv4/moon_orchestrator/moon_orchestrator/__main__.py
+++ b/moonv4/moon_orchestrator/moon_orchestrator/__main__.py
@@ -1,3 +1,4 @@
from moon_orchestrator.server import main
-main()
+server = main()
+server.run()
diff --git a/moonv4/moon_orchestrator/moon_orchestrator/api/configuration.py b/moonv4/moon_orchestrator/moon_orchestrator/api/configuration.py
deleted file mode 100644
index 887a989b..00000000
--- a/moonv4/moon_orchestrator/moon_orchestrator/api/configuration.py
+++ /dev/null
@@ -1,63 +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 json
-from oslo_config import cfg
-from oslo_log import log as logging
-# from moon_db.core import IntraExtensionRootManager
-from moon_db.core import ConfigurationManager
-
-LOG = logging.getLogger("moon.orchestrator.api.configuration")
-CONF = cfg.CONF
-
-
-class Configuration(object):
- """
- Retrieve the global configuration.
- """
-
- __version__ = "0.1.0"
-
- def get_policy_templates(self, ctx, args):
- """List all policy templates
-
- :param ctx: {"id": "intra_extension_id"}
- :param args: {}
- :return: {
- "template_id": {
- "name": "name of the template",
- "description": "description of the template",
- }
- """
- templates = ConfigurationManager.get_policy_templates_dict(ctx["user_id"])
- return {"policy_templates": templates}
-
- def get_aggregation_algorithms(self, ctx, args):
- """List all aggregation algorithms
-
- :param ctx: {"id": "intra_extension_id"}
- :param args: {}
- :return: {
- "algorithm_id": {
- "name": "name of the algorithm",
- "description": "description of the algorithm",
- }
- }
- """
- return {'aggregation_algorithms': ConfigurationManager.get_aggregation_algorithms_dict(ctx["user_id"])}
-
- def get_sub_meta_rule_algorithms(self, ctx, args):
- """List all sub meta rule algorithms
-
- :param ctx: {"id": "intra_extension_id"}
- :param args: {}
- :return: {
- "algorithm_id": {
- "name": "name of the algorithm",
- "description": "description of the algorithm",
- }
- }
- """
- return {'sub_meta_rule_algorithms': ConfigurationManager.get_sub_meta_rule_algorithms_dict(ctx["user_id"])}
diff --git a/moonv4/moon_orchestrator/moon_orchestrator/api/containers.py b/moonv4/moon_orchestrator/moon_orchestrator/api/containers.py
deleted file mode 100644
index 23acea5f..00000000
--- a/moonv4/moon_orchestrator/moon_orchestrator/api/containers.py
+++ /dev/null
@@ -1,123 +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 hashlib
-from oslo_config import cfg
-from oslo_log import log as logging
-# from moon_db.core import IntraExtensionRootManager
-# from moon_db.core import ConfigurationManager
-from moon_utilities.security_functions import call
-
-LOG = logging.getLogger("moon.orchestrator.api.containers")
-CONF = cfg.CONF
-
-
-class Containers(object):
- """
- Manage containers.
- """
-
- __version__ = "0.1.0"
-
- def __init__(self, docker_manager):
- self.docker_manager = docker_manager
- self.components = dict()
- for pdp_key, pdp_value in call("moon_manager", method="get_pdp",
- ctx={"user_id": "admin", "id": None})["pdps"].items():
- self.add_container(ctx={"id": pdp_key, "pipeline": pdp_value["security_pipeline"]})
-
- def get_container(self, ctx, args=None):
- """Get containers linked to an intra-extension
-
- :param ctx: {
- "id": "intra_extension_uuid",
- "keystone_project_id": "Keystone Project UUID"
- }
- :param args: {}
- :return: {
- "containers": {...},
- }
- """
- uuid = ctx.get("id")
- keystone_project_id = ctx.get("keystone_project_id")
- # _containers = self.docker_manager.get_component(uuid=uuid)
- # LOG.info("containers={}".format(_containers))
- if uuid:
- return self.components[uuid]
- elif keystone_project_id:
- for container_id, container_value in self.components.items():
- if container_value['keystone_project_id'] == keystone_project_id:
- return {container_id: container_value}
- else:
- return {}
- return {"containers": self.components}
-
- def add_container(self, ctx, args=None):
- """Add containers
-
- :param ctx: {"id": "intra_extension_uuid"}
- :param args: {}
- :return: {
- "container_id1": {"status": True},
- "container_id2": {"status": True},
- }
- """
- LOG.info("add_container {}".format(ctx))
- pdp = call("moon_manager", method="get_pdp",
- ctx={"user_id": "admin", "id": ctx["id"]},
- args={})["pdps"]
- pdp_id = list(pdp.keys())[0]
- if not pdp[pdp_id]["keystone_project_id"]:
- return {"result": "False", "message": "Cannot find keystone_project_id in pdp"}
- keystone_project_id = pdp[pdp_id]["keystone_project_id"]
- self.components[ctx["id"]] = []
- for policy_key, policy_value in call("moon_manager", method="get_policies",
- ctx={"user_id": "admin", "id": None},
- args={})["policies"].items():
- if policy_key in ctx["pipeline"]:
- models = call("moon_manager", method="get_models",
- ctx={"user_id": "admin", "id": None},
- args={})["models"]
- for meta_rule in models[policy_value['model_id']]['meta_rules']:
- genre = policy_value['genre']
- pre_container_id = "pdp:{}_metarule:{}_project:{}".format(ctx["id"], meta_rule, keystone_project_id)
- container_data = {"pdp": ctx["id"], "metarule": meta_rule, "project": keystone_project_id}
- policy_component = self.docker_manager.load(component=genre,
- uuid=pre_container_id,
- container_data=container_data)
- self.components[ctx["id"]].append({
- "meta_rule_id": meta_rule,
- "genre": policy_value['genre'],
- "keystone_project_id": keystone_project_id,
- "container_id": policy_value['genre']+"_"+hashlib.sha224(pre_container_id.encode("utf-8")).hexdigest()
- })
- return {"containers": self.components[ctx["id"]]}
-
- def delete_container(self, ctx, args=None):
- """Delete a container
-
- :param ctx: {"id": "intra_extension_uuid"}
- :param args: {}
- :return: {}
- """
- try:
- self.docker_manager.kill(component_id="moon_secpolicy_"+ctx["id"])
- try:
- # FIXME (asteroide): need to select other security_function here
- self.docker_manager.kill(component_id="moon_secfunction_authz_"+ctx["id"])
- except Exception as e:
- LOG.error(e, exc_info=True)
- return {"result": True,
- "error": {'code': 200, 'title': 'Moon Warning', 'description': str(e)},
- "intra_extension_id": ctx["id"],
- "ctx": ctx, "args": args}
- except Exception as e:
- LOG.error(e, exc_info=True)
- return {"result": False,
- "error": {'code': 500, 'title': 'Moon Error', 'description': str(e)},
- "intra_extension_id": ctx["id"],
- "ctx": ctx, "args": args}
- return {"result": True}
-
diff --git a/moonv4/moon_orchestrator/moon_orchestrator/api/generic.py b/moonv4/moon_orchestrator/moon_orchestrator/api/generic.py
index cadd98d3..fd43b1c5 100644
--- a/moonv4/moon_orchestrator/moon_orchestrator/api/generic.py
+++ b/moonv4/moon_orchestrator/moon_orchestrator/api/generic.py
@@ -2,28 +2,130 @@
# 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'.
+"""
+Those API are helping API used to manage the Moon platform.
+"""
+from flask_restful import Resource, request
+import logging
+import moon_orchestrator.api
+from moon_utilities.security_functions import check_auth
-class Status(object):
+__version__ = "0.1.0"
+
+LOG = logging.getLogger("moon.orchestrator.api." + __name__)
+
+
+class Status(Resource):
"""
- Retrieve the current status of all components.
+ Endpoint for status requests
"""
- __version__ = "0.1.0"
+ __urls__ = ("/status", "/status/", "/status/<string:component_id>")
- def get_status(self, ctx, args):
- """Retrieve the current status of all components."""
- return {"status": "Running"}
+ def get(self, component_id=None):
+ """Retrieve status of all components
+ :return: {
+ "orchestrator": {
+ "status": "Running"
+ },
+ "security_router": {
+ "status": "Running"
+ }
+ }
+ """
+ raise NotImplemented
-class Logs(object):
+
+class Logs(Resource):
"""
- Retrieve the current status of all components.
+ Endpoint for logs requests
"""
- __version__ = "0.1.0"
+ __urls__ = ("/logs", "/logs/", "/logs/<string:component_id>")
+
+ def get(self, component_id=None):
+ """Get logs from the Moon platform
+
+ :param component_id: the ID of the component your are looking for (optional)
+ :return: [
+ "2015-04-15-13:45:20
+ "2015-04-15-13:45:21
+ "2015-04-15-13:45:22
+ "2015-04-15-13:45:23
+ ]
+ """
+ filter_str = request.args.get('filter', '')
+ from_str = request.args.get('from', '')
+ to_str = request.args.get('to', '')
+ event_number = request.args.get('event_number', '')
+ try:
+ event_number = int(event_number)
+ except ValueError:
+ event_number = None
+ args = dict()
+ args["filter"] = filter_str
+ args["from"] = from_str
+ args["to"] = to_str
+ args["event_number"] = event_number
+
+ raise NotImplemented
+
+
+class API(Resource):
+ """
+ Endpoint for API requests
+ """
- def get_logs(self, ctx, args):
- return {"error": "NotImplemented", "ctx": ctx, "args": args}
+ __urls__ = (
+ "/api",
+ "/api/",
+ "/api/<string:group_id>",
+ "/api/<string:group_id>/",
+ "/api/<string:group_id>/<string:endpoint_id>")
+ @check_auth
+ def get(self, group_id="", endpoint_id="", user_id=""):
+ """Retrieve all API endpoints or a specific endpoint if endpoint_id is given
+ :param group_id: the name of one existing group (ie generic, ...)
+ :param endpoint_id: the name of one existing component (ie Logs, Status, ...)
+ :return: {
+ "group_name": {
+ "endpoint_name": {
+ "description": "a description",
+ "methods": {
+ "get": "description of the HTTP method"
+ },
+ "urls": ('/api', '/api/', '/api/<string:endpoint_id>')
+ }
+ }
+ """
+ __methods = ("get", "post", "put", "delete", "options", "patch")
+ api_list = filter(lambda x: "__" not in x, dir(moon_orchestrator.api))
+ api_desc = dict()
+ for api_name in api_list:
+ api_desc[api_name] = {}
+ group_api_obj = eval("moon_interface.api.{}".format(api_name))
+ api_desc[api_name]["description"] = group_api_obj.__doc__
+ if "__version__" in dir(group_api_obj):
+ api_desc[api_name]["version"] = group_api_obj.__version__
+ object_list = list(filter(lambda x: "__" not in x, dir(group_api_obj)))
+ for obj in map(lambda x: eval("moon_interface.api.{}.{}".format(api_name, x)), object_list):
+ if "__urls__" in dir(obj):
+ api_desc[api_name][obj.__name__] = dict()
+ api_desc[api_name][obj.__name__]["urls"] = obj.__urls__
+ api_desc[api_name][obj.__name__]["methods"] = dict()
+ for _method in filter(lambda x: x in __methods, dir(obj)):
+ docstring = eval("moon_interface.api.{}.{}.{}.__doc__".format(api_name, obj.__name__, _method))
+ api_desc[api_name][obj.__name__]["methods"][_method] = docstring
+ api_desc[api_name][obj.__name__]["description"] = str(obj.__doc__)
+ if group_id in api_desc:
+ if endpoint_id in api_desc[group_id]:
+ return {group_id: {endpoint_id: api_desc[group_id][endpoint_id]}}
+ elif len(endpoint_id) > 0:
+ LOG.error("Unknown endpoint_id {}".format(endpoint_id))
+ return {"error": "Unknown endpoint_id {}".format(endpoint_id)}
+ return {group_id: api_desc[group_id]}
+ return api_desc
diff --git a/moonv4/moon_orchestrator/moon_orchestrator/api/pods.py b/moonv4/moon_orchestrator/moon_orchestrator/api/pods.py
new file mode 100644
index 00000000..319788e5
--- /dev/null
+++ b/moonv4/moon_orchestrator/moon_orchestrator/api/pods.py
@@ -0,0 +1,127 @@
+# Copyright 2015 Open Platform for NFV Project, Inc. and its contributors
+# This software is distributed under the terms and conditions of the 'Apache-2.0'
+# license which can be found in the file 'LICENSE' in this package distribution
+# or at 'http://www.apache.org/licenses/LICENSE-2.0'.
+
+from flask import request
+from flask_restful import Resource
+from moon_utilities.security_functions import check_auth
+import logging
+
+LOG = logging.getLogger("moon.orchestrator.api.pods")
+
+
+class Pods(Resource):
+ """
+ Endpoint for pdp requests
+ """
+
+ __urls__ = (
+ "/pods",
+ "/pods/",
+ "/pods/<string:uuid>",
+ "/pods/<string:uuid>/",
+ )
+
+ def __init__(self, **kwargs):
+ self.driver = kwargs.get("driver")
+ self.create_security_function = kwargs.get("create_security_function_hook")
+
+ @check_auth
+ def get(self, uuid=None, user_id=None):
+ """Retrieve all pods
+
+ :param uuid: uuid of the pod
+ :param user_id: user ID who do the request
+ :return: {
+ "pod_id1": {
+ "name": "...",
+ "replicas": "...",
+ "description": "...",
+ }
+ }
+ :internal_api: get_pdp
+ """
+ pods = {}
+ # LOG.info("pods={}".format(self.driver.get_pods()))
+ if uuid:
+ return {"pods": self.driver.get_pods(uuid)}
+ 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)
+ return {"pods": pods}
+
+ @check_auth
+ def post(self, uuid=None, user_id=None):
+ """Create a new pod.
+
+ :param uuid: uuid of the pod (not used here)
+ :param user_id: user ID who do the request
+ :request body: {
+ "name": "...",
+ "description": "...",
+ "type": "plugin_name"
+ }
+ :return: {
+ "pdp_id1": {
+ "name": "...",
+ "replicas": "...",
+ "description": "...",
+ }
+ }
+ """
+ LOG.info("POST param={}".format(request.json))
+ self.create_security_function(
+ request.json.get("keystone_project_id"),
+ request.json.get("pdp_id"),
+ request.json.get("security_pipeline"),
+ manager_data=request.json,
+ active_context=None,
+ active_context_name=None)
+ pods = {}
+ 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)
+ return {"pods": pods}
+
+ @check_auth
+ def delete(self, uuid=None, user_id=None):
+ """Delete a pod
+
+ :param uuid: uuid of the pod to delete
+ :param user_id: user ID who do the request
+ :return: {
+ "result": "True or False",
+ "message": "optional message"
+ }
+ """
+ return {"result": True}
+
+ @check_auth
+ def patch(self, uuid=None, user_id=None):
+ """Update a pod
+
+ :param uuid: uuid of the pdp to update
+ :param user_id: user ID who do the request
+ :request body: {
+ "name": "...",
+ "replicas": "...",
+ "description": "...",
+ }
+ :return: {
+ "pod_id1": {
+ "name": "...",
+ "replicas": "...",
+ "description": "...",
+ }
+ }
+ :internal_api: update_pdp
+ """
+ return {"pods": None}
+
diff --git a/moonv4/moon_orchestrator/moon_orchestrator/api/slaves.py b/moonv4/moon_orchestrator/moon_orchestrator/api/slaves.py
deleted file mode 100644
index 3a16fea1..00000000
--- a/moonv4/moon_orchestrator/moon_orchestrator/api/slaves.py
+++ /dev/null
@@ -1,78 +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'.
-
-from oslo_config import cfg
-from oslo_log import log as logging
-from uuid import uuid4
-
-LOG = logging.getLogger("moon.orchestrator.api.slaves")
-CONF = cfg.CONF
-
-
-class Slaves(object):
- """
- Manage containers.
- """
-
- __version__ = "0.1.0"
-
- def __init__(self, slaves):
- self.slaves = slaves
-
- def add_slave(self, ctx, args=None):
- """Add a new slave in the global list
-
- :param ctx: {
- "name": "name of the slave",
- "description": "description"
- }
- :param args: {}
- :return: {
- "uuid_of_the_slave": {
- "name": "name of the slave",
- "description": "description"
- }
- }
- """
- if "name" in ctx:
- for _id, _dict in self.slaves.items():
- if _dict['name'] == ctx['name']:
- LOG.warning("A slave named {} already exists!".format(ctx['name']))
- return {"slaves": {_id: _dict}}
- uuid = uuid4().hex
- ctx.pop("method")
- ctx.pop("call_master")
- self.slaves[uuid] = ctx
- LOG.info("New slave added: {}".format(ctx['name']))
- return {"slaves": {uuid: ctx}}
- LOG.warning("No name given for the new slave.")
-
- def get_slaves(self, ctx, args=None):
- """Get all the known slaves
-
- :param ctx: {}
- :param args: {}
- :return: {
- "uuid_of_the_slave": {
- "name": "name of the slave",
- "description": "description"
- }
- }
- """
- return {"slaves": self.slaves}
-
- def delete_slave(self, ctx, args=None):
- """Delete a previous slave in the global list
-
- :param ctx: {
- "id": "ID of the slave"
- }
- :param args: {}
- :return: None
- """
- if "id" in ctx:
- if ctx['id'] in self.slaves:
- self.slaves.pop(ctx['id'])
- return {"slaves": self.slaves}
diff --git a/moonv4/moon_orchestrator/moon_orchestrator/drivers.py b/moonv4/moon_orchestrator/moon_orchestrator/drivers.py
new file mode 100644
index 00000000..95000840
--- /dev/null
+++ b/moonv4/moon_orchestrator/moon_orchestrator/drivers.py
@@ -0,0 +1,175 @@
+# 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 kubernetes import client, config
+import logging
+import urllib3.exceptions
+from moon_utilities import configuration
+
+LOG = logging.getLogger("moon.orchestrator.drivers")
+
+
+def get_driver():
+ try:
+ return K8S()
+ except urllib3.exceptions.MaxRetryError as e:
+ LOG.exception(e)
+ return Docker()
+
+
+class Driver:
+
+ def __init__(self):
+ self.cache = {}
+ # example of cache:
+ # {
+ # "uuid_of_pod": {
+ # "ip": "",
+ # "hostname": "",
+ # "port": 30001,
+ # "pdp": "",
+ # "keystone_project_id": "",
+ # "plugin_name": "",
+ # "namespace": ""
+ # }
+ # }
+
+ def get_pods(self, namespace=None):
+ raise NotImplementedError
+
+ def load_pod(self, data, api_client=None, ext_client=None):
+ raise NotImplementedError
+
+ def delete_pod(self, uuid=None, name=None):
+ raise NotImplementedError
+
+ def get_slaves(self):
+ raise NotImplementedError
+
+
+class K8S(Driver):
+
+ def __init__(self):
+ super(K8S, self).__init__()
+ config.load_kube_config()
+ self.client = client.CoreV1Api()
+
+ def get_pods(self, name=None):
+ if name:
+ pods = self.client.list_pod_for_all_namespaces(watch=False)
+ for pod in pods.items:
+ LOG.info("get_pods {}".format(pod.metadata.name))
+ if name in pod.metadata.name:
+ return pod
+ else:
+ return None
+ LOG.info("get_pods cache={}".format(self.cache))
+ return self.cache
+
+ @staticmethod
+ def __create_pod(client, data):
+ pod_manifest = {
+ 'apiVersion': 'extensions/v1beta1',
+ 'kind': 'Deployment',
+ 'metadata': {
+ 'name': data[0].get('name')
+ },
+ 'spec': {
+ 'replicas': 1,
+ 'template': {
+ 'metadata': {'labels': {'app': data[0].get('name')}},
+ 'hostname': data[0].get('name'),
+ 'spec': {
+ 'containers': []
+ }
+ },
+ }
+ }
+ for _data in data:
+ pod_manifest['spec']['template']['spec']['containers'].append(
+ {
+ 'image': _data.get('container', "busybox"),
+ 'name': _data.get('name'),
+ 'hostname': _data.get('name'),
+ 'ports': [
+ {"containerPort": _data.get('port', 80)},
+ ],
+ 'env': [
+ {'name': "UUID", "value": _data.get('name', "None")},
+ {'name': "TYPE", "value": _data.get('genre', "None")},
+ {'name': "PORT", "value": str(_data.get('port', 80))},
+ {'name': "PDP_ID", "value": _data.get('pdp_id', "None")},
+ {'name': "META_RULE_ID", "value": _data.get('meta_rule_id', "None")},
+ {'name': "KEYSTONE_PROJECT_ID",
+ "value": _data.get('keystone_project_id', "None")},
+ ]
+ }
+ )
+ resp = client.create_namespaced_deployment(body=pod_manifest,
+ namespace='moon')
+ LOG.info("Pod {} created!".format(data[0].get('name')))
+ # logger.info(yaml.dump(pod_manifest, sys.stdout))
+ # logger.info(resp)
+ return resp
+
+ @staticmethod
+ def __create_service(client, data, expose=False):
+ service_manifest = {
+ 'apiVersion': 'v1',
+ 'kind': 'Service',
+ 'metadata': {
+ 'name': data.get('name'),
+ 'namespace': 'moon'
+ },
+ 'spec': {
+ 'ports': [{
+ 'port': data.get('port', 80),
+ 'targetPort': data.get('port', 80)
+ }],
+ 'selector': {
+ 'app': data.get('name')
+ },
+ # 'type': 'NodePort',
+ 'endpoints': [{
+ 'port': data.get('port', 80),
+ 'protocol': 'TCP',
+ }],
+ }
+ }
+ if expose:
+ service_manifest['spec']['ports'][0]['nodePort'] = \
+ configuration.increment_port()
+ service_manifest['spec']['type'] = "NodePort"
+ resp = client.create_namespaced_service(namespace="moon",
+ body=service_manifest)
+ LOG.info("Service {} created!".format(data.get('name')))
+ return resp
+
+ def load_pod(self, data, api_client=None, ext_client=None, expose=False):
+ _client = api_client if api_client else self.client
+ pod = self.__create_pod(client=ext_client, data=data)
+ service = self.__create_service(client=_client, data=data[0],
+ expose=expose)
+ self.cache[pod.metadata.uid] = data
+
+ def delete_pod(self, uuid=None, name=None):
+ LOG.info("Deleting pod {}".format(uuid))
+ # TODO: delete_namespaced_deployment
+ # https://github.com/kubernetes-incubator/client-python/blob/master/kubernetes/client/apis/extensions_v1beta1_api.py
+
+ def get_slaves(self):
+ contexts, active_context = config.list_kube_config_contexts()
+ return contexts, active_context
+
+
+class Docker(Driver):
+
+ def load_pod(self, data, api_client=None, ext_client=None):
+ LOG.info("Creating pod {}".format(data[0].get('name')))
+ raise NotImplementedError
+
+ def delete_pod(self, uuid=None, name=None):
+ LOG.info("Deleting pod {}".format(uuid))
+ raise NotImplementedError
diff --git a/moonv4/moon_orchestrator/moon_orchestrator/http_server.py b/moonv4/moon_orchestrator/moon_orchestrator/http_server.py
new file mode 100644
index 00000000..7aed18a6
--- /dev/null
+++ b/moonv4/moon_orchestrator/moon_orchestrator/http_server.py
@@ -0,0 +1,292 @@
+# 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 Flask, jsonify
+from flask_cors import CORS, cross_origin
+from flask_restful import Resource, Api
+import logging
+from kubernetes import client, config
+import random
+import requests
+import time
+from moon_orchestrator import __version__
+from moon_orchestrator.api.pods import Pods
+from moon_orchestrator.api.generic import Logs, Status
+from moon_utilities import configuration, exceptions
+from moon_utilities.misc import get_random_name
+from moon_orchestrator.drivers import get_driver
+
+LOG = logging.getLogger("moon.orchestrator.http")
+
+
+class Server:
+ """Base class for HTTP server"""
+
+ def __init__(self, host="localhost", port=80, api=None, **kwargs):
+ """Run a server
+
+ :param host: hostname of the server
+ :param port: port for the running server
+ :param kwargs: optional parameters
+ :return: a running server
+ """
+ self._host = host
+ self._port = port
+ self._api = api
+ self._extra = kwargs
+
+ @property
+ def host(self):
+ return self._host
+
+ @host.setter
+ def host(self, name):
+ self._host = name
+
+ @host.deleter
+ def host(self):
+ self._host = ""
+
+ @property
+ def port(self):
+ return self._port
+
+ @port.setter
+ def port(self, number):
+ self._port = number
+
+ @port.deleter
+ def port(self):
+ self._port = 80
+
+ def run(self):
+ raise NotImplementedError()
+
+__API__ = (
+ Status, Logs
+ )
+
+
+class Root(Resource):
+ """
+ The root of the web service
+ """
+ __urls__ = ("/", )
+ __methods = ("get", "post", "put", "delete", "options")
+
+ def get(self):
+ tree = {"/": {"methods": ("get",), "description": "List all methods for that service."}}
+ for item in __API__:
+ tree[item.__name__] = {"urls": item.__urls__}
+ _methods = []
+ for _method in self.__methods:
+ if _method in dir(item):
+ _methods.append(_method)
+ tree[item.__name__]["methods"] = _methods
+ tree[item.__name__]["description"] = item.__doc__.strip()
+ return {
+ "version": __version__,
+ "tree": tree
+ }
+
+
+class HTTPServer(Server):
+
+ def __init__(self, host="localhost", port=80, **kwargs):
+ super(HTTPServer, self).__init__(host=host, port=port, **kwargs)
+ self.app = Flask(__name__)
+ conf = configuration.get_configuration("components/orchestrator")
+ self.orchestrator_hostname = conf["components/orchestrator"].get("hostname", "orchestrator")
+ self.orchestrator_port = conf["components/orchestrator"].get("port", 80)
+ 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.driver = get_driver()
+ LOG.info("Driver = {}".format(self.driver.__class__))
+ self.__set_route()
+ self.__hook_errors()
+ pdp = None
+ while True:
+ try:
+ pdp = requests.get(
+ "http://{}:{}/pdp".format(self.manager_hostname,
+ self.manager_port))
+ except requests.exceptions.ConnectionError:
+ LOG.warning("Manager is not ready, standby...")
+ time.sleep(1)
+ except KeyError:
+ LOG.warning("Manager is not ready, standby...")
+ time.sleep(1)
+ else:
+ if "pdps" in pdp.json():
+ break
+ LOG.debug("pdp={}".format(pdp))
+ self.create_wrappers()
+ for _pdp_key, _pdp_value in pdp.json()['pdps'].items():
+ if _pdp_value.get('keystone_project_id'):
+ # TODO: select context to add security function
+ self.create_security_function(
+ keystone_project_id=_pdp_value.get('keystone_project_id'),
+ pdp_id=_pdp_key,
+ policy_ids=_pdp_value.get('security_pipeline', []))
+
+ 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, '/')
+
+ for api in __API__:
+ self.api.add_resource(api, *api.__urls__)
+ self.api.add_resource(Pods, *Pods.__urls__,
+ resource_class_kwargs={
+ "driver": self.driver,
+ "create_security_function_hook":
+ self.create_security_function,
+ })
+
+ def run(self):
+ self.app.run(host=self._host, port=self._port) # nosec
+
+ @staticmethod
+ def __filter_str(data):
+ return data.replace("@", "-")
+
+ def create_wrappers(self):
+ contexts, active_context = self.driver.get_slaves()
+ LOG.debug("contexts: {}".format(contexts))
+ LOG.debug("active_context: {}".format(active_context))
+ conf = configuration.get_configuration("components/wrapper")
+ hostname = conf["components/wrapper"].get(
+ "hostname", "wrapper")
+ port = conf["components/wrapper"].get("port", 80)
+ container = conf["components/wrapper"].get(
+ "container",
+ "wukongsun/moon_wrapper:v4.3")
+ for _ctx in contexts:
+ _config = config.new_client_from_config(context=_ctx['name'])
+ LOG.debug("_config={}".format(_config))
+ api_client = client.CoreV1Api(_config)
+ ext_client = client.ExtensionsV1beta1Api(_config)
+ # TODO: get data from consul
+ data = [{
+ "name": hostname + "-" + get_random_name(),
+ "container": container,
+ "port": port,
+ "namespace": "moon"
+ }, ]
+ pod = self.driver.load_pod(data, api_client, ext_client, expose=True)
+ LOG.debug('wrapper pod={}'.format(pod))
+
+ def create_security_function(self, keystone_project_id,
+ pdp_id, policy_ids, manager_data={},
+ active_context=None,
+ active_context_name=None):
+ """ Create security functions
+
+ :param policy_id: the policy ID mapped to this security function
+ :param active_context: if present, add the security function in this
+ context
+ :param active_context_name: if present, add the security function in
+ this context name
+ if active_context_name and active_context are not present, add the
+ security function in all context (ie, in all slaves)
+ :return: None
+ """
+ for key, value in self.driver.get_pods().items():
+ for _pod in value:
+ if _pod.get('keystone_project_id') == keystone_project_id:
+ LOG.warning("A pod for this Keystone project {} "
+ "already exists.".format(keystone_project_id))
+ return
+
+ plugins = configuration.get_plugins()
+ conf = configuration.get_configuration("components/interface")
+ i_hostname = conf["components/interface"].get("hostname", "interface")
+ i_port = conf["components/interface"].get("port", 80)
+ i_container = conf["components/interface"].get(
+ "container",
+ "wukongsun/moon_interface:v4.3")
+ data = [
+ {
+ "name": i_hostname + "-" + get_random_name(),
+ "container": i_container,
+ "port": i_port,
+ 'pdp_id': pdp_id,
+ 'genre': "interface",
+ 'keystone_project_id': keystone_project_id,
+ "namespace": "moon"
+ },
+ ]
+ LOG.info("data={}".format(data))
+ policies = manager_data.get('policies')
+ if not policies:
+ LOG.info("No policy data from Manager, trying to get them")
+ policies = requests.get("http://{}:{}/policies".format(
+ self.manager_hostname, self.manager_port)).json().get(
+ "policies", dict())
+ LOG.info("policies={}".format(policies))
+ models = manager_data.get('models')
+ if not models:
+ LOG.info("No models data from Manager, trying to get them")
+ models = requests.get("http://{}:{}/models".format(
+ self.manager_hostname, self.manager_port)).json().get(
+ "models", dict())
+ LOG.info("models={}".format(models))
+
+ for policy_id in policy_ids:
+ if policy_id in policies:
+ genre = policies[policy_id].get("genre", "authz")
+ if genre in plugins:
+ for meta_rule in models[policies[policy_id]['model_id']]['meta_rules']:
+ data.append({
+ "name": genre + "-" + get_random_name(),
+ "container": plugins[genre]['container'],
+ 'pdp_id': pdp_id,
+ "port": plugins[genre].get('port', 8080),
+ 'genre': genre,
+ 'policy_id': policy_id,
+ 'meta_rule_id': meta_rule,
+ 'keystone_project_id': keystone_project_id,
+ "namespace": "moon"
+ })
+ LOG.info("data={}".format(data))
+ contexts, _active_context = self.driver.get_slaves()
+ LOG.info("active_context_name={}".format(active_context_name))
+ LOG.info("active_context={}".format(active_context))
+ if active_context_name:
+ for _context in contexts:
+ if _context["name"] == active_context_name:
+ active_context = _context
+ break
+ if active_context:
+ active_context = _active_context
+ _config = config.new_client_from_config(
+ context=active_context['name'])
+ LOG.debug("_config={}".format(_config))
+ api_client = client.CoreV1Api(_config)
+ ext_client = client.ExtensionsV1beta1Api(_config)
+ self.driver.load_pod(data, api_client, ext_client, expose=False)
+ return
+ LOG.info("contexts={}".format(contexts))
+ for _ctx in contexts:
+ _config = config.new_client_from_config(context=_ctx['name'])
+ LOG.debug("_config={}".format(_config))
+ api_client = client.CoreV1Api(_config)
+ ext_client = client.ExtensionsV1beta1Api(_config)
+ self.driver.load_pod(data, api_client, ext_client, expose=False)
+
+
diff --git a/moonv4/moon_orchestrator/moon_orchestrator/messenger.py b/moonv4/moon_orchestrator/moon_orchestrator/messenger.py
deleted file mode 100644
index 2b7b3866..00000000
--- a/moonv4/moon_orchestrator/moon_orchestrator/messenger.py
+++ /dev/null
@@ -1,63 +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 oslo_messaging
-from oslo_log import log as logging
-import time
-from moon_utilities.api import APIList
-from moon_utilities import configuration
-
-from oslo_config import cfg
-from moon_orchestrator.api.generic import Status, Logs
-from moon_orchestrator.api.containers import Containers
-from moon_orchestrator.api.slaves import Slaves
-
-TOPIC = "orchestrator"
-LOG = logging.getLogger("moon.orchestrator.messenger")
-CONF = cfg.CONF
-
-
-class Server:
-
- def __init__(self, containers, docker_manager, slaves):
- cfg.CONF.transport_url = self.__get_transport_url()
- self.CONTAINERS = containers
- self.transport = oslo_messaging.get_transport(cfg.CONF)
- self.target = oslo_messaging.Target(topic=TOPIC, server='server1')
- LOG.info("Starting MQ server with topic: {}".format(TOPIC))
- self.docker_manager = docker_manager
- for _container in containers:
- Status._container = containers[_container]
- self.endpoints = [
- APIList((Status, Logs, Containers)),
- Status(),
- Logs(),
- Containers(self.docker_manager),
- Slaves(slaves)
- ]
- self.server = oslo_messaging.get_rpc_server(self.transport, self.target, self.endpoints,
- executor='threading',
- access_policy=oslo_messaging.DefaultRPCAccessPolicy)
-
- @staticmethod
- def __get_transport_url():
- messenger = configuration.get_configuration(configuration.MESSENGER)["messenger"]
- return messenger['url']
-
- def run(self):
- try:
- self.server.start()
- while True:
- time.sleep(1)
- except KeyboardInterrupt:
- LOG.warning("Stopping server by crtl+c (please be patient, closing connections...)")
- except SystemExit:
- LOG.warning("Stopping server (please be patient, closing connections...)")
- except Exception as e:
- LOG.error("Exception occurred: {}".format(e))
-
- self.server.stop()
- self.server.wait()
-
diff --git a/moonv4/moon_orchestrator/moon_orchestrator/server.py b/moonv4/moon_orchestrator/moon_orchestrator/server.py
index 8fd2740f..5e16bfcd 100644
--- a/moonv4/moon_orchestrator/moon_orchestrator/server.py
+++ b/moonv4/moon_orchestrator/moon_orchestrator/server.py
@@ -3,175 +3,34 @@
# 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 os
-import hashlib
-from oslo_log import log as logging
-from docker import Client
-import docker.errors as docker_errors
+import logging
from moon_utilities import configuration, exceptions
-from moon_orchestrator import messenger
-
+from moon_orchestrator.http_server import HTTPServer
LOG = logging.getLogger("moon.orchestrator")
+DOMAIN = "moon_orchestrator"
-CONTAINERS = {}
-SLAVES = {}
-docker_conf = configuration.get_configuration("docker")['docker']
-docker = Client(base_url=docker_conf['url'])
-LOG.info("docker_url={}".format(docker_conf['url']))
-docker_network = docker_conf['network']
-
-
-def kill_handler(signum, frame):
- _exit(0)
-
-
-class DockerManager:
-
- def load(self, component, uuid=None, container_data=None):
- """Load a new docker mapping the component given
-
- :param component: the name of the component (policy or function)
- :param uuid: the uuid of the intra_extension linked to that component
- :return: the created component
- """
- component_id = component+"_"+hashlib.sha224(uuid.encode("utf-8")).hexdigest()
- plugins = configuration.get_plugins()
- if component in plugins.keys():
- components = configuration.get_components()
- configuration.add_component(
- name=component_id,
- uuid=component_id,
- port=configuration.increment_port(),
- bind="0.0.0.0",
- extra=container_data,
- container=plugins[component]['container']
- )
- # _command = plugins[component]['command']
- # try:
- # _index = _command.index("<UUID>")
- # _command[_index] = component_id
- # except ValueError:
- # pass
- self.run(component_id, environment={"UUID": component_id})
- CONTAINERS[component_id] = components.get(component_id)
- CONTAINERS[component_id]["running"] = True
- return CONTAINERS[component_id]
-
- def load_all_containers(self):
- LOG.info("Try to load all containers...")
- current_containers = [item["Names"][0] for item in docker.containers()]
- components = configuration.get_components()
- containers_not_running = []
- for c_name in (
- '/keystone',
- '/consul',
- '/db',
- '/messenger'
- ):
- if c_name not in current_containers:
- containers_not_running.append(c_name)
- if containers_not_running:
- raise exceptions.ContainerMissing(
- "Following containers are missing: {}".format(", ".join(containers_not_running)))
- for c_name in (
- '/interface',
- '/manager',
- '/router'):
- if c_name not in current_containers:
- LOG.info("Starting container {}...".format(c_name))
- self.run(c_name.strip("/"))
- else:
- LOG.info("Container {} already running...".format(c_name))
- CONTAINERS[c_name] = components.get(c_name.strip("/"))
- CONTAINERS[c_name]["running"] = True
-
- def run(self, name, environment=None):
- components = configuration.get_components()
- if name in components:
- image = components[name]['container']
- params = {
- 'image': image,
- 'name': name,
- 'hostname': name,
- 'detach': True,
- 'host_config': docker.create_host_config(network_mode=docker_network)
- }
- if 'port' in components[name] and components[name]['port']:
- params["ports"] = [components[name]['port'], ]
- params["host_config"] = docker.create_host_config(
- network_mode=docker_network,
- port_bindings={components[name]['port']: components[name]['port']}
- )
- if environment:
- params["environment"] = environment
- container = docker.create_container(**params)
- docker.start(container=container.get('Id'))
-
- @staticmethod
- def get_component(uuid=None):
- if uuid:
- return CONTAINERS.get(uuid, None)
- return CONTAINERS
-
- @staticmethod
- def kill(component_id, delete=True):
- LOG.info("Killing container {}".format(component_id))
- docker.kill(container=component_id)
- if delete:
- docker.remove_container(container=component_id)
-
+__CWD__ = os.path.dirname(os.path.abspath(__file__))
-def _exit(exit_number=0, error=None):
- for _container in CONTAINERS:
- LOG.warning("Deleting containers named {}...".format(_container))
- # print(40 * "-" + _container)
- try:
- # print(docker.logs(container=_container).decode("utf-8"))
- docker.kill(container=_container)
- except docker_errors.NotFound:
- LOG.error("The container {} was not found".format(_container))
- except docker_errors.APIError as e:
- LOG.error(e)
- else:
- docker.remove_container(container=_container)
- LOG.info("Moon orchestrator: offline")
-
- # TODO (asteroide): put in the debug log
- if error:
- LOG.info(str(error))
- sys.exit(exit_number)
-
-
-def __save_pid():
- try:
- open("/var/run/moon_orchestrator.pid", "w").write(str(os.getpid()))
- except PermissionError:
- LOG.warning("You don't have the right to write PID file in /var/run... Continuing anyway.")
- LOG.warning("Writing PID file in {}".format(os.getcwd()))
- open("./moon_orchestrator.pid", "w").write(str(os.getpid()))
-
-
-def server():
+def main():
configuration.init_logging()
- conf = configuration.add_component("orchestrator", "orchestrator")
- LOG.info("Starting main server {}".format(conf["components/orchestrator"]["hostname"]))
-
- docker_manager = DockerManager()
-
- docker_manager.load_all_containers()
- serv = messenger.Server(containers=CONTAINERS, docker_manager=docker_manager, slaves=SLAVES)
try:
- serv.run()
- finally:
- _exit(0)
-
-
-def main():
- server()
+ conf = configuration.get_configuration("components/orchestrator")
+ hostname = conf["components/orchestrator"].get("hostname", "orchestrator")
+ port = conf["components/orchestrator"].get("port", 80)
+ bind = conf["components/orchestrator"].get("bind", "127.0.0.1")
+ except exceptions.ConsulComponentNotFound:
+ hostname = "orchestrator"
+ bind = "127.0.0.1"
+ port = 80
+ configuration.add_component(uuid="orchestrator", name=hostname, port=port, bind=bind)
+ LOG.info("Starting server with IP {} on port {} bind to {}".format(hostname, port, bind))
+ server = HTTPServer(host=bind, port=port)
+ return server
if __name__ == '__main__':
- main()
+ server = main()
+ server.run()
diff --git a/moonv4/moon_orchestrator/requirements.txt b/moonv4/moon_orchestrator/requirements.txt
index c7653278..6197f10f 100644
--- a/moonv4/moon_orchestrator/requirements.txt
+++ b/moonv4/moon_orchestrator/requirements.txt
@@ -1,12 +1,8 @@
-docker-py
-kombu !=4.0.1,!=4.0.0
-oslo.messaging !=5.14.0,!=5.13.0
-oslo.config
-oslo.log
-vine
-jinja2
-sqlalchemy
-pymysql
+flask
+flask_restful
+flask_cors
werkzeug
moon_utilities
-moon_db \ No newline at end of file
+moon_db
+kubernetes
+pyaml \ No newline at end of file
diff --git a/moonv4/moon_orchestrator/tests/unit_python/conftest.py b/moonv4/moon_orchestrator/tests/unit_python/conftest.py
new file mode 100644
index 00000000..044489e6
--- /dev/null
+++ b/moonv4/moon_orchestrator/tests/unit_python/conftest.py
@@ -0,0 +1,18 @@
+import pytest
+import requests_mock
+import mock_pods
+from utilities import CONTEXT
+
+
+@pytest.fixture
+def context():
+ return CONTEXT
+
+
+@pytest.fixture(autouse=True)
+def no_requests(monkeypatch):
+ """ Modify the response from Requests module
+ """
+ with requests_mock.Mocker(real_http=True) as m:
+ mock_pods.register_pods(m)
+ yield m \ No newline at end of file
diff --git a/moonv4/moon_orchestrator/tests/unit_python/mock_pods.py b/moonv4/moon_orchestrator/tests/unit_python/mock_pods.py
new file mode 100644
index 00000000..c5633152
--- /dev/null
+++ b/moonv4/moon_orchestrator/tests/unit_python/mock_pods.py
@@ -0,0 +1,404 @@
+from kubernetes import client, config
+from utilities import CONF, get_b64_conf, COMPONENTS
+
+pdp_mock = {
+ "pdp_id1": {
+ "name": "...",
+ "security_pipeline": ["policy_id_1", "policy_id_2"],
+ "keystone_project_id": "keystone_project_id1",
+ "description": "...",
+ },
+ "pdp_id12": {
+ "name": "...",
+ "security_pipeline": ["policy_id_1", "policy_id_2"],
+ "keystone_project_id": "keystone_project_id1",
+ "description": "...",
+ }
+}
+
+meta_rules_mock = {
+ "meta_rule_id1": {
+ "name": "meta_rule1",
+ "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"]
+ },
+ "meta_rule_id2": {
+ "name": "name of the meta rules2",
+ "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"]
+ }
+}
+
+policies_mock = {
+ "policy_id_1": {
+ "name": "test_policy1",
+ "model_id": "model_id_1",
+ "genre": "authz",
+ "description": "test",
+ },
+ "policy_id_2": {
+ "name": "test_policy2",
+ "model_id": "model_id_2",
+ "genre": "authz",
+ "description": "test",
+ }
+}
+
+subject_mock = {
+ "policy_id_1": {
+ "subject_id": {
+ "name": "subject_name",
+ "keystone_id": "keystone_project_id1",
+ "description": "a description"
+ }
+ },
+ "policy_id_2": {
+ "subject_id": {
+ "name": "subject_name",
+ "keystone_id": "keystone_project_id1",
+ "description": "a description"
+ }
+ }
+}
+
+subject_assignment_mock = {
+ "subject_id": {
+ "policy_id": "ID of the policy",
+ "subject_id": "ID of the subject",
+ "category_id": "ID of the category",
+ "assignments": [],
+ }
+}
+
+object_mock = {
+ "policy_id_1": {
+ "object_id": {
+ "name": "object_name",
+ "description": "a description"
+ }
+ },
+ "policy_id_2": {
+ "object_id": {
+ "name": "object_name",
+ "description": "a description"
+ }
+ }
+}
+
+object_assignment_mock = {
+ "object_id": {
+ "policy_id": "ID of the policy",
+ "object_id": "ID of the object",
+ "category_id": "ID of the category",
+ "assignments": [],
+ }
+}
+
+action_mock = {
+ "policy_id_1": {
+ "action_id": {
+ "name": "action_name",
+ "description": "a description"
+ }
+ },
+ "policy_id_2": {
+ "action_id": {
+ "name": "action_name",
+ "description": "a description"
+ }
+ }
+}
+
+action_assignment_mock = {
+ "action_id": {
+ "policy_id": "ID of the policy",
+ "action_id": "ID of the action",
+ "category_id": "ID of the category",
+ "assignments": [],
+ }
+}
+
+models_mock = {
+ "model_id_1": {
+ "name": "test_model",
+ "description": "test",
+ "meta_rules": ["meta_rule_id1"]
+ },
+ "model_id_2": {
+ "name": "test_model",
+ "description": "test",
+ "meta_rules": ["meta_rule_id2"]
+ },
+}
+
+rules_mock = {
+ "rules": {
+ "meta_rule_id": "meta_rule_id1",
+ "rule_id1": {
+ "rule": ["subject_data_id1",
+ "object_data_id1",
+ "action_data_id1"],
+ "instructions": (
+ {"decision": "grant"},
+ # "grant" to immediately exit,
+ # "continue" to wait for the result of next policy
+ # "deny" to deny the request
+ )
+ },
+ "rule_id2": {
+ "rule": ["subject_data_id2",
+ "object_data_id2",
+ "action_data_id2"],
+ "instructions": (
+ {
+ "update": {
+ "operation": "add",
+ # operations may be "add" or "delete"
+ "target": "rbac:role:admin"
+ # add the role admin to the current user
+ }
+ },
+ {"chain": {"name": "rbac"}}
+ # chain with the policy named rbac
+ )
+ }
+ }
+}
+
+
+def patch_k8s(monkeypatch):
+ def _load_kube_config_mockreturn(*args, **kwargs):
+ return
+ monkeypatch.setattr(config, 'load_kube_config',
+ _load_kube_config_mockreturn)
+
+ def list_kube_config_contexts_mockreturn(*args, **kwargs):
+ return [{"name": "active_context"}], {"name": "active_context"}
+ monkeypatch.setattr(config, 'list_kube_config_contexts',
+ list_kube_config_contexts_mockreturn)
+
+ def new_client_from_config_mockreturn(*args, **kwargs):
+ return {"client": True}
+ monkeypatch.setattr(config, 'new_client_from_config',
+ new_client_from_config_mockreturn)
+
+ def list_pod_for_all_namespaces_mockreturn(*args, **kwargs):
+ class pods:
+ items = []
+ return pods
+ monkeypatch.setattr(client.CoreV1Api, 'list_pod_for_all_namespaces',
+ list_pod_for_all_namespaces_mockreturn)
+
+ def create_namespaced_deployment_mockreturn(*args, **kwargs):
+
+ class metadata:
+ uid = "123456789"
+
+ class pod:
+ def __init__(self):
+ self.metadata = metadata()
+ return pod()
+ monkeypatch.setattr(client.ExtensionsV1beta1Api,
+ 'create_namespaced_deployment',
+ create_namespaced_deployment_mockreturn)
+
+ def create_namespaced_service_mockreturn(*args, **kwargs):
+ return {}
+ monkeypatch.setattr(client.CoreV1Api,
+ 'create_namespaced_service',
+ create_namespaced_service_mockreturn)
+
+
+def register_pods(m):
+ """ Modify the response from Requests module
+ """
+ register_consul(m)
+ register_pdp(m)
+ # register_meta_rules(m)
+ register_policies(m)
+ register_models(m)
+ # register_policy_subject(m, "policy_id_1")
+ # register_policy_subject(m, "policy_id_2")
+ # register_policy_object(m, "policy_id_1")
+ # register_policy_object(m, "policy_id_2")
+ # register_policy_action(m, "policy_id_1")
+ # register_policy_action(m, "policy_id_2")
+ # register_policy_subject_assignment(m, "policy_id_1", "subject_id")
+ # register_policy_subject_assignment_list(m1, "policy_id_1")
+ # register_policy_subject_assignment(m, "policy_id_2", "subject_id")
+ # register_policy_subject_assignment_list(m1, "policy_id_2")
+ # register_policy_object_assignment(m, "policy_id_1", "object_id")
+ # register_policy_object_assignment_list(m1, "policy_id_1")
+ # register_policy_object_assignment(m, "policy_id_2", "object_id")
+ # register_policy_object_assignment_list(m1, "policy_id_2")
+ # register_policy_action_assignment(m, "policy_id_1", "action_id")
+ # register_policy_action_assignment_list(m1, "policy_id_1")
+ # register_policy_action_assignment(m, "policy_id_2", "action_id")
+ # register_policy_action_assignment_list(m1, "policy_id_2")
+ # register_rules(m, "policy_id1")
+
+
+def register_consul(m):
+ for component in COMPONENTS:
+ m.register_uri(
+ 'GET', 'http://consul:8500/v1/kv/{}'.format(component),
+ json=[{'Key': component, 'Value': get_b64_conf(component)}]
+ )
+ m.register_uri(
+ 'GET', 'http://consul:8500/v1/kv/components_port_start',
+ json=[
+ {
+ "LockIndex": 0,
+ "Key": "components_port_start",
+ "Flags": 0,
+ "Value": "MzEwMDE=",
+ "CreateIndex": 9,
+ "ModifyIndex": 9
+ }
+ ],
+ )
+ m.register_uri(
+ 'PUT', 'http://consul:8500/v1/kv/components_port_start',
+ json=[],
+ )
+ m.register_uri(
+ 'GET', 'http://consul:8500/v1/kv/plugins?recurse=true',
+ json=[
+ {
+ "LockIndex": 0,
+ "Key": "plugins/authz",
+ "Flags": 0,
+ "Value": "eyJjb250YWluZXIiOiAid3Vrb25nc3VuL21vb25fYXV0aHo6djQuMyIsICJwb3J0IjogODA4MX0=",
+ "CreateIndex": 14,
+ "ModifyIndex": 656
+ }
+ ],
+ )
+
+
+def register_pdp(m):
+ m.register_uri(
+ 'GET', 'http://{}:{}/{}'.format(CONF['components']['manager']['hostname'],
+ CONF['components']['manager']['port'], 'pdp'),
+ json={'pdps': pdp_mock}
+ )
+
+
+def register_meta_rules(m):
+ m.register_uri(
+ 'GET', 'http://{}:{}/{}'.format(CONF['components']['manager']['hostname'],
+ CONF['components']['manager']['port'], 'meta_rules'),
+ json={'meta_rules': meta_rules_mock}
+ )
+
+
+def register_policies(m):
+ m.register_uri(
+ 'GET', 'http://{}:{}/{}'.format(CONF['components']['manager']['hostname'],
+ CONF['components']['manager']['port'], 'policies'),
+ json={'policies': policies_mock}
+ )
+
+
+def register_models(m):
+ m.register_uri(
+ 'GET', 'http://{}:{}/{}'.format(CONF['components']['manager']['hostname'],
+ CONF['components']['manager']['port'], 'models'),
+ json={'models': models_mock}
+ )
+
+
+def register_policy_subject(m, policy_id):
+ m.register_uri(
+ 'GET', 'http://{}:{}/{}/{}/subjects'.format(CONF['components']['manager']['hostname'],
+ CONF['components']['manager']['port'], 'policies', policy_id),
+ json={'subjects': subject_mock[policy_id]}
+ )
+
+
+def register_policy_object(m, policy_id):
+ m.register_uri(
+ 'GET', 'http://{}:{}/{}/{}/objects'.format(CONF['components']['manager']['hostname'],
+ CONF['components']['manager']['port'], 'policies', policy_id),
+ json={'objects': object_mock[policy_id]}
+ )
+
+
+def register_policy_action(m, policy_id):
+ m.register_uri(
+ 'GET', 'http://{}:{}/{}/{}/actions'.format(CONF['components']['manager']['hostname'],
+ CONF['components']['manager']['port'], 'policies', policy_id),
+ json={'actions': action_mock[policy_id]}
+ )
+
+
+def register_policy_subject_assignment(m, policy_id, subj_id):
+ m.register_uri(
+ 'GET', 'http://{}:{}/{}/{}/subject_assignments/{}'.format(CONF['components']['manager']['hostname'],
+ CONF['components']['manager']['port'], 'policies',
+ policy_id,
+ subj_id),
+ json={'subject_assignments': subject_assignment_mock}
+ )
+
+
+def register_policy_subject_assignment_list(m, policy_id):
+ m.register_uri(
+ 'GET', 'http://{}:{}/{}/{}/subject_assignments'.format(CONF['components']['manager']['hostname'],
+ CONF['components']['manager']['port'], 'policies',
+ policy_id),
+ json={'subject_assignments': subject_assignment_mock}
+ )
+
+
+def register_policy_object_assignment(m, policy_id, obj_id):
+ m.register_uri(
+ 'GET', 'http://{}:{}/{}/{}/object_assignments/{}'.format(CONF['components']['manager']['hostname'],
+ CONF['components']['manager']['port'], 'policies',
+ policy_id,
+ obj_id),
+ json={'object_assignments': object_assignment_mock}
+ )
+
+
+def register_policy_object_assignment_list(m, policy_id):
+ m.register_uri(
+ 'GET', 'http://{}:{}/{}/{}/object_assignments'.format(CONF['components']['manager']['hostname'],
+ CONF['components']['manager']['port'], 'policies',
+ policy_id),
+ json={'object_assignments': object_assignment_mock}
+ )
+
+
+def register_policy_action_assignment(m, policy_id, action_id):
+ m.register_uri(
+ 'GET', 'http://{}:{}/{}/{}/action_assignments/{}'.format(CONF['components']['manager']['hostname'],
+ CONF['components']['manager']['port'], 'policies',
+ policy_id,
+ action_id),
+ json={'action_assignments': action_assignment_mock}
+ )
+
+
+def register_policy_action_assignment_list(m, policy_id):
+ m.register_uri(
+ 'GET', 'http://{}:{}/{}/{}/action_assignments'.format(CONF['components']['manager']['hostname'],
+ CONF['components']['manager']['port'], 'policies',
+ policy_id),
+ json={'action_assignments': action_assignment_mock}
+ )
+
+
+def register_rules(m, policy_id):
+ m.register_uri(
+ 'GET', 'http://{}:{}/{}/{}/{}'.format(CONF['components']['manager']['hostname'],
+ CONF['components']['manager']['port'], 'policies',
+ policy_id, 'rules'),
+ json={'rules': rules_mock}
+ ) \ No newline at end of file
diff --git a/moonv4/moon_orchestrator/tests/unit_python/requirements.txt b/moonv4/moon_orchestrator/tests/unit_python/requirements.txt
new file mode 100644
index 00000000..8bd8449f
--- /dev/null
+++ b/moonv4/moon_orchestrator/tests/unit_python/requirements.txt
@@ -0,0 +1,5 @@
+flask
+flask_cors
+flask_restful
+moon_db
+moon_utilities \ No newline at end of file
diff --git a/moonv4/moon_orchestrator/tests/unit_python/test_pods.py b/moonv4/moon_orchestrator/tests/unit_python/test_pods.py
new file mode 100644
index 00000000..42c8404b
--- /dev/null
+++ b/moonv4/moon_orchestrator/tests/unit_python/test_pods.py
@@ -0,0 +1,43 @@
+import json
+from mock_pods import patch_k8s
+from utilities import get_json
+
+
+def test_get_pods(context, monkeypatch):
+ patch_k8s(monkeypatch)
+
+ import moon_orchestrator.server
+ server = moon_orchestrator.server.main()
+ _client = server.app.test_client()
+ req = _client.get("/pods")
+ assert req.status_code == 200
+ assert req.data
+ data = get_json(req.data)
+ assert isinstance(data, dict)
+ assert "pods" in data
+
+
+def test_add_pods(context, monkeypatch):
+ patch_k8s(monkeypatch)
+
+ import moon_orchestrator.server
+ server = moon_orchestrator.server.main()
+ _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)
+ assert isinstance(data, dict)
+ assert "pods" in data
+ assert data["pods"]
+
+
+def test_delete_pods(context, monkeypatch):
+ # TODO
+ pass
diff --git a/moonv4/moon_orchestrator/tests/unit_python/utilities.py b/moonv4/moon_orchestrator/tests/unit_python/utilities.py
new file mode 100644
index 00000000..aec03d9d
--- /dev/null
+++ b/moonv4/moon_orchestrator/tests/unit_python/utilities.py
@@ -0,0 +1,173 @@
+import base64
+import json
+import pytest
+from uuid import uuid4
+
+
+CONF = {
+ "openstack": {
+ "keystone": {
+ "url": "http://keystone:5000/v3",
+ "user": "admin",
+ "check_token": False,
+ "password": "p4ssw0rd",
+ "domain": "default",
+ "certificate": False,
+ "project": "admin"
+ }
+ },
+ "components": {
+ "wrapper": {
+ "bind": "0.0.0.0",
+ "port": 8080,
+ "container": "wukongsun/moon_wrapper:v4.3",
+ "timeout": 5,
+ "hostname": "wrapper"
+ },
+ "manager": {
+ "bind": "0.0.0.0",
+ "port": 8082,
+ "container": "wukongsun/moon_manager:v4.3",
+ "hostname": "manager"
+ },
+ "port_start": 31001,
+ "orchestrator": {
+ "bind": "0.0.0.0",
+ "port": 8083,
+ "container": "wukongsun/moon_orchestrator:v4.3",
+ "hostname": "interface"
+ },
+ "interface": {
+ "bind": "0.0.0.0",
+ "port": 8080,
+ "container": "wukongsun/moon_interface:v4.3",
+ "hostname": "interface"
+ }
+ },
+ "plugins": {
+ "session": {
+ "port": 8082,
+ "container": "asteroide/session:latest"
+ },
+ "authz": {
+ "port": 8081,
+ "container": "wukongsun/moon_authz:v4.3"
+ }
+ },
+ "logging": {
+ "handlers": {
+ "file": {
+ "filename": "/tmp/moon.log",
+ "class": "logging.handlers.RotatingFileHandler",
+ "level": "DEBUG",
+ "formatter": "custom",
+ "backupCount": 3,
+ "maxBytes": 1048576
+ },
+ "console": {
+ "class": "logging.StreamHandler",
+ "formatter": "brief",
+ "level": "INFO",
+ "stream": "ext://sys.stdout"
+ }
+ },
+ "formatters": {
+ "brief": {
+ "format": "%(levelname)s %(name)s %(message)-30s"
+ },
+ "custom": {
+ "format": "%(asctime)-15s %(levelname)s %(name)s %(message)s"
+ }
+ },
+ "root": {
+ "handlers": [
+ "console"
+ ],
+ "level": "ERROR"
+ },
+ "version": 1,
+ "loggers": {
+ "moon": {
+ "handlers": [
+ "console",
+ "file"
+ ],
+ "propagate": False,
+ "level": "DEBUG"
+ }
+ }
+ },
+ "slave": {
+ "name": None,
+ "master": {
+ "url": None,
+ "login": None,
+ "password": None
+ }
+ },
+ "docker": {
+ "url": "tcp://172.88.88.1:2376",
+ "network": "moon"
+ },
+ "database": {
+ "url": "sqlite:///database.db",
+ # "url": "mysql+pymysql://moon:p4sswOrd1@db/moon",
+ "driver": "sql"
+ },
+ "messenger": {
+ "url": "rabbit://moon:p4sswOrd1@messenger:5672/moon"
+ }
+}
+
+
+CONTEXT = {
+ "project_id": "a64beb1cc224474fb4badd43173e7101",
+ "subject_name": "testuser",
+ "object_name": "vm1",
+ "action_name": "boot",
+ "request_id": uuid4().hex,
+ "interface_name": "interface",
+ "manager_url": "http://{}:{}".format(
+ CONF["components"]["manager"]["hostname"],
+ CONF["components"]["manager"]["port"]
+ ),
+ "cookie": uuid4().hex,
+ "pdp_id": "b3d3e18abf3340e8b635fd49e6634ccd",
+ "security_pipeline": ["f8f49a779ceb47b3ac810f01ef71b4e0"]
+ }
+
+
+COMPONENTS = (
+ "logging",
+ "openstack/keystone",
+ "database",
+ "slave",
+ "components/manager",
+ "components/orchestrator",
+ "components/interface",
+ "components/wrapper",
+)
+
+
+def get_b64_conf(component=None):
+ if component == "components":
+ return base64.b64encode(
+ json.dumps(CONF["components"]).encode('utf-8')+b"\n").decode('utf-8')
+ elif component in CONF:
+ return base64.b64encode(
+ json.dumps(
+ CONF[component]).encode('utf-8')+b"\n").decode('utf-8')
+ elif not component:
+ return base64.b64encode(
+ json.dumps(CONF).encode('utf-8')+b"\n").decode('utf-8')
+ elif "/" in component:
+ key1, _, key2 = component.partition("/")
+ return base64.b64encode(
+ json.dumps(
+ CONF[key1][key2]).encode('utf-8')+b"\n").decode('utf-8')
+
+
+def get_json(data):
+ return json.loads(data.decode("utf-8"))
+
+
diff --git a/moonv4/moon_router/Dockerfile b/moonv4/moon_router/Dockerfile
deleted file mode 100644
index 1722b801..00000000
--- a/moonv4/moon_router/Dockerfile
+++ /dev/null
@@ -1,11 +0,0 @@
-FROM ubuntu:latest
-
-RUN apt update && apt install python3.5 python3-pip -y
-RUN pip3 install pip --upgrade
-
-ADD . /root
-WORKDIR /root/
-RUN pip3 install -r requirements.txt --upgrade
-RUN pip3 install .
-
-CMD ["python3", "-m", "moon_router"] \ No newline at end of file
diff --git a/moonv4/moon_router/README.md b/moonv4/moon_router/README.md
deleted file mode 100644
index 91899b31..00000000
--- a/moonv4/moon_router/README.md
+++ /dev/null
@@ -1,18 +0,0 @@
-# Router: Core module for the Moon project
-
-This package contains the core module for the Moon project
-It is designed to provide authorization features to all OpenStack components.
-
-For any other information, refer to the parent project:
-
- https://git.opnfv.org/moon
-
-## Build Image
-```bash
-docker image build -t wukongsun/moon_router:v4.1 .
-```
-
-## Push Image
-```bash
-docker push wukongsun/moon_router:v4.1
-``` \ No newline at end of file
diff --git a/moonv4/moon_router/doc/api-moon-secrouter.pdf b/moonv4/moon_router/doc/api-moon-secrouter.pdf
deleted file mode 100644
index 9ba75db0..00000000
--- a/moonv4/moon_router/doc/api-moon-secrouter.pdf
+++ /dev/null
Binary files differ
diff --git a/moonv4/moon_router/doc/api.pdf b/moonv4/moon_router/doc/api.pdf
deleted file mode 100644
index b7d91293..00000000
--- a/moonv4/moon_router/doc/api.pdf
+++ /dev/null
Binary files differ
diff --git a/moonv4/moon_router/moon_router/__main__.py b/moonv4/moon_router/moon_router/__main__.py
deleted file mode 100644
index 0d7a8fe6..00000000
--- a/moonv4/moon_router/moon_router/__main__.py
+++ /dev/null
@@ -1,3 +0,0 @@
-from moon_router.server import main
-
-main()
diff --git a/moonv4/moon_router/moon_router/api/generic.py b/moonv4/moon_router/moon_router/api/generic.py
deleted file mode 100644
index d066f715..00000000
--- a/moonv4/moon_router/moon_router/api/generic.py
+++ /dev/null
@@ -1,46 +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'.
-from moon_utilities.security_functions import call
-
-
-class Status(object):
- """
- Retrieve the current status of all components.
- """
-
- __version__ = "0.1.0"
-
- def __get_status(self, ctx, args={}):
- return {"status": "Running"}
-
- def get_status(self, ctx, args={}):
- status = dict()
- if "component_id" in ctx and ctx["component_id"] == "security_router":
- return {"security_router": self.__get_status(ctx, args)}
- elif "component_id" in ctx and ctx["component_id"]:
- # TODO (dthom): check if component exist
- status[ctx["component_id"]] = call(ctx["component_id"], ctx, "get_status", args=args)
- else:
- # TODO (dthom): must get the status of all containers
- status["orchestrator"] = call("orchestrator", ctx, "get_status", args=args)
- status["security_router"] = self.__get_status(ctx, args)
- return status
-
-
-class Logs(object):
- """
- Retrieve the current status of all components.
- """
-
- __version__ = "0.1.0"
-
- def get_logs(self, ctx, args={}):
- logs = dict()
- logs["orchestrator"] = call("orchestrator", ctx, "get_logs", args=args)
- # TODO (dthom): must get the logs of all containers
- logs["security_router"] = {"error": "Not implemented", "ctx": ctx, "args": args}
- return logs
-
-
diff --git a/moonv4/moon_router/moon_router/api/route.py b/moonv4/moon_router/moon_router/api/route.py
deleted file mode 100644
index c9cfb82a..00000000
--- a/moonv4/moon_router/moon_router/api/route.py
+++ /dev/null
@@ -1,472 +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 copy
-import time
-import itertools
-from uuid import uuid4
-from oslo_log import log as logging
-from moon_utilities.security_functions import call, notify
-from moon_router.api.generic import Status, Logs
-from moon_utilities import configuration
-
-LOG = logging.getLogger("moon.router.api.route")
-
-API = {
- "orchestrator": (
- "add_container",
- "delete_container",
- "add_slave",
- "get_slaves",
- "delete_slave"
- ),
- # TODO (asteroide): need to check if some of those calls need (or not) to be called "update_"
- "manager": (
- "get_subject_assignments",
- "set_subject_assignment",
- "delete_subject_assignment",
- "get_object_assignments",
- "set_object_assignment",
- "delete_object_assignment",
- "get_action_assignments",
- "set_action_assignment",
- "delete_action_assignment",
- "get_subject_data",
- "add_subject_data",
- "delete_subject_data",
- "get_object_data",
- "add_object_data",
- "delete_object_data",
- "get_action_data",
- "add_action_data",
- "delete_action_data",
- "get_subject_categories",
- "set_subject_category",
- "delete_subject_category",
- "get_object_categories",
- "set_object_category",
- "delete_object_category",
- "get_action_categories",
- "set_action_category",
- "delete_action_category",
- "add_meta_rules",
- "delete_meta_rules",
- "get_meta_rules",
- "set_meta_rules",
- "get_models",
- "add_model",
- "delete_model",
- "update_model",
- "get_pdp",
- "add_pdp",
- "delete_pdp",
- "update_pdp",
- "get_subjects",
- "set_subject",
- "delete_subject",
- "get_objects",
- "set_object",
- "delete_object",
- "get_actions",
- "set_action",
- "delete_action",
- "get_policies",
- "add_policy",
- "delete_policy",
- "update_policy",
- "get_subject_assignments",
- "update_subject_assignment",
- "delete_subject_assignment",
- "get_object_assignments",
- "update_object_assignment",
- "delete_object_assignment",
- "get_action_assignments",
- "update_action_assignment",
- "delete_action_assignment",
- "get_rules",
- "add_rule",
- "delete_rule",
- "update_from_master"
- ),
- "function": (
- "authz",
- "return_authz",
- ),
-}
-
-
-class Cache(object):
-
- # TODO (asteroide): set cache integer in CONF file
- __UPDATE_INTERVAL = 10
-
- __CONTAINERS = {}
- __CONTAINERS_UPDATE = 0
-
- __CONTAINER_CHAINING_UPDATE = 0
- __CONTAINER_CHAINING = {}
-
- __PDP = {}
- __PDP_UPDATE = 0
-
- __POLICIES = {}
- __POLICIES_UPDATE = 0
-
- __MODELS = {}
- __MODELS_UPDATE = 0
-
- __AUTHZ_REQUESTS = {}
-
- def update(self, component=None):
- self.__update_container()
- self.__update_pdp()
- self.__update_policies()
- self.__update_models()
- for key, value in self.__PDP.items():
- LOG.info("Updating container_chaining with {}".format(value["keystone_project_id"]))
- self.__update_container_chaining(value["keystone_project_id"])
-
- @property
- def authz_requests(self):
- return self.__AUTHZ_REQUESTS
-
- def __update_pdp(self):
- pdp = call("moon_manager", method="get_pdp", ctx={"user_id": "admin"}, args={})
- if not pdp["pdps"]:
- LOG.info("Updating PDP through master")
- pdp = call("moon_manager", method="get_pdp",
- ctx={
- "user_id": "admin",
- 'call_master': True
- },
- args={})
- for _pdp in pdp["pdps"].values():
- if _pdp['keystone_project_id'] not in self.__CONTAINER_CHAINING:
- self.__CONTAINER_CHAINING[_pdp['keystone_project_id']] = {}
- # Note (asteroide): force update of chaining
- self.__update_container_chaining(_pdp['keystone_project_id'])
- for key, value in pdp["pdps"].items():
- self.__PDP[key] = value
-
- @property
- def pdp(self):
- current_time = time.time()
- if self.__PDP_UPDATE + self.__UPDATE_INTERVAL < current_time:
- self.__update_pdp()
- self.__PDP_UPDATE = current_time
- return self.__PDP
-
- def __update_policies(self):
- policies = call("moon_manager", method="get_policies", ctx={"user_id": "admin"}, args={})
- for key, value in policies["policies"].items():
- self.__POLICIES[key] = value
-
- @property
- def policies(self):
- current_time = time.time()
- if self.__POLICIES_UPDATE + self.__UPDATE_INTERVAL < current_time:
- self.__update_policies()
- self.__POLICIES_UPDATE = current_time
- return self.__POLICIES
-
- def __update_models(self):
- models = call("moon_manager", method="get_models", ctx={"user_id": "admin"}, args={})
- for key, value in models["models"].items():
- self.__MODELS[key] = value
-
- @property
- def models(self):
- current_time = time.time()
- if self.__MODELS_UPDATE + self.__UPDATE_INTERVAL < current_time:
- self.__update_models()
- self.__MODELS_UPDATE = current_time
- return self.__MODELS
-
- def __update_container(self):
- containers = call("orchestrator", method="get_container", ctx={}, args={})
- for key, value in containers["containers"].items():
- self.__CONTAINERS[key] = value
-
- @property
- def container_chaining(self):
- current_time = time.time()
- if self.__CONTAINER_CHAINING_UPDATE + self.__UPDATE_INTERVAL < current_time:
- for key, value in self.pdp.items():
- self.__update_container_chaining(value["keystone_project_id"])
- self.__CONTAINER_CHAINING_UPDATE = current_time
- return self.__CONTAINER_CHAINING
-
- def __update_container_chaining(self, keystone_project_id):
- container_ids = []
- for pdp_id, pdp_value, in CACHE.pdp.items():
- LOG.info("pdp_id, pdp_value = {}, {}".format(pdp_id, pdp_value))
- if pdp_value:
- if pdp_value["keystone_project_id"] == keystone_project_id:
- for policy_id in pdp_value["security_pipeline"]:
- model_id = CACHE.policies[policy_id]['model_id']
- LOG.info("model_id = {}".format(model_id))
- LOG.info("CACHE = {}".format(CACHE.models[model_id]))
- for meta_rule_id in CACHE.models[model_id]["meta_rules"]:
- LOG.info("CACHE.containers = {}".format(CACHE.containers))
- for container_id, container_values, in CACHE.containers.items():
- LOG.info("container_id, container_values = {}".format(container_id, container_values))
- for container_value in container_values:
- LOG.info("container_value[\"meta_rule_id\"] == meta_rule_id = {} {}".format(container_value["meta_rule_id"], meta_rule_id))
- if container_value["meta_rule_id"] == meta_rule_id:
- container_ids.append(
- {
- "container_id": container_value["container_id"],
- "genre": container_value["genre"]
- }
- )
- break
- self.__CONTAINER_CHAINING[keystone_project_id] = container_ids
-
- @property
- def containers(self):
- """intra_extensions cache
- example of content :
- {
- "pdp_uuid1": "component_uuid1",
- "pdp_uuid2": "component_uuid2",
- }
- :return:
- """
- current_time = time.time()
- if self.__CONTAINERS_UPDATE + self.__UPDATE_INTERVAL < current_time:
- self.__update_container()
- self.__CONTAINERS_UPDATE = current_time
- return self.__CONTAINERS
-
-
-CACHE = Cache()
-
-
-class AuthzRequest:
-
- result = None
- req_max_delay = 2
-
- def __init__(self, ctx, args):
- self.ctx = ctx
- self.args = args
- self.request_id = ctx["request_id"]
- if self.ctx['id'] not in CACHE.container_chaining:
- LOG.warning("Unknown Project ID {}".format(self.ctx['id']))
- # TODO (asteroide): add a better exception handler
- raise Exception("Unknown Project ID {}".format(self.ctx['id']))
- self.container_chaining = CACHE.container_chaining[self.ctx['id']]
- ctx["container_chaining"] = copy.deepcopy(self.container_chaining)
- LOG.info("self.container_chaining={}".format(self.container_chaining))
- self.pdp_container = self.container_chaining[0]["container_id"]
- self.run()
-
- def run(self):
- notify(request_id=self.request_id, container_id=self.pdp_container, payload=self.ctx)
- cpt = 0
- while cpt < self.req_max_delay*10:
- time.sleep(0.1)
- cpt += 1
- if CACHE.authz_requests[self.request_id]:
- self.result = CACHE.authz_requests[self.request_id]
- return
- LOG.warning("Request {} has timed out".format(self.request_id))
-
- def is_authz(self):
- if not self.result:
- return False
- authz_results = []
- for key in self.result["pdp_set"]:
- if "effect" in self.result["pdp_set"][key]:
- if self.result["pdp_set"][key]["effect"] == "grant":
- # the pdp is a authorization PDP and grant the request
- authz_results.append(True)
- elif self.result["pdp_set"][key]["effect"] == "passed":
- # the pdp is not a authorization PDP (session or delegation) and had run normally
- authz_results.append(True)
- elif self.result["pdp_set"][key]["effect"] == "unset":
- # the pdp is not a authorization PDP (session or delegation) and had not yep run
- authz_results.append(True)
- else:
- # the pdp is (or not) a authorization PDP and had run badly
- authz_results.append(False)
- if list(itertools.accumulate(authz_results, lambda x, y: x & y))[-1]:
- self.result["pdp_set"]["effect"] = "grant"
- if self.result:
- if "pdp_set" in self.result and self.result["pdp_set"]["effect"] == "grant":
- return True
- return False
-
-
-class Router(object):
- """
- Route requests to all components.
- """
-
- __version__ = "0.1.0"
- cache_requests = {}
- slave_name = ""
-
- def __init__(self, add_master_cnx):
- self.slave = configuration.get_configuration(configuration.SLAVE)["slave"]
- try:
- self.slave_name = self.slave['name']
- except KeyError:
- pass
- if self.slave_name and add_master_cnx:
- result = call('security_router', method="route",
- ctx={
- "name": self.slave_name,
- "description": self.slave_name,
- "call_master": True,
- "method": "add_slave"}, args={})
- if "result" in result and not result["result"]:
- LOG.error("An error occurred when sending slave name {} {}".format(
- self.slave_name, result
- ))
- self.slave_id = list(result['slaves'].keys())[0]
- result = call('security_router', method="route",
- ctx={
- "name": self.slave_name,
- "description": self.slave_name,
- "call_master": True,
- "method": "get_slaves"}, args={})
- if "result" in result and not result["result"]:
- LOG.error("An error occurred when receiving slave names {} {}".format(
- self.slave_name, result
- ))
- LOG.info("SLAVES: {}".format(result))
-
- def delete(self):
- if self.slave_name and self.slave_id:
- result = call('security_router', method="route",
- ctx={
- "name": self.slave_name,
- "description": self.slave_name,
- "call_master": True,
- "method": "delete_slave",
- "id": self.slave_id}, args={})
- if "result" in result and not result["result"]:
- LOG.error("An error occurred when sending slave name {} {}".format(
- self.slave_name, result
- ))
- LOG.info("SLAVE CONNECTION ENDED!")
- LOG.info(result)
-
- def check_pdp(self, ctx):
- _ctx = copy.deepcopy(ctx)
- keystone_id = _ctx.pop('id')
- # LOG.info("_ctx {}".format(_ctx))
- ext = call("moon_manager", method="get_pdp", ctx=_ctx, args={})
- # LOG.info("check_pdp {}".format(ext))
- if "error" in ext:
- return False
- keystone_id_list = map(lambda x: x["keystone_project_id"], ext['pdps'].values())
- if not ext['pdps'] or keystone_id not in keystone_id_list:
- if self.slave_name:
- _ctx['call_master'] = True
- # update from master if exist and test again
- LOG.info("Need to update from master {}".format(keystone_id))
- ext = call("moon_manager", method="get_pdp", ctx=_ctx, args={})
- if "error" in ext:
- return False
- keystone_id_list = map(lambda x: x["keystone_project_id"], ext['pdps'].values())
- if not ext['pdps'] or keystone_id not in keystone_id_list:
- return False
- else:
- # Must update from Master
- _ctx["keystone_id"] = keystone_id
- _ctx["pdp_id"] = None
- _ctx["security_pipeline"] = None
- _ctx['call_master'] = False
- pdp_value = {}
- for pdp_id, pdp_value in ext["pdps"].items():
- if keystone_id == pdp_value["keystone_project_id"]:
- _ctx["pdp_id"] = keystone_id
- _ctx["security_pipeline"] = pdp_value["security_pipeline"]
- break
- call("moon_manager", method="update_from_master", ctx=_ctx, args=pdp_value)
- CACHE.update()
- return True
- else:
- # return False otherwise
- return False
- return True
-
- def send_update(self, api, ctx={}, args={}):
- # TODO (asteroide): add threads here
- if not self.slave_name:
- # Note (asteroide):
- # if adding or setting an element: do nothing
- # if updating or deleting an element: force deletion in the slave
- if "update_" in api or "delete_" in api:
- for slave_id, slave_dict in call("orchestrator", method="get_slaves", ctx={}, args={})['slaves'].items():
- LOG.info('send_update slave_id={}'.format(slave_id))
- LOG.info('send_update slave_dict={}'.format(slave_dict))
- ctx['method'] = api.replace("update", "delete")
- # TODO (asteroide): force data_id to None to force the deletion in the slave
- result = call("security_router_"+slave_dict['name'], method="route", ctx=ctx, args=args)
- if "result" in result and not result["result"]:
- LOG.error("An error occurred when sending update to {} {}".format(
- "security_router_"+slave_dict['name'], result
- ))
-
- def route(self, ctx, args):
- """Route the request to the right endpoint
-
- :param ctx: dictionary depending of the real destination
- :param args: dictionary depending of the real destination
- :return: dictionary depending of the real destination
- """
- LOG.info("Get Route {} {}".format(ctx, args))
- if ctx["method"] == "get_status":
- return Status().get_status(ctx=ctx, args=args)
- if ctx["method"] == "get_logs":
- return Logs().get_logs(ctx=ctx, args=args)
- for component in API:
- if ctx["method"] in API[component]:
- if component == "orchestrator":
- return call(component, method=ctx["method"], ctx=ctx, args=args)
- if component == "manager":
- result = call("moon_manager", method=ctx["method"], ctx=ctx, args=args)
- if ctx["method"] == "get_pdp":
- _ctx = copy.deepcopy(ctx)
- _ctx["call_master"] = True
- result2 = call("moon_manager", method=ctx["method"], ctx=_ctx, args=args)
- result["pdps"].update(result2["pdps"])
- self.send_update(api=ctx["method"], ctx=ctx, args=args)
- return result
- if component == "function":
- if ctx["method"] == "return_authz":
- request_id = ctx["request_id"]
- CACHE.authz_requests[request_id] = args
- return args
- elif self.check_pdp(ctx):
- req_id = uuid4().hex
- CACHE.authz_requests[req_id] = {}
- ctx["request_id"] = req_id
- req = AuthzRequest(ctx, args)
- # result = copy.deepcopy(req.result)
- if req.is_authz():
- return {"authz": True,
- "pdp_id": ctx["id"],
- "ctx": ctx, "args": args}
- return {"authz": False,
- "error": {'code': 403, 'title': 'Authz Error',
- 'description': "The authz request is refused."},
- "pdp_id": ctx["id"],
- "ctx": ctx, "args": args}
- return {"result": False,
- "error": {'code': 500, 'title': 'Moon Error',
- 'description': "Function component not found."},
- "pdp_id": ctx["id"],
- "ctx": ctx, "args": args}
-
- # TODO (asteroide): must raise an exception here ?
- return {"result": False,
- "error": {'code': 500, 'title': 'Moon Error', 'description': "Endpoint method not found."},
- "intra_extension_id": ctx["id"],
- "ctx": ctx, "args": args}
-
diff --git a/moonv4/moon_router/moon_router/messenger.py b/moonv4/moon_router/moon_router/messenger.py
deleted file mode 100644
index 0a377678..00000000
--- a/moonv4/moon_router/moon_router/messenger.py
+++ /dev/null
@@ -1,69 +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'.
-
-from oslo_config import cfg
-import oslo_messaging
-import time
-from oslo_log import log as logging
-from moon_router.api.generic import Status, Logs
-from moon_router.api.route import Router
-from moon_utilities.api import APIList
-from moon_utilities import configuration
-
-LOG = logging.getLogger("moon.router.messenger")
-
-
-class Server:
-
- TOPIC = "security_router"
-
- def __init__(self, add_master_cnx=False):
- slave = configuration.get_configuration(configuration.SLAVE)["slave"]
- cfg.CONF.transport_url = self.__get_transport_url()
- if add_master_cnx and slave["master"]["url"]:
- self.transport = oslo_messaging.get_transport(cfg.CONF, slave["master"]["url"])
- self.TOPIC = self.TOPIC + "_" + slave["name"]
- else:
- self.transport = oslo_messaging.get_transport(cfg.CONF)
- self.target = oslo_messaging.Target(topic=self.TOPIC, server='server1')
- LOG.info("Starting MQ server with topic: {}".format(self.TOPIC))
- self.endpoints = [
- APIList((Status, Logs, Router)),
- Status(),
- Logs(),
- Router(add_master_cnx)
- ]
- self.server = oslo_messaging.get_rpc_server(self.transport, self.target, self.endpoints,
- executor='threading',
- access_policy=oslo_messaging.DefaultRPCAccessPolicy)
- self.__is_alive = False
-
- @staticmethod
- def __get_transport_url():
- messenger = configuration.get_configuration(configuration.MESSENGER)["messenger"]
- return messenger['url']
-
- def stop(self):
- self.__is_alive = False
- self.endpoints[-1].delete()
-
- def run(self):
- try:
- self.__is_alive = True
- self.server.start()
- while True:
- if self.__is_alive:
- time.sleep(1)
- else:
- break
- except KeyboardInterrupt:
- print("Stopping server by crtl+c")
- except SystemExit:
- print("Stopping server with SystemExit")
- print("Stopping server")
-
- self.server.stop()
- self.server.wait()
-
diff --git a/moonv4/moon_router/moon_router/server.py b/moonv4/moon_router/moon_router/server.py
deleted file mode 100644
index 1b2bddee..00000000
--- a/moonv4/moon_router/moon_router/server.py
+++ /dev/null
@@ -1,63 +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 threading
-import signal
-from oslo_log import log as logging
-from moon_utilities import configuration, exceptions
-from moon_router.messenger import Server
-
-
-class AsyncServer(threading.Thread):
-
- def __init__(self, add_master_cnx):
- threading.Thread.__init__(self)
- self.server = Server(add_master_cnx=add_master_cnx)
-
- def run(self):
- self.server.run()
-
-LOG = logging.getLogger("moon.router")
-
-__CWD__ = os.path.dirname(os.path.abspath(__file__))
-
-background_threads = []
-
-
-def stop_thread():
- for _t in background_threads:
- _t.stop()
-
-
-def main():
- global background_threads
- configuration.init_logging()
- try:
- conf = configuration.get_configuration("components/router")
- except exceptions.ConsulComponentNotFound:
- conf = configuration.add_component("router", "router")
- signal.signal(signal.SIGALRM, stop_thread)
- signal.signal(signal.SIGTERM, stop_thread)
- signal.signal(signal.SIGABRT, stop_thread)
- background_master = None
- slave = configuration.get_configuration(configuration.SLAVE)["slave"]
- if slave['name']:
- background_master = AsyncServer(add_master_cnx=True)
- background_threads.append(background_master)
- background_slave = AsyncServer(add_master_cnx=False)
- background_threads.append(background_slave)
- if slave['name']:
- background_master.start()
- LOG.info("Connecting to master...")
- background_slave.start()
- LOG.info("Starting main server {}".format(conf["components/router"]["hostname"]))
- if slave['name']:
- background_master.join()
- background_slave.join()
-
-
-if __name__ == '__main__':
- main()
diff --git a/moonv4/moon_router/tests/moon_db-0.1.0.tar.gz b/moonv4/moon_router/tests/moon_db-0.1.0.tar.gz
deleted file mode 100644
index 14df1d47..00000000
--- a/moonv4/moon_router/tests/moon_db-0.1.0.tar.gz
+++ /dev/null
Binary files differ
diff --git a/moonv4/moon_router/tests/moon_policy-0.1.0.tar.gz b/moonv4/moon_router/tests/moon_policy-0.1.0.tar.gz
deleted file mode 100644
index d3246532..00000000
--- a/moonv4/moon_router/tests/moon_policy-0.1.0.tar.gz
+++ /dev/null
Binary files differ
diff --git a/moonv4/moon_utilities/Changelog b/moonv4/moon_utilities/Changelog
index e39a8b53..952c2aa1 100644
--- a/moonv4/moon_utilities/Changelog
+++ b/moonv4/moon_utilities/Changelog
@@ -35,3 +35,31 @@ CHANGES
-----
- Add authentication features for interface
+1.3.0
+-----
+- Add cache functionality
+
+1.3.1
+-----
+- Delete Oslo config possibilities
+
+1.3.2
+-----
+- Delete Oslo logging and config
+
+1.3.3
+-----
+- Update the cache
+
+1.3.4
+-----
+- Fix a bug on the connection between interface and authz
+
+1.4.0
+-----
+- Add a waiting loop when the Keystone server is not currently available
+
+1.4.1
+-----
+- Cleanup moon_utilities code
+
diff --git a/moonv4/moon_utilities/LICENSE b/moonv4/moon_utilities/LICENSE
index 4143aac2..d6456956 100644
--- a/moonv4/moon_utilities/LICENSE
+++ b/moonv4/moon_utilities/LICENSE
@@ -174,31 +174,29 @@
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
---- License for python-keystoneclient versions prior to 2.1 ---
-
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
-
- 1. Redistributions of source code must retain the above copyright notice,
- this list of conditions and the following disclaimer.
-
- 2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-
- 3. Neither the name of this project nor the names of its contributors may
- be used to endorse or promote products derived from this software without
- specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
-FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
-SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
-CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
-OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ END OF TERMS AND CONDITIONS
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright [yyyy] [name of copyright owner]
+
+ 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.
diff --git a/moonv4/moon_utilities/README.md b/moonv4/moon_utilities/README.md
new file mode 100644
index 00000000..bbc1d458
--- /dev/null
+++ b/moonv4/moon_utilities/README.md
@@ -0,0 +1,33 @@
+# Moon Python Utilities Package
+This package contains the core module for the Moon project.
+It is designed to provide authorization feature to all OpenStack components.
+
+For any other information, refer to the parent project:
+
+ https://git.opnfv.org/moon
+
+moon_utilities is a common Python lib for other Moon Python packages
+
+## Build
+### Build Python Package
+```bash
+cd ${MOON_HOME}/moonv4/moon_utilities
+python3 setup.py sdist bdist_wheel
+```
+
+### Push Python Package to PIP
+```bash
+cd ${MOON_HOME}/moonv4/moon_utilities
+gpg --detach-sign -u "${GPG_ID}" -a dist/moon_utilities-X.Y.Z-py3-none-any.whl
+gpg --detach-sign -u "${GPG_ID}" -a dist/moon_utilities-X.Y.Z.tar.gz
+twine upload dist/moon_db-X.Y.Z-py3-none-any.whl dist/moon_utilities-X.Y.Z-py3-none-any.whl.asc
+twine upload dist/moon_db-X.Y.Z.tar.gz dist/moon_uutilities-X.Y.Z.tar.gz.asc
+```
+
+## Test
+### Python Unit Test
+launch Docker for Python unit tests
+```bash
+cd ${MOON_HOME}/moonv4/moon_utilities
+docker run --rm --volume $(pwd):/data wukongsun/moon_python_unit_test:latest
+```
diff --git a/moonv4/moon_utilities/README.rst b/moonv4/moon_utilities/README.rst
deleted file mode 100644
index ded4e99a..00000000
--- a/moonv4/moon_utilities/README.rst
+++ /dev/null
@@ -1,9 +0,0 @@
-Core module for the Moon project
-================================
-
-This package contains the core module for the Moon project
-It is designed to provide authorization features to all OpenStack components.
-
-For any other information, refer to the parent project:
-
- https://git.opnfv.org/moon
diff --git a/moonv4/moon_utilities/moon_utilities/__init__.py b/moonv4/moon_utilities/moon_utilities/__init__.py
index 2c7f8f5c..e3ad9307 100644
--- a/moonv4/moon_utilities/moon_utilities/__init__.py
+++ b/moonv4/moon_utilities/moon_utilities/__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/moonv4/moon_utilities/moon_utilities/cache.py b/moonv4/moon_utilities/moon_utilities/cache.py
new file mode 100644
index 00000000..8c6ee3bf
--- /dev/null
+++ b/moonv4/moon_utilities/moon_utilities/cache.py
@@ -0,0 +1,543 @@
+import logging
+import time
+import requests
+from uuid import uuid4
+from moon_utilities import configuration, exceptions
+
+LOG = logging.getLogger("moon.utilities.cache")
+
+
+class Cache(object):
+ # TODO (asteroide): set cache integer in CONF file
+ '''
+ [NOTE] Propose to define the following variables inside the init method
+ as defining them out side the init, will be treated as private static variables
+ and keep tracks with any changes done anywhere
+ for more info : you can check https://docs.python.org/3/tutorial/classes.html#class-and-instance-variables
+ '''
+ __UPDATE_INTERVAL = 10
+
+ __CONTAINERS = {}
+ __CONTAINERS_UPDATE = 0
+
+ __CONTAINER_CHAINING_UPDATE = 0
+ __CONTAINER_CHAINING = {}
+
+ __PDP = {}
+ __PDP_UPDATE = 0
+
+ __POLICIES = {}
+ __POLICIES_UPDATE = 0
+
+ __MODELS = {}
+ __MODELS_UPDATE = 0
+
+ __SUBJECTS = {}
+ __OBJECTS = {}
+ __ACTIONS = {}
+
+ __SUBJECT_ASSIGNMENTS = {}
+ __OBJECT_ASSIGNMENTS = {}
+ __ACTION_ASSIGNMENTS = {}
+
+ __SUBJECT_CATEGORIES = {}
+ __SUBJECT_CATEGORIES_UPDATE = 0
+ __OBJECT_CATEGORIES = {}
+ __OBJECT_CATEGORIES_UPDATE = 0
+ __ACTION_CATEGORIES = {}
+ __ACTION_CATEGORIES_UPDATE = 0
+
+ __META_RULES = {}
+ __META_RULES_UPDATE = 0
+
+ __RULES = {}
+ __RULES_UPDATE = 0
+
+ __AUTHZ_REQUESTS = {}
+
+ def __init__(self):
+ self.manager_url = "{}://{}:{}".format(
+ configuration.get_components()['manager'].get('protocol', 'http'),
+ configuration.get_components()['manager']['hostname'],
+ configuration.get_components()['manager']['port']
+ )
+ self.orchestrator_url = "{}://{}:{}".format(
+ configuration.get_components()['orchestrator'].get('protocol', 'http'),
+ configuration.get_components()['orchestrator']['hostname'],
+ configuration.get_components()['orchestrator']['port']
+ )
+
+ def update(self):
+ self.__update_container()
+ self.__update_pdp()
+ self.__update_policies()
+ self.__update_models()
+ for key, value in self.__PDP.items():
+ # LOG.info("Updating container_chaining with {}".format(value["keystone_project_id"]))
+ self.__update_container_chaining(value["keystone_project_id"])
+
+ @property
+ def authz_requests(self):
+ return self.__AUTHZ_REQUESTS
+
+ # perimeter functions
+
+ @property
+ def subjects(self):
+ return self.__SUBJECTS
+
+ def update_subjects(self, policy_id=None):
+ req = requests.get("{}/policies/{}/subjects".format(
+ self.manager_url, policy_id))
+ self.__SUBJECTS[policy_id] = req.json()['subjects']
+
+ def get_subject(self, policy_id, name):
+ try:
+ for _subject_id, _subject_dict in self.__SUBJECTS[policy_id].items():
+ if _subject_dict["name"] == name:
+ return _subject_id
+ except KeyError:
+ pass
+ self.update_subjects(policy_id)
+ for _subject_id, _subject_dict in self.__SUBJECTS[policy_id].items():
+ if _subject_dict["name"] == name:
+ return _subject_id
+ raise exceptions.SubjectUnknown("Cannot find subject {}".format(name))
+
+ @property
+ def objects(self):
+ return self.__OBJECTS
+
+ def update_objects(self, policy_id=None):
+ req = requests.get("{}/policies/{}/objects".format(
+ self.manager_url, policy_id))
+ self.__OBJECTS[policy_id] = req.json()['objects']
+
+ def get_object(self, policy_id, name):
+ try:
+ for _object_id, _object_dict in self.__OBJECTS[policy_id].items():
+ if _object_dict["name"] == name:
+ return _object_id
+ except KeyError:
+ pass
+ self.update_objects(policy_id)
+ for _object_id, _object_dict in self.__OBJECTS[policy_id].items():
+ if _object_dict["name"] == name:
+ return _object_id
+ raise exceptions.SubjectUnknown("Cannot find object {}".format(name))
+
+ @property
+ def actions(self):
+ return self.__ACTIONS
+
+ def update_actions(self, policy_id=None):
+ req = requests.get("{}/policies/{}/actions".format(
+ self.manager_url, policy_id))
+ self.__ACTIONS[policy_id] = req.json()['actions']
+
+ def get_action(self, policy_id, name):
+ try:
+ for _action_id, _action_dict in self.__ACTIONS[policy_id].items():
+ if _action_dict["name"] == name:
+ return _action_id
+ except KeyError:
+ pass
+ self.update_actions(policy_id)
+ for _action_id, _action_dict in self.__ACTIONS[policy_id].items():
+ if _action_dict["name"] == name:
+ return _action_id
+ raise exceptions.SubjectUnknown("Cannot find action {}".format(name))
+
+ # meta_rule functions
+
+ @property
+ def meta_rules(self):
+ current_time = time.time()
+ if self.__META_RULES_UPDATE + self.__UPDATE_INTERVAL < current_time:
+ self.__update_meta_rules()
+ self.__META_RULES_UPDATE = current_time
+ return self.__META_RULES
+
+ def __update_meta_rules(self):
+ req = requests.get("{}/meta_rules".format(self.manager_url))
+ self.__META_RULES = req.json()['meta_rules']
+
+ # rule functions
+
+ @property
+ def rules(self):
+ current_time = time.time()
+ if self.__RULES_UPDATE + self.__UPDATE_INTERVAL < current_time:
+ self.__update_rules()
+ self.__RULES_UPDATE = current_time
+ return self.__RULES
+
+ def __update_rules(self):
+ for policy_id in self.__POLICIES:
+ LOG.info("Get {}".format("{}/policies/{}/rules".format(
+ self.manager_url, policy_id)))
+ req = requests.get("{}/policies/{}/rules".format(
+ self.manager_url, policy_id))
+ self.__RULES[policy_id] = req.json()['rules']
+ LOG.info("UPDATE RULES {}".format(self.__RULES))
+
+ # assignment functions
+
+ @property
+ def subject_assignments(self):
+ return self.__SUBJECT_ASSIGNMENTS
+
+ def update_subject_assignments(self, policy_id=None, perimeter_id=None):
+ if perimeter_id:
+ req = requests.get("{}/policies/{}/subject_assignments/{}".format(
+ self.manager_url, policy_id, perimeter_id))
+ else:
+ req = requests.get("{}/policies/{}/subject_assignments".format(
+ self.manager_url, policy_id))
+ if policy_id not in self.__SUBJECT_ASSIGNMENTS:
+ self.__SUBJECT_ASSIGNMENTS[policy_id] = {}
+ self.__SUBJECT_ASSIGNMENTS[policy_id].update(
+ req.json()['subject_assignments'])
+
+ def get_subject_assignments(self, policy_id, perimeter_id, category_id):
+ if policy_id not in self.subject_assignments:
+ self.update_subject_assignments(policy_id, perimeter_id)
+ '''
+ [NOTE] invalid condition for testing existence of policy_id
+ because update_subject_assignments function already add an empty object
+ with the given policy_id and then assign the response to it
+ as mentioned in these lines of code (line 191,192)
+
+ Note: the same condition applied for the object,action assignment
+ line 234, 260
+ '''
+ if policy_id not in self.subject_assignments:
+ raise Exception("Cannot found the policy {}".format(policy_id))
+ for key, value in self.subject_assignments[policy_id].items():
+ if perimeter_id == value['subject_id'] and category_id == value['category_id']:
+ return value['assignments']
+ return []
+
+ @property
+ def object_assignments(self):
+ return self.__OBJECT_ASSIGNMENTS
+
+ def update_object_assignments(self, policy_id=None, perimeter_id=None):
+ if perimeter_id:
+ req = requests.get("{}/policies/{}/object_assignments/{}".format(
+ self.manager_url, policy_id, perimeter_id))
+ else:
+ req = requests.get("{}/policies/{}/object_assignments".format(
+ self.manager_url, policy_id))
+ if policy_id not in self.__OBJECT_ASSIGNMENTS:
+ self.__OBJECT_ASSIGNMENTS[policy_id] = {}
+ self.__OBJECT_ASSIGNMENTS[policy_id].update(
+ req.json()['object_assignments'])
+
+ def get_object_assignments(self, policy_id, perimeter_id, category_id):
+ if policy_id not in self.object_assignments:
+ self.update_object_assignments(policy_id, perimeter_id)
+ if policy_id not in self.object_assignments:
+ raise Exception("Cannot found the policy {}".format(policy_id))
+ for key, value in self.object_assignments[policy_id].items():
+ if perimeter_id == value['object_id'] and category_id == value['category_id']:
+ return value['assignments']
+ return []
+
+ @property
+ def action_assignments(self):
+ return self.__ACTION_ASSIGNMENTS
+
+ def update_action_assignments(self, policy_id=None, perimeter_id=None):
+ if perimeter_id:
+ req = requests.get("{}/policies/{}/action_assignments/{}".format(
+ self.manager_url, policy_id, perimeter_id))
+ else:
+ req = requests.get("{}/policies/{}/action_assignments".format(
+ self.manager_url, policy_id))
+ if policy_id not in self.__ACTION_ASSIGNMENTS:
+ self.__ACTION_ASSIGNMENTS[policy_id] = {}
+ self.__ACTION_ASSIGNMENTS[policy_id].update(
+ req.json()['action_assignments'])
+
+ def get_action_assignments(self, policy_id, perimeter_id, category_id):
+ if policy_id not in self.action_assignments:
+ self.update_action_assignments(policy_id, perimeter_id)
+ if policy_id not in self.action_assignments:
+ raise Exception("Cannot found the policy {}".format(policy_id))
+ for key, value in self.action_assignments[policy_id].items():
+ if perimeter_id == value['action_id'] and category_id == value['category_id']:
+ return value['assignments']
+ return []
+
+ # category functions
+
+ @property
+ def subject_categories(self):
+ current_time = time.time()
+ if self.__SUBJECT_CATEGORIES_UPDATE + self.__UPDATE_INTERVAL < current_time:
+ self.__update_subject_categories()
+ self.__SUBJECT_CATEGORIES_UPDATE = current_time
+ return self.__SUBJECT_CATEGORIES
+
+ def __update_subject_categories(self):
+ req = requests.get("{}/policies/subject_categories".format(
+ self.manager_url))
+ self.__SUBJECT_CATEGORIES.update(req.json()['subject_categories'])
+
+ @property
+ def object_categories(self):
+ current_time = time.time()
+ if self.__OBJECT_CATEGORIES_UPDATE + self.__UPDATE_INTERVAL < current_time:
+ self.__update_object_categories()
+ self.__OBJECT_CATEGORIES_UPDATE = current_time
+ return self.__OBJECT_CATEGORIES
+
+ def __update_object_categories(self):
+ req = requests.get("{}/policies/object_categories".format(
+ self.manager_url))
+ self.__OBJECT_CATEGORIES.update(req.json()['object_categories'])
+
+ @property
+ def action_categories(self):
+ current_time = time.time()
+ if self.__ACTION_CATEGORIES_UPDATE + self.__UPDATE_INTERVAL < current_time:
+ self.__update_action_categories()
+ self.__ACTION_CATEGORIES_UPDATE = current_time
+ return self.__ACTION_CATEGORIES
+
+ def __update_action_categories(self):
+ req = requests.get("{}/policies/action_categories".format(
+ self.manager_url))
+ self.__ACTION_CATEGORIES.update(req.json()['action_categories'])
+
+ # PDP functions
+
+ def __update_pdp(self):
+ req = requests.get("{}/pdp".format(self.manager_url))
+ pdp = req.json()
+ for _pdp in pdp["pdps"].values():
+ if _pdp['keystone_project_id'] not in self.__CONTAINER_CHAINING:
+ self.__CONTAINER_CHAINING[_pdp['keystone_project_id']] = {}
+ # Note (asteroide): force update of chaining
+ self.__update_container_chaining(_pdp['keystone_project_id'])
+ for key, value in pdp["pdps"].items():
+ self.__PDP[key] = value
+
+ @property
+ def pdp(self):
+ """Policy Decision Point
+ Example of content:
+ {
+ "pdp_id": {
+ "keystone_project_id": "keystone_project_id",
+ "name": "pdp1",
+ "description": "test",
+ "security_pipeline": [
+ "policy_id"
+ ]
+ }
+ }
+
+ :return:
+ """
+ current_time = time.time()
+ if self.__PDP_UPDATE + self.__UPDATE_INTERVAL < current_time:
+ self.__update_pdp()
+ self.__PDP_UPDATE = current_time
+ return self.__PDP
+
+ # policy functions
+ def __update_policies(self):
+ req = requests.get("{}/policies".format(self.manager_url))
+ policies = req.json()
+ for key, value in policies["policies"].items():
+ self.__POLICIES[key] = value
+
+ @property
+ def policies(self):
+ current_time = time.time()
+ if self.__POLICIES_UPDATE + self.__UPDATE_INTERVAL < current_time:
+ self.__update_policies()
+ self.__POLICIES_UPDATE = current_time
+ return self.__POLICIES
+
+ # model functions
+
+ def __update_models(self):
+ req = requests.get("{}/models".format(self.manager_url))
+ models = req.json()
+ for key, value in models["models"].items():
+ self.__MODELS[key] = value
+
+ @property
+ def models(self):
+ current_time = time.time()
+ if self.__MODELS_UPDATE + self.__UPDATE_INTERVAL < current_time:
+ self.__update_models()
+ self.__MODELS_UPDATE = current_time
+ return self.__MODELS
+
+ # helper functions
+
+ def get_policy_from_meta_rules(self, meta_rule_id):
+ for pdp_key, pdp_value in self.pdp.items():
+ for policy_id in pdp_value["security_pipeline"]:
+ model_id = self.policies[policy_id]["model_id"]
+ if meta_rule_id in self.models[model_id]["meta_rules"]:
+ return policy_id
+
+ def get_pdp_from_keystone_project(self, keystone_project_id):
+ for pdp_key, pdp_value in self.pdp.items():
+ if keystone_project_id == pdp_value["keystone_project_id"]:
+ return pdp_key
+
+ def get_keystone_project_id_from_policy_id(self, policy_id):
+ for pdp_key, pdp_value in self.pdp.items():
+ if policy_id in pdp_value["security_pipeline"]:
+ return pdp_value["keystone_project_id"]
+ # for policy_id in pdp_value["security_pipeline"]:
+ # model_id = self.policies[policy_id]["model_id"]
+ # if meta_rule_id in self.models[model_id]["meta_rules"]:
+ # return pdp_value["keystone_project_id"]
+
+ def get_containers_from_keystone_project_id(self, keystone_project_id,
+ meta_rule_id=None):
+ for container_id, container_values in self.containers.items():
+ for container_value in container_values:
+ if 'keystone_project_id' not in container_value:
+ continue
+ if container_value['keystone_project_id'] == keystone_project_id:
+ if not meta_rule_id:
+ yield container_id, container_value
+ elif container_value.get('meta_rule_id') == meta_rule_id:
+ yield container_id, container_value
+ break
+
+ # containers functions
+
+ def __update_container(self):
+ req = requests.get("{}/pods".format(self.orchestrator_url))
+ pods = req.json()
+ for key, value in pods["pods"].items():
+ # if key not in self.__CONTAINERS:
+ self.__CONTAINERS[key] = value
+ # else:
+ # for container in value:
+ # self.__CONTAINERS[key].update(value)
+
+ def add_container(self, container_data):
+ """Add a new container in the cache
+
+ :param container_data: dictionary with information for the container
+ Example:
+ {
+ "name": name,
+ "hostname": name,
+ "port": {
+ "PrivatePort": tcp_port,
+ "Type": "tcp",
+ "IP": "0.0.0.0",
+ "PublicPort": tcp_port
+ },
+ "keystone_project_id": uuid,
+ "pdp_id": self.CACHE.get_pdp_from_keystone_project(uuid),
+ "meta_rule_id": meta_rule_id,
+ "container_name": container_name,
+ "plugin_name": plugin_name
+ "container_id": "container_id"
+ }
+
+ :return:
+ """
+ self.__CONTAINERS[uuid4().hex] = {
+ "keystone_project_id": container_data['keystone_project_id'],
+ "name": container_data['name'],
+ "container_id": container_data['container_id'],
+ "hostname": container_data['name'],
+ "policy_id": container_data['policy_id'],
+ "meta_rule_id": container_data['meta_rule_id'],
+ "port": [
+ {
+ "PublicPort": container_data['port']["PublicPort"],
+ "Type": container_data['port']["Type"],
+ "IP": container_data['port']["IP"],
+ "PrivatePort": container_data['port']["PrivatePort"]
+ }
+ ],
+ "genre": container_data['plugin_name']
+ }
+ self.__update_container_chaining(self.get_keystone_project_id_from_policy_id(container_data['policy_id']))
+
+ @property
+ def containers(self):
+ """Containers cache
+ example of content :
+ {
+ "policy_uuid1": "component_hostname1",
+ "policy_uuid2": "component_hostname2",
+ }
+ :return:
+ """
+ current_time = time.time()
+ if self.__CONTAINERS_UPDATE + self.__UPDATE_INTERVAL < current_time:
+ self.__update_container()
+ self.__CONTAINERS_UPDATE = current_time
+ return self.__CONTAINERS
+
+ @property
+ def container_chaining(self):
+ """Cache for mapping Keystone Project ID with meta_rule ID and container ID
+ Example of content:
+ {
+ "keystone_project_id": [
+ {
+ "container_id": "container_id",
+ "genre": "genre",
+ "policy_id": "policy_id",
+ "meta_rule_id": "meta_rule_id",
+ }
+ ]
+ }
+
+ :return:
+ """
+ current_time = time.time()
+ if self.__CONTAINER_CHAINING_UPDATE + self.__UPDATE_INTERVAL < current_time:
+ for key, value in self.pdp.items():
+ if not value["keystone_project_id"]:
+ continue
+ self.__update_container_chaining(value["keystone_project_id"])
+ self.__CONTAINER_CHAINING_UPDATE = current_time
+ LOG.info(self.__CONTAINER_CHAINING_UPDATE)
+ return self.__CONTAINER_CHAINING
+
+ def __update_container_chaining(self, keystone_project_id):
+ container_ids = []
+ for pdp_id, pdp_value, in self.__PDP.items():
+ if pdp_value:
+ if pdp_value["keystone_project_id"] == keystone_project_id:
+ for policy_id in pdp_value["security_pipeline"]:
+ model_id = self.__POLICIES[policy_id]['model_id']
+ for meta_rule_id in self.__MODELS[model_id]["meta_rules"]:
+ for container_id, container_value in self.get_containers_from_keystone_project_id(
+ keystone_project_id,
+ meta_rule_id
+ ):
+ _raw = requests.get("{}/pods/{}".format(
+ self.orchestrator_url, container_value["name"])
+ )
+ LOG.debug("_raw={}".format(_raw.text))
+ container_ids.append(
+ {
+ "container_id": container_value["name"],
+ "genre": container_value["genre"],
+ "policy_id": policy_id,
+ "meta_rule_id": meta_rule_id,
+ "hostname": container_value["name"],
+ "hostip": "127.0.0.1",
+ "port": container_value["port"],
+ }
+ )
+ self.__CONTAINER_CHAINING[keystone_project_id] = container_ids
+
diff --git a/moonv4/moon_utilities/moon_utilities/configuration.py b/moonv4/moon_utilities/moon_utilities/configuration.py
index 32eeff13..cda75de5 100644
--- a/moonv4/moon_utilities/moon_utilities/configuration.py
+++ b/moonv4/moon_utilities/moon_utilities/configuration.py
@@ -4,15 +4,11 @@
# or at 'http://www.apache.org/licenses/LICENSE-2.0'.
-import copy
import base64
import json
import requests
import logging
import logging.config
-# from oslo_log import log as logging
-from oslo_config import cfg
-# import oslo_messaging
from moon_utilities import exceptions
LOG = logging.getLogger("moon.utilities")
@@ -21,8 +17,6 @@ CONSUL_HOST = "consul"
CONSUL_PORT = "8500"
DATABASE = "database"
-SLAVE = "slave"
-MESSENGER = "messenger"
KEYSTONE = "keystone"
DOCKER = "docker"
COMPONENTS = "components"
@@ -33,11 +27,6 @@ def init_logging():
logging.config.dictConfig(config['logging'])
-def init_oslo_config():
- cfg.CONF.transport_url = get_configuration("messenger")['messenger']['url']
- cfg.CONF.rpc_response_timeout = 5
-
-
def increment_port():
components_port_start = int(get_configuration("components_port_start")['components_port_start'])
components_port_start += 1
@@ -53,8 +42,8 @@ def get_configuration(key):
url = "http://{}:{}/v1/kv/{}".format(CONSUL_HOST, CONSUL_PORT, key)
req = requests.get(url)
if req.status_code != 200:
- LOG.info("url={}".format(url))
- raise exceptions.ConsulComponentNotFound
+ LOG.error("url={}".format(url))
+ raise exceptions.ConsulComponentNotFound("error={}: {}".format(req.status_code, req.text))
data = req.json()
if len(data) == 1:
data = data[0]
@@ -123,4 +112,3 @@ def get_components():
init_logging()
-init_oslo_config()
diff --git a/moonv4/moon_utilities/moon_utilities/exceptions.py b/moonv4/moon_utilities/moon_utilities/exceptions.py
index ba5ecf46..eb606432 100644
--- a/moonv4/moon_utilities/moon_utilities/exceptions.py
+++ b/moonv4/moon_utilities/moon_utilities/exceptions.py
@@ -138,26 +138,6 @@ class ModelExisting(MoonError):
logger = "Error"
-class RootExtensionUnknown(IntraExtensionUnknown):
- description = _("The root_extension is unknown.")
- code = 400
- title = 'Root Extension Unknown'
- logger = "Error"
-
-
-class RootPDPNotInitialized(IntraExtensionException):
- description = _("The root_extension is not initialized.")
- code = 400
- title = 'Root Extension Not Initialized'
- logger = "Error"
-
-
-class IntraExtensionCreationError(IntraExtensionException):
- description = _("The arguments for the creation of this Extension were malformed.")
- code = 400
- title = 'Intra Extension Creation Error'
-
-
# Authz exceptions
class AuthzException(MoonError):
diff --git a/moonv4/moon_utilities/moon_utilities/get_os_apis.py b/moonv4/moon_utilities/moon_utilities/get_os_apis.py
deleted file mode 100644
index dea2a878..00000000
--- a/moonv4/moon_utilities/moon_utilities/get_os_apis.py
+++ /dev/null
@@ -1,122 +0,0 @@
-import json
-import logging
-import requests
-import argparse
-
-URLS = {
- "keystone": "https://api.github.com/repos/openstack/keystone/contents/api-ref/source/v3",
- "nova": "https://api.github.com/repos/openstack/nova/contents/api-ref/source",
- "neutron": "https://api.github.com/repos/openstack/neutron-lib/contents/api-ref/source/v2",
- "glance": "https://api.github.com/repos/openstack/glance/contents/api-ref/source/v2",
- "swift": "https://api.github.com/repos/openstack/swift/contents/api-ref/source",
- "cinder": "https://api.github.com/repos/openstack/cinder/contents/api-ref/source/v3",
-
-}
-
-logger = None
-
-USER = ""
-PASS = ""
-
-
-def init():
- global logger, USER, PASS
- 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("--format", "-f", help="Output format (txt, json)", default="json")
- parser.add_argument("--output", "-o", help="Output filename")
- parser.add_argument("--credentials", "-c", help="Github credential filename (inside format user:pass)")
- args = parser.parse_args()
-
- FORMAT = '%(levelname)s %(message)s'
-
- if args.verbose:
- logging.basicConfig(
- format=FORMAT,
- level=logging.INFO)
- elif args.debug:
- logging.basicConfig(
- format=FORMAT,
- level=logging.DEBUG)
- else:
- logging.basicConfig(
- format=FORMAT,
- level=logging.WARNING)
-
- if args.credentials:
- cred = open(args.credentials).read()
- USER = cred.split(":")[0]
- PASS = cred.split(":")[1]
-
- logger = logging.getLogger(__name__)
-
- return args
-
-
-def get_api_item(url):
- if USER:
- r = requests.get(url, auth=(USER, PASS))
- else:
- r = requests.get(url)
- items = []
- for line in r.text.splitlines():
- if ".. rest_method::" in line:
- items.append(line.replace(".. rest_method::", "").strip())
- logger.debug("\n\t".join(items))
- return items
-
-
-def get_content(key, args):
- logger.info("Analysing {}".format(key))
- if USER:
- r = requests.get(URLS[key], auth=(USER, PASS))
- else:
- r = requests.get(URLS[key])
- data = r.json()
- results = {}
- for item in data:
- try:
- logger.debug("{} {}".format(item['name'], item['download_url']))
- if item['type'] == "file" and ".inc" in item['name']:
- results[item['name'].replace(".inc", "")] = get_api_item(item['download_url'])
- except TypeError:
- logger.error("Error with {}".format(item))
- except requests.exceptions.MissingSchema:
- logger.error("MissingSchema error {}".format(item))
- return results
-
-
-def to_str(results):
- output = ""
- for key in results:
- output += "{}\n".format(key)
- for item in results[key]:
- output += "\t{}\n".format(item)
- for value in results[key][item]:
- output += "\t\t{}\n".format(value)
- return output
-
-
-def save(results, args):
- if args.output:
- if args.format == 'json':
- json.dump(results, open(args.output, "w"), indent=4)
- elif args.format == 'txt':
- open(args.output, "w").write(to_str(results))
- else:
- if args.format == 'json':
- print(json.dumps(results, indent=4))
- elif args.format in ('txt', 'text'):
- print(to_str(results))
-
-
-def main():
- args = init()
- results = {}
- for key in URLS:
- results[key] = get_content(key, args)
- save(results, args)
-
-if __name__ == "__main__":
- main() \ No newline at end of file
diff --git a/moonv4/moon_utilities/moon_utilities/misc.py b/moonv4/moon_utilities/moon_utilities/misc.py
index d13b4511..b83523c3 100644
--- a/moonv4/moon_utilities/moon_utilities/misc.py
+++ b/moonv4/moon_utilities/moon_utilities/misc.py
@@ -4,28 +4,18 @@
# or at 'http://www.apache.org/licenses/LICENSE-2.0'.
-import os
-import re
-import types
-import requests
-from oslo_log import log as logging
-from oslo_config import cfg
-import oslo_messaging
-from moon_utilities import exceptions
-from oslo_config.cfg import ConfigOpts
+import logging
+import random
LOG = logging.getLogger(__name__)
-CONF = cfg.CONF
def get_uuid_from_name(name, elements, **kwargs):
- LOG.error("get_uuid_from_name {} {} {}".format(name, elements, kwargs))
for element in elements:
if type(elements[element]) is dict and elements[element].get('name') == name:
if kwargs:
for args in kwargs:
if elements[element].get(args) != kwargs[args]:
- LOG.error("get_uuid_from_name2 {} {} {}".format(args, elements[element].get(args), kwargs[args]))
return
else:
return element
@@ -45,3 +35,108 @@ def get_name_from_uuid(uuid, elements, **kwargs):
else:
return elements[element].get('name')
+
+def get_random_name():
+ _list = (
+ "windy",
+ "vengeful",
+ "precious",
+ "vivacious",
+ "quiet",
+ "confused",
+ "exultant",
+ "impossible",
+ "thick",
+ "obsolete",
+ "piquant",
+ "fanatical",
+ "tame",
+ "perfect",
+ "animated",
+ "dark",
+ "stimulating",
+ "drunk",
+ "depressed",
+ "fumbling",
+ "like",
+ "undesirable",
+ "spurious",
+ "subsequent",
+ "spiteful",
+ "last",
+ "stale",
+ "hulking",
+ "giddy",
+ "minor",
+ "careful",
+ "possessive",
+ "gullible",
+ "fragile",
+ "divergent",
+ "ill-informed",
+ "false",
+ "jumpy",
+ "damaged",
+ "likeable",
+ "volatile",
+ "handsomely",
+ "wet",
+ "long-term",
+ "pretty",
+ "taboo",
+ "normal",
+ "magnificent",
+ "nutty",
+ "puzzling",
+ "small",
+ "kind",
+ "devilish",
+ "chubby",
+ "paltry",
+ "cultured",
+ "old",
+ "defective",
+ "hanging",
+ "innocent",
+ "jagged",
+ "economic",
+ "good",
+ "sulky",
+ "real",
+ "bent",
+ "shut",
+ "furry",
+ "terrific",
+ "hollow",
+ "terrible",
+ "mammoth",
+ "pleasant",
+ "scared",
+ "obnoxious",
+ "absorbing",
+ "imported",
+ "infamous",
+ "grieving",
+ "ill-fated",
+ "mighty",
+ "handy",
+ "comfortable",
+ "astonishing",
+ "brown",
+ "assorted",
+ "wrong",
+ "unsightly",
+ "spooky",
+ "delightful",
+ "acid",
+ "inconclusive",
+ "mere",
+ "careless",
+ "historical",
+ "flashy",
+ "squealing",
+ "quarrelsome",
+ "empty",
+ "long",
+ )
+ return random.choice(_list)
diff --git a/moonv4/moon_utilities/moon_utilities/options.py b/moonv4/moon_utilities/moon_utilities/options.py
deleted file mode 100644
index 8b8ccca4..00000000
--- a/moonv4/moon_utilities/moon_utilities/options.py
+++ /dev/null
@@ -1,300 +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 sys
-from oslo_config import cfg
-from oslo_log import log as logging
-from moon_utilities import __version__
-
-LOG = logging.getLogger(__name__)
-CONF = cfg.CONF
-
-__CWD__ = os.path.dirname(os.path.abspath(__file__))
-
-
-def configure(domain="moon", version=__version__, usage=""):
- # FIXME (dthom): put DEBUG as default log level doesn't work
- extra_log_level_defaults = [
- '{}=DEBUG'.format(__name__),
- ]
- # LOG.setLevel(logging.DEBUG)
- logging.set_defaults(
- default_log_levels=logging.get_default_log_levels() + extra_log_level_defaults)
-
- logging.register_options(CONF)
- logging.setup(CONF, domain)
-
- CONF.register_opts(get_opts())
-
- # rabbit_group = cfg.OptGroup(name='messenger',
- # title='Messenger options')
- # CONF.register_group(rabbit_group)
- # CONF.register_opts(get_messenger_opts(), group="messenger")
-
- slave_group = cfg.OptGroup(name='slave',
- title='Messenger options')
- CONF.register_group(slave_group)
- CONF.register_opts(get_slave_opts(), group="slave")
-
- database_group = cfg.OptGroup(name='database',
- title='Database options')
- CONF.register_group(database_group)
- CONF.register_opts(get_database_opts(), group="database")
-
- database_configuration_group = cfg.OptGroup(name='database_configuration',
- title='Database configuration options')
- CONF.register_group(database_configuration_group)
- CONF.register_opts(get_database_configuration_opts(), group="database_configuration")
-
- orchestrator_group = cfg.OptGroup(name='orchestrator',
- title='Orchestrator options')
- CONF.register_group(orchestrator_group)
- CONF.register_opts(get_orchestrator_opts(), group="orchestrator")
-
- secrouter_group = cfg.OptGroup(name='security_router',
- title='Security Router options')
- CONF.register_group(secrouter_group)
- CONF.register_opts(get_security_router_opts(), group="security_router")
-
- manager_group = cfg.OptGroup(name='security_manager',
- title='Manager options')
- CONF.register_group(manager_group)
- CONF.register_opts(get_manager_opts(), group="security_manager")
-
- secpolicy_group = cfg.OptGroup(name='security_policy',
- title='Security policy options')
- CONF.register_group(secpolicy_group)
- CONF.register_opts(get_security_policy_opts(), group="security_policy")
-
- secfunction_group = cfg.OptGroup(name='security_function',
- title='Security function options')
- CONF.register_group(secfunction_group)
- CONF.register_opts(get_security_function_opts(), group="security_function")
-
- interface_group = cfg.OptGroup(name='interface',
- title='Interface options')
- CONF.register_group(interface_group)
- CONF.register_opts(get_interface_opts(), group="interface")
-
- keystone_group = cfg.OptGroup(name='keystone',
- title='Keystone options')
- CONF.register_group(keystone_group)
- CONF.register_opts(get_keystone_opts(), group="keystone")
-
- filename = "moon.conf"
- for _filename in (
- "/etc/moon/{}",
- "conf/{}",
- "../conf/{}",
- ):
- try:
- default_config_files = (_filename.format(filename), )
- CONF(args=sys.argv[1:],
- project=domain,
- # version=pbr.version.VersionInfo('keystone').version_string(),
- version=version,
- usage=usage,
- default_config_files=default_config_files)
- except cfg.ConfigFilesNotFoundError:
- continue
- else:
- LOG.info("Using {} configuration file".format(_filename.format(filename)))
- return _filename.format(filename)
-
-
-def get_opts():
- return [
- cfg.StrOpt('proxy',
- default="",
- help='Proxy server to use'),
- cfg.StrOpt('dist_dir',
- default="",
- help='Directory where the python packages can be found'),
- cfg.StrOpt('plugin_dir',
- default="",
- help='Directory where the python plugins can be found'),
- cfg.StrOpt('docker_url',
- default="unix://var/run/docker.sock",
- help='Docker URL to connect to.'),
- cfg.StrOpt('policy_directory',
- default="/etc/moon/policies",
- help='Directory containing all the intra-extension templates'),
- cfg.StrOpt('root_policy_directory',
- default="/etc/moon/policies/policy_root",
- help='Directory containing the Root intra-extension template'),
- cfg.StrOpt('master',
- default="",
- help='URL of the Moon Master'),
- cfg.StrOpt('master_login',
- default="",
- help='Login to log into the Moon Master'),
- cfg.StrOpt('master_password',
- default="",
- help='Password for the Moon Master'),
- ]
-
-
-# def get_messenger_opts():
-# return [
-# cfg.StrOpt('host',
-# default="0.0.0.0",
-# help='RabbitMQ server name or IP.'),
-# cfg.IntOpt('port',
-# default=8800,
-# help='RabbitMQ server port.'),
-# ]
-
-
-def get_orchestrator_opts():
- return [
- cfg.StrOpt('host',
- default="127.0.0.1",
- help='Host binding'),
- cfg.IntOpt('port',
- default=38000,
- help='Port number of the server'),
- ]
-
-
-def get_slave_opts():
- return [
- cfg.StrOpt('slave_name',
- default="",
- help='name of the slave'),
- cfg.StrOpt('master_url',
- default="",
- help='URL of the RabbitMQ bus of the Master, '
- 'example: master_url=rabbit://moon:p4sswOrd1@messenger:5672/moon'),
- cfg.StrOpt('master_login',
- default="",
- help='login name of the master administrator, example: master_login=admin'),
- cfg.StrOpt('master_password',
- default="",
- help='password of the master administrator, example: master_password=XXXXXXX'),
- ]
-
-
-def get_security_router_opts():
- return [
- cfg.StrOpt('container',
- default="",
- help='Name of the container to download (if empty build from scratch)'),
- cfg.StrOpt('host',
- default="127.0.0.1",
- help='Host binding'),
- cfg.IntOpt('port',
- default=38001,
- help='Port number of the server'),
- ]
-
-
-def get_manager_opts():
- return [
- cfg.StrOpt('container',
- default="",
- help='Name of the container to download (if empty build from scratch)'),
- cfg.StrOpt('host',
- default="127.0.0.1",
- help='Host binding'),
- cfg.IntOpt('port',
- default=38001,
- help='Port number of the server'),
- ]
-
-
-def get_security_policy_opts():
- return [
- cfg.StrOpt('container',
- default="",
- help='Name of the container to download (if empty build from scratch)'),
- ]
-
-
-def get_security_function_opts():
- return [
- cfg.StrOpt('container',
- default="",
- help='Name of the container to download (if empty build from scratch)'),
- ]
-
-
-def get_interface_opts():
- return [
- cfg.StrOpt('container',
- default="",
- help='Name of the container to download (if empty build from scratch)'),
- cfg.StrOpt('host',
- default="127.0.0.1",
- help='Host binding'),
- cfg.IntOpt('port',
- default=38002,
- help='Port number of the server'),
- ]
-
-
-def get_database_opts():
- return [
- cfg.StrOpt('url',
- default="mysql+pymysql://moonuser:password@localhost/moon",
- help='URL of the database'),
- cfg.StrOpt('driver',
- default="sql",
- help='Driver binding'),
- ]
-
-
-def get_database_configuration_opts():
- return [
- cfg.StrOpt('url',
- default="",
- help='URL of the database'),
- cfg.StrOpt('driver',
- default="memory",
- help='Driver binding'),
- ]
-
-
-def get_keystone_opts():
- return [
- cfg.StrOpt('url',
- default="http://localhost:35357",
- help='URL of the Keystone manager.'),
- cfg.StrOpt('user',
- default="admin",
- help='Username of the Keystone manager.'),
- cfg.StrOpt('password',
- default="nomoresecrete",
- help='Password of the Keystone manager.'),
- cfg.StrOpt('project',
- default="admin",
- help='Project used to connect to the Keystone manager.'),
- cfg.StrOpt('domain',
- default="Default",
- help='Default domain for the Keystone manager.'),
- cfg.StrOpt('check_token',
- default="true",
- help='If true, yes or strict, always check Keystone tokens against the server'),
- cfg.StrOpt('server_crt',
- default="",
- help='If using Keystone in HTTPS mode, give a certificate filename here'),
- ]
-
-filename = configure()
-
-
-def get_docker_template_dir(templatename="template.dockerfile"):
- path = os.path.dirname(os.path.abspath(filename))
- PATHS = (
- path,
- os.path.join(path, "dockers"),
- "/etc/moon/"
- "~/.moon/"
- )
- for _path in PATHS:
- if os.path.isfile(os.path.join(_path, templatename)):
- return _path
- raise Exception("Configuration error, cannot find docker template in {}".format(PATHS))
-
diff --git a/moonv4/moon_utilities/moon_utilities/security_functions.py b/moonv4/moon_utilities/moon_utilities/security_functions.py
index ad1a44fa..50ab4daf 100644
--- a/moonv4/moon_utilities/moon_utilities/security_functions.py
+++ b/moonv4/moon_utilities/moon_utilities/security_functions.py
@@ -12,28 +12,14 @@ import requests
import time
from functools import wraps
from flask import request
-from oslo_log import log as logging
-from oslo_config import cfg
-import oslo_messaging
+import logging
from moon_utilities import exceptions
from moon_utilities import configuration
LOG = logging.getLogger("moon.utilities." + __name__)
-CONF = cfg.CONF
keystone_config = configuration.get_configuration("openstack/keystone")["openstack/keystone"]
-slave = configuration.get_configuration(configuration.SLAVE)["slave"]
-
-__transport_master = oslo_messaging.get_transport(cfg.CONF, slave.get("master_url"))
-__transport = oslo_messaging.get_transport(CONF)
-
-__n_transport = oslo_messaging.get_notification_transport(CONF)
-__n_notifier = oslo_messaging.Notifier(__n_transport,
- 'router.host',
- driver='messagingv2',
- topics=['authz-workers'])
-__n_notifier = __n_notifier.prepare(publisher_id='router')
-
+TOKENS = {}
__targets = {}
@@ -111,6 +97,7 @@ def enforce(action_names, object_name, **extra):
def login(user=None, password=None, domain=None, project=None, url=None):
+ start_time = time.time()
if not user:
user = keystone_config['user']
if not password:
@@ -151,15 +138,19 @@ def login(user=None, password=None, domain=None, project=None, url=None):
}
}
- req = requests.post("{}/auth/tokens".format(url),
- json=data_auth, headers=headers,
- verify=keystone_config['certificate'])
-
- if req.status_code in (200, 201, 204):
- headers['X-Auth-Token'] = req.headers['X-Subject-Token']
- return headers
- LOG.error(req.text)
- raise exceptions.KeystoneError
+ while True:
+ req = requests.post("{}/auth/tokens".format(url),
+ json=data_auth, headers=headers,
+ verify=keystone_config['certificate'])
+
+ if req.status_code in (200, 201, 204):
+ headers['X-Auth-Token'] = req.headers['X-Subject-Token']
+ return headers
+ LOG.warning("Waiting for Keystone...")
+ if time.time() - start_time == 100:
+ LOG.error(req.text)
+ raise exceptions.KeystoneError
+ time.sleep(5)
def logout(headers, url=None):
@@ -173,95 +164,92 @@ def logout(headers, url=None):
raise exceptions.KeystoneError
-def notify(request_id, container_id, payload, event_type="authz"):
- ctxt = {
- 'request_id': request_id,
- 'container_id': container_id
- }
- __n_notifier.critical(ctxt, event_type, payload=payload)
- # FIXME (asteroide): the notification mus be done 2 times otherwise the notification
- # may not be sent (need to search why)
- __n_notifier.critical(ctxt, event_type, payload=payload)
-
-
-def call(endpoint="security_router", ctx=None, method="route", **kwargs):
- if not ctx:
- ctx = dict()
- if endpoint not in __targets:
- __targets[endpoint] = dict()
- __targets[endpoint]["endpoint"] = oslo_messaging.Target(topic=endpoint, version='1.0')
- __targets[endpoint]["client"] = dict()
- __targets[endpoint]["client"]["internal"] = oslo_messaging.RPCClient(__transport,
- __targets[endpoint]["endpoint"])
- __targets[endpoint]["client"]["external"] = oslo_messaging.RPCClient(__transport_master,
- __targets[endpoint]["endpoint"])
- if 'call_master' in ctx and ctx['call_master'] and slave.get("master_url"):
- client = __targets[endpoint]["client"]["external"]
- LOG.info("Calling master {} on {}...".format(method, endpoint))
- else:
- client = __targets[endpoint]["client"]["internal"]
- LOG.info("Calling {} on {}...".format(method, endpoint))
- result = copy.deepcopy(client.call(ctx, method, **kwargs))
- LOG.info("result={}".format(result))
- del client
- return result
-
-
class Context:
- def __init__(self, _keystone_project_id, _subject, _object, _action, _request_id):
- from moon_db.core import PDPManager, ModelManager, PolicyManager
- self.PolicyManager = PolicyManager
- self.ModelManager = ModelManager
- self.PDPManager = PDPManager
- self.__keystone_project_id = _keystone_project_id
+ def __init__(self, init_context, cache):
+ 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 PDPManager.get_pdp("admin").items():
- if _pdp_value["keystone_project_id"] == _keystone_project_id:
+ 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
- self.__subject = _subject
- self.__object = _object
- self.__action = _action
+ if not self.__pdp_value:
+ raise exceptions.AuthzException(
+ "Cannot create context for authz "
+ "with Keystone project ID {}".format(
+ self.__keystone_project_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 = _request_id
- self.__index = 0
- self.__init_initial_request()
+ 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.__index = -1
+ # self.__init_initial_request()
self.__headers = []
- policies = PolicyManager.get_policies("admin")
- models = ModelManager.get_models("admin")
+ 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_rules = ModelManager.get_meta_rules("admin")
+ self.__meta_rules = self.cache.meta_rules
self.__pdp_set = {}
+ # self.__init_pdp_set()
+
+ def delete_cache(self):
+ self.cache = {}
+
+ def set_cache(self, cache):
+ self.cache = cache
+
+ def increment_index(self):
+ self.__index += 1
+ self.__init_current_request()
self.__init_pdp_set()
- def __init_initial_request(self):
- subjects = self.PolicyManager.get_subjects("admin", policy_id=None)
- for _subject_id, _subject_dict in subjects.items():
- if _subject_dict["name"] == self.__subject:
- self.__subject = _subject_id
- break
- else:
- raise exceptions.SubjectUnknown("Cannot find subject {}".format(self.__subject))
- objects = self.PolicyManager.get_objects("admin", policy_id=None)
- for _object_id, _object_dict in objects.items():
- if _object_dict["name"] == self.__object:
- self.__object = _object_id
- break
- else:
- raise exceptions.ObjectUnknown("Cannot find object {}".format(self.__object))
- actions = self.PolicyManager.get_actions("admin", policy_id=None)
- for _action_id, _action_dict in actions.items():
- if _action_dict["name"] == self.__action:
- self.__action = _action_id
- break
- else:
- raise exceptions.ActionUnknown("Cannot find action {}".format(self.__action))
+ @property
+ def current_state(self):
+ return self.__pdp_set[self.__headers[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
+
+ @current_state.deleter
+ def current_state(self):
+ self.__pdp_set[self.__headers[self.__index]]['effect'] = "unset"
+
+ @property
+ def current_policy_id(self):
+ return self.__pdp_value["security_pipeline"][self.__index]
+
+ @current_policy_id.setter
+ def current_policy_id(self, value):
+ pass
+
+ @current_policy_id.deleter
+ def current_policy_id(self):
+ pass
+
+ def __init_current_request(self):
+ self.__subject = self.cache.get_subject(
+ self.__pdp_value["security_pipeline"][self.__index],
+ self.__subject)
+ self.__object = self.cache.get_object(
+ self.__pdp_value["security_pipeline"][self.__index],
+ self.__object)
+ self.__action = self.cache.get_action(
+ self.__pdp_value["security_pipeline"][self.__index],
+ self.__action)
self.__current_request = dict(self.initial_request)
def __init_pdp_set(self):
@@ -269,67 +257,70 @@ class Context:
self.__pdp_set[header] = dict()
self.__pdp_set[header]["meta_rules"] = self.__meta_rules[header]
self.__pdp_set[header]["target"] = self.__add_target(header)
- # TODO (asteroide): the following information must be retrieve somewhere
self.__pdp_set[header]["effect"] = "unset"
self.__pdp_set["effect"] = "deny"
- @staticmethod
- def update_target(context):
- from moon_db.core import PDPManager, ModelManager, PolicyManager
- # result = dict()
- current_request = context['current_request']
- _subject = current_request.get("subject")
- _object = current_request.get("object")
- _action = current_request.get("action")
- meta_rule_id = context['headers'][context['index']]
- policy_id = PolicyManager.get_policy_from_meta_rules("admin", meta_rule_id)
- meta_rules = ModelManager.get_meta_rules("admin")
- # for meta_rule_id in meta_rules:
- for sub_cat in meta_rules[meta_rule_id]['subject_categories']:
- if sub_cat not in context["pdp_set"][meta_rule_id]["target"]:
- context["pdp_set"][meta_rule_id]["target"][sub_cat] = []
- for assign in PolicyManager.get_subject_assignments("admin", policy_id, _subject, sub_cat).values():
- for assign in assign["assignments"]:
- if assign not in context["pdp_set"][meta_rule_id]["target"][sub_cat]:
- context["pdp_set"][meta_rule_id]["target"][sub_cat].append(assign)
- for obj_cat in meta_rules[meta_rule_id]['object_categories']:
- if obj_cat not in context["pdp_set"][meta_rule_id]["target"]:
- context["pdp_set"][meta_rule_id]["target"][obj_cat] = []
- for assign in PolicyManager.get_object_assignments("admin", policy_id, _object, obj_cat).values():
- for assign in assign["assignments"]:
- if assign not in context["pdp_set"][meta_rule_id]["target"][obj_cat]:
- context["pdp_set"][meta_rule_id]["target"][obj_cat].append(assign)
- for act_cat in meta_rules[meta_rule_id]['action_categories']:
- if act_cat not in context["pdp_set"][meta_rule_id]["target"]:
- context["pdp_set"][meta_rule_id]["target"][act_cat] = []
- for assign in PolicyManager.get_action_assignments("admin", policy_id, _action, act_cat).values():
- for assign in assign["assignments"]:
- if assign not in context["pdp_set"][meta_rule_id]["target"][act_cat]:
- context["pdp_set"][meta_rule_id]["target"][act_cat].append(assign)
- # context["pdp_set"][meta_rule_id]["target"].update(result)
+ # def update_target(self, context):
+ # # result = dict()
+ # current_request = context['current_request']
+ # _subject = current_request.get("subject")
+ # _object = current_request.get("object")
+ # _action = current_request.get("action")
+ # meta_rule_id = context['headers'][context['index']]
+ # policy_id = self.cache.get_policy_from_meta_rules(meta_rule_id)
+ # meta_rules = self.cache.meta_rules()
+ # # for meta_rule_id in meta_rules:
+ # for sub_cat in meta_rules[meta_rule_id]['subject_categories']:
+ # if sub_cat not in context["pdp_set"][meta_rule_id]["target"]:
+ # context["pdp_set"][meta_rule_id]["target"][sub_cat] = []
+ # for assign in self.cache.get_subject_assignments(policy_id, _subject, sub_cat).values():
+ # for assign in assign["assignments"]:
+ # if assign not in context["pdp_set"][meta_rule_id]["target"][sub_cat]:
+ # context["pdp_set"][meta_rule_id]["target"][sub_cat].append(assign)
+ # for obj_cat in meta_rules[meta_rule_id]['object_categories']:
+ # if obj_cat not in context["pdp_set"][meta_rule_id]["target"]:
+ # context["pdp_set"][meta_rule_id]["target"][obj_cat] = []
+ # for assign in self.cache.get_object_assignments(policy_id, _object, obj_cat).values():
+ # for assign in assign["assignments"]:
+ # if assign not in context["pdp_set"][meta_rule_id]["target"][obj_cat]:
+ # context["pdp_set"][meta_rule_id]["target"][obj_cat].append(assign)
+ # for act_cat in meta_rules[meta_rule_id]['action_categories']:
+ # if act_cat not in context["pdp_set"][meta_rule_id]["target"]:
+ # context["pdp_set"][meta_rule_id]["target"][act_cat] = []
+ # for assign in self.cache.get_action_assignments(policy_id, _action, act_cat).values():
+ # for assign in assign["assignments"]:
+ # if assign not in context["pdp_set"][meta_rule_id]["target"][act_cat]:
+ # context["pdp_set"][meta_rule_id]["target"][act_cat].append(assign)
+ # # context["pdp_set"][meta_rule_id]["target"].update(result)
def __add_target(self, meta_rule_id):
+ """build target from meta_rule
+
+ Target is dict of categories as keys ; and the value of each category
+ will be a list of assignments
+
+ """
result = dict()
_subject = self.__current_request["subject"]
_object = self.__current_request["object"]
_action = self.__current_request["action"]
- meta_rules = self.ModelManager.get_meta_rules("admin")
- policy_id = self.PolicyManager.get_policy_from_meta_rules("admin", meta_rule_id)
+ meta_rules = self.cache.meta_rules
+ policy_id = self.cache.get_policy_from_meta_rules(meta_rule_id)
for sub_cat in meta_rules[meta_rule_id]['subject_categories']:
if sub_cat not in result:
result[sub_cat] = []
- for assign in self.PolicyManager.get_subject_assignments("admin", policy_id, _subject, sub_cat).values():
- result[sub_cat].extend(assign["assignments"])
+ result[sub_cat].extend(
+ self.cache.get_subject_assignments(policy_id, _subject, sub_cat))
for obj_cat in meta_rules[meta_rule_id]['object_categories']:
if obj_cat not in result:
result[obj_cat] = []
- for assign in self.PolicyManager.get_object_assignments("admin", policy_id, _object, obj_cat).values():
- result[obj_cat].extend(assign["assignments"])
+ result[obj_cat].extend(
+ self.cache.get_object_assignments(policy_id, _object, obj_cat))
for act_cat in meta_rules[meta_rule_id]['action_categories']:
if act_cat not in result:
result[act_cat] = []
- for assign in self.PolicyManager.get_action_assignments("admin", policy_id, _action, act_cat).values():
- result[act_cat].extend(assign["assignments"])
+ result[act_cat].extend(
+ self.cache.get_action_assignments(policy_id, _action, act_cat))
return result
def __repr__(self):
@@ -356,6 +347,8 @@ pdp_set: {pdp_set}
"index": copy.deepcopy(self.__index),
"pdp_set": copy.deepcopy(self.__pdp_set),
"request_id": copy.deepcopy(self.__request_id),
+ "manager_url": copy.deepcopy(self.__manager_url),
+ "interface_name": copy.deepcopy(self.__interface_name),
}
@property
@@ -371,6 +364,42 @@ pdp_set: {pdp_set}
raise Exception("You cannot update the request_id")
@property
+ def manager_url(self):
+ return self.__manager_url
+
+ @manager_url.setter
+ def manager_url(self, value):
+ raise Exception("You cannot update the manager_url")
+
+ @manager_url.deleter
+ def manager_url(self):
+ raise Exception("You cannot update the manager_url")
+
+ @property
+ def interface_name(self):
+ return self.__interface_name
+
+ @interface_name.setter
+ def interface_name(self, value):
+ raise Exception("You cannot update the interface_name")
+
+ @interface_name.deleter
+ def interface_name(self):
+ raise Exception("You cannot update the interface_name")
+
+ @property
+ def cookie(self):
+ return self.__cookie
+
+ @cookie.setter
+ def cookie(self, value):
+ raise Exception("You cannot update the cookie")
+
+ @cookie.deleter
+ def cookie(self):
+ raise Exception("You cannot delete the cookie")
+
+ @property
def initial_request(self):
return {
"subject": self.__subject,
@@ -395,7 +424,8 @@ pdp_set: {pdp_set}
@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.
+ # Note (asteroide): if the current request is modified,
+ # we must update the PDP Set.
self.__init_pdp_set()
@current_request.deleter
@@ -425,7 +455,7 @@ pdp_set: {pdp_set}
@index.deleter
def index(self):
- self.__index = 0
+ self.__index = -1
@property
def pdp_set(self):
@@ -439,8 +469,6 @@ pdp_set: {pdp_set}
def pdp_set(self):
self.__pdp_set = {}
-TOKENS = {}
-
def check_token(token, url=None):
_verify = False
diff --git a/moonv4/moon_utilities/requirements.txt b/moonv4/moon_utilities/requirements.txt
index e30f5d29..5b80e5f2 100644
--- a/moonv4/moon_utilities/requirements.txt
+++ b/moonv4/moon_utilities/requirements.txt
@@ -1,8 +1,3 @@
-kombu !=4.0.1,!=4.0.0
-oslo.messaging
-oslo.config
-oslo.log
-vine
werkzeug
flask
requests \ No newline at end of file
diff --git a/moonv4/moon_utilities/setup.py b/moonv4/moon_utilities/setup.py
index 6c9ffd3d..21e11419 100644
--- a/moonv4/moon_utilities/setup.py
+++ b/moonv4/moon_utilities/setup.py
@@ -17,13 +17,13 @@ setup(
packages=find_packages(),
- author="Thomas Duval",
+ author='Thomas Duval',
- author_email="thomas.duval@orange.com",
+ author_email='thomas.duval@orange.com',
- description="Some utilities for all the Moon components",
+ description='Some utilities for all the Moon components',
- long_description=open('README.rst').read(),
+ long_description=open('README.md').read(),
install_requires=required,
@@ -32,12 +32,11 @@ setup(
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",
+ 'Programming Language :: Python :: 3',
+ 'Development Status :: 1 - Planning',
+ 'License :: OSI Approved',
+ 'Natural Language :: English',
+ 'Operating System :: OS Independent',
],
)
diff --git a/moonv4/moon_utilities/tests/unit_python/conftest.py b/moonv4/moon_utilities/tests/unit_python/conftest.py
new file mode 100644
index 00000000..7217586a
--- /dev/null
+++ b/moonv4/moon_utilities/tests/unit_python/conftest.py
@@ -0,0 +1,17 @@
+import pytest
+import requests_mock
+import mock_components
+import mock_keystone
+import mock_cache
+
+
+@pytest.fixture(autouse=True)
+def no_requests(monkeypatch):
+ """ Modify the response from Requests module
+ """
+ with requests_mock.Mocker(real_http=True) as m:
+ mock_components.register_components(m)
+ mock_keystone.register_keystone(m)
+ mock_cache.register_cache(m)
+ print("End registering URI")
+ yield m \ No newline at end of file
diff --git a/moonv4/moon_utilities/tests/unit_python/mock_cache.py b/moonv4/moon_utilities/tests/unit_python/mock_cache.py
new file mode 100644
index 00000000..b2b287a9
--- /dev/null
+++ b/moonv4/moon_utilities/tests/unit_python/mock_cache.py
@@ -0,0 +1,321 @@
+from utilities import CONF
+
+pdp_mock = {
+ "pdp_id1": {
+ "name": "...",
+ "security_pipeline": ["policy_id_1", "policy_id_2"],
+ "keystone_project_id": "keystone_project_id1",
+ "description": "...",
+ },
+ "pdp_id12": {
+ "name": "...",
+ "security_pipeline": ["policy_id_1", "policy_id_2"],
+ "keystone_project_id": "keystone_project_id1",
+ "description": "...",
+ }
+}
+
+meta_rules_mock = {
+ "meta_rule_id1": {
+ "name": "meta_rule1",
+ "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"]
+ },
+ "meta_rule_id2": {
+ "name": "name of the meta rules2",
+ "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"]
+ }
+}
+
+policies_mock = {
+ "policy_id_1": {
+ "name": "test_policy1",
+ "model_id": "model_id_1",
+ "genre": "authz",
+ "description": "test",
+ },
+ "policy_id_2": {
+ "name": "test_policy2",
+ "model_id": "model_id_2",
+ "genre": "authz",
+ "description": "test",
+ }
+}
+
+subject_mock = {
+ "policy_id_1": {
+ "subject_id": {
+ "name": "subject_name",
+ "keystone_id": "keystone_project_id1",
+ "description": "a description"
+ }
+ },
+ "policy_id_2": {
+ "subject_id": {
+ "name": "subject_name",
+ "keystone_id": "keystone_project_id1",
+ "description": "a description"
+ }
+ }
+}
+
+subject_assignment_mock = {
+ "subject_id": {
+ "policy_id": "ID of the policy",
+ "subject_id": "ID of the subject",
+ "category_id": "ID of the category",
+ "assignments": [],
+ }
+}
+
+object_mock = {
+ "policy_id_1": {
+ "object_id": {
+ "name": "object_name",
+ "description": "a description"
+ }
+ },
+ "policy_id_2": {
+ "object_id": {
+ "name": "object_name",
+ "description": "a description"
+ }
+ }
+}
+
+object_assignment_mock = {
+ "object_id": {
+ "policy_id": "ID of the policy",
+ "object_id": "ID of the object",
+ "category_id": "ID of the category",
+ "assignments": [],
+ }
+}
+
+action_mock = {
+ "policy_id_1": {
+ "action_id": {
+ "name": "action_name",
+ "description": "a description"
+ }
+ },
+ "policy_id_2": {
+ "action_id": {
+ "name": "action_name",
+ "description": "a description"
+ }
+ }
+}
+
+action_assignment_mock = {
+ "action_id": {
+ "policy_id": "ID of the policy",
+ "action_id": "ID of the action",
+ "category_id": "ID of the category",
+ "assignments": [],
+ }
+}
+
+models_mock = {
+ "model_id_1": {
+ "name": "test_model",
+ "description": "test",
+ "meta_rules": ["meta_rule_id1"]
+ },
+ "model_id_2": {
+ "name": "test_model",
+ "description": "test",
+ "meta_rules": ["meta_rule_id2"]
+ },
+}
+
+rules_mock = {
+ "rules": {
+ "meta_rule_id": "meta_rule_id1",
+ "rule_id1": {
+ "rule": ["subject_data_id1",
+ "object_data_id1",
+ "action_data_id1"],
+ "instructions": (
+ {"decision": "grant"},
+ # "grant" to immediately exit,
+ # "continue" to wait for the result of next policy
+ # "deny" to deny the request
+ )
+ },
+ "rule_id2": {
+ "rule": ["subject_data_id2",
+ "object_data_id2",
+ "action_data_id2"],
+ "instructions": (
+ {
+ "update": {
+ "operation": "add",
+ # operations may be "add" or "delete"
+ "target": "rbac:role:admin"
+ # add the role admin to the current user
+ }
+ },
+ {"chain": {"name": "rbac"}}
+ # chain with the policy named rbac
+ )
+ }
+ }
+}
+
+
+def register_cache(m):
+ """ Modify the response from Requests module
+ """
+ register_pdp(m)
+ register_meta_rules(m)
+ register_policies(m)
+ register_models(m)
+ register_policy_subject(m, "policy_id_1")
+ register_policy_subject(m, "policy_id_2")
+ register_policy_object(m, "policy_id_1")
+ register_policy_object(m, "policy_id_2")
+ register_policy_action(m, "policy_id_1")
+ register_policy_action(m, "policy_id_2")
+ register_policy_subject_assignment(m, "policy_id_1", "subject_id")
+ # register_policy_subject_assignment_list(m1, "policy_id_1")
+ register_policy_subject_assignment(m, "policy_id_2", "subject_id")
+ # register_policy_subject_assignment_list(m1, "policy_id_2")
+ register_policy_object_assignment(m, "policy_id_1", "object_id")
+ # register_policy_object_assignment_list(m1, "policy_id_1")
+ register_policy_object_assignment(m, "policy_id_2", "object_id")
+ # register_policy_object_assignment_list(m1, "policy_id_2")
+ register_policy_action_assignment(m, "policy_id_1", "action_id")
+ # register_policy_action_assignment_list(m1, "policy_id_1")
+ register_policy_action_assignment(m, "policy_id_2", "action_id")
+ # register_policy_action_assignment_list(m1, "policy_id_2")
+ register_rules(m, "policy_id1")
+
+
+def register_pdp(m):
+ m.register_uri(
+ 'GET', 'http://{}:{}/{}'.format(CONF['components']['manager']['hostname'],
+ CONF['components']['manager']['port'], 'pdp'),
+ json={'pdps': pdp_mock}
+ )
+
+
+def register_meta_rules(m):
+ m.register_uri(
+ 'GET', 'http://{}:{}/{}'.format(CONF['components']['manager']['hostname'],
+ CONF['components']['manager']['port'], 'meta_rules'),
+ json={'meta_rules': meta_rules_mock}
+ )
+
+
+def register_policies(m):
+ m.register_uri(
+ 'GET', 'http://{}:{}/{}'.format(CONF['components']['manager']['hostname'],
+ CONF['components']['manager']['port'], 'policies'),
+ json={'policies': policies_mock}
+ )
+
+
+def register_models(m):
+ m.register_uri(
+ 'GET', 'http://{}:{}/{}'.format(CONF['components']['manager']['hostname'],
+ CONF['components']['manager']['port'], 'models'),
+ json={'models': models_mock}
+ )
+
+
+def register_policy_subject(m, policy_id):
+ m.register_uri(
+ 'GET', 'http://{}:{}/{}/{}/subjects'.format(CONF['components']['manager']['hostname'],
+ CONF['components']['manager']['port'], 'policies', policy_id),
+ json={'subjects': subject_mock[policy_id]}
+ )
+
+
+def register_policy_object(m, policy_id):
+ m.register_uri(
+ 'GET', 'http://{}:{}/{}/{}/objects'.format(CONF['components']['manager']['hostname'],
+ CONF['components']['manager']['port'], 'policies', policy_id),
+ json={'objects': object_mock[policy_id]}
+ )
+
+
+def register_policy_action(m, policy_id):
+ m.register_uri(
+ 'GET', 'http://{}:{}/{}/{}/actions'.format(CONF['components']['manager']['hostname'],
+ CONF['components']['manager']['port'], 'policies', policy_id),
+ json={'actions': action_mock[policy_id]}
+ )
+
+
+def register_policy_subject_assignment(m, policy_id, subj_id):
+ m.register_uri(
+ 'GET', 'http://{}:{}/{}/{}/subject_assignments/{}'.format(CONF['components']['manager']['hostname'],
+ CONF['components']['manager']['port'], 'policies',
+ policy_id,
+ subj_id),
+ json={'subject_assignments': subject_assignment_mock}
+ )
+
+
+def register_policy_subject_assignment_list(m, policy_id):
+ m.register_uri(
+ 'GET', 'http://{}:{}/{}/{}/subject_assignments'.format(CONF['components']['manager']['hostname'],
+ CONF['components']['manager']['port'], 'policies',
+ policy_id),
+ json={'subject_assignments': subject_assignment_mock}
+ )
+
+
+def register_policy_object_assignment(m, policy_id, obj_id):
+ m.register_uri(
+ 'GET', 'http://{}:{}/{}/{}/object_assignments/{}'.format(CONF['components']['manager']['hostname'],
+ CONF['components']['manager']['port'], 'policies',
+ policy_id,
+ obj_id),
+ json={'object_assignments': object_assignment_mock}
+ )
+
+
+def register_policy_object_assignment_list(m, policy_id):
+ m.register_uri(
+ 'GET', 'http://{}:{}/{}/{}/object_assignments'.format(CONF['components']['manager']['hostname'],
+ CONF['components']['manager']['port'], 'policies',
+ policy_id),
+ json={'object_assignments': object_assignment_mock}
+ )
+
+
+def register_policy_action_assignment(m, policy_id, action_id):
+ m.register_uri(
+ 'GET', 'http://{}:{}/{}/{}/action_assignments/{}'.format(CONF['components']['manager']['hostname'],
+ CONF['components']['manager']['port'], 'policies',
+ policy_id,
+ action_id),
+ json={'action_assignments': action_assignment_mock}
+ )
+
+
+def register_policy_action_assignment_list(m, policy_id):
+ m.register_uri(
+ 'GET', 'http://{}:{}/{}/{}/action_assignments'.format(CONF['components']['manager']['hostname'],
+ CONF['components']['manager']['port'], 'policies',
+ policy_id),
+ json={'action_assignments': action_assignment_mock}
+ )
+
+
+def register_rules(m, policy_id):
+ m.register_uri(
+ 'GET', 'http://{}:{}/{}/{}/{}'.format(CONF['components']['manager']['hostname'],
+ CONF['components']['manager']['port'], 'policies',
+ policy_id, 'rules'),
+ json={'rules': rules_mock}
+ ) \ No newline at end of file
diff --git a/moonv4/moon_utilities/tests/unit_python/mock_components.py b/moonv4/moon_utilities/tests/unit_python/mock_components.py
new file mode 100644
index 00000000..a0319e1a
--- /dev/null
+++ b/moonv4/moon_utilities/tests/unit_python/mock_components.py
@@ -0,0 +1,27 @@
+import utilities
+
+COMPONENTS = (
+ "logging",
+ "openstack/keystone",
+ "database",
+ "slave",
+ "components/manager",
+ "components/orchestrator",
+ "components/interface",
+)
+
+
+def register_components(m):
+ for component in COMPONENTS:
+ m.register_uri(
+ 'GET', 'http://consul:8500/v1/kv/{}'.format(component),
+ json=[{'Key': component, 'Value': utilities.get_b64_conf(component)}]
+ )
+
+ m.register_uri(
+ 'GET', 'http://consul:8500/v1/kv/components?recurse=true',
+ json=[
+ {"Key": key, "Value": utilities.get_b64_conf(key)} for key in COMPONENTS
+ ],
+ # json={'Key': "components", 'Value': get_b64_conf("components")}
+ ) \ No newline at end of file
diff --git a/moonv4/moon_utilities/tests/unit_python/mock_keystone.py b/moonv4/moon_utilities/tests/unit_python/mock_keystone.py
new file mode 100644
index 00000000..c0b26b88
--- /dev/null
+++ b/moonv4/moon_utilities/tests/unit_python/mock_keystone.py
@@ -0,0 +1,23 @@
+def register_keystone(m):
+ 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"
+ }]}
+ ) \ No newline at end of file
diff --git a/moonv4/moon_utilities/tests/unit_python/requirements.txt b/moonv4/moon_utilities/tests/unit_python/requirements.txt
new file mode 100644
index 00000000..3c1ad607
--- /dev/null
+++ b/moonv4/moon_utilities/tests/unit_python/requirements.txt
@@ -0,0 +1,2 @@
+pytest
+requests_mock \ No newline at end of file
diff --git a/moonv4/moon_utilities/tests/unit_python/test_cache.py b/moonv4/moon_utilities/tests/unit_python/test_cache.py
new file mode 100644
index 00000000..3d4f7292
--- /dev/null
+++ b/moonv4/moon_utilities/tests/unit_python/test_cache.py
@@ -0,0 +1,75 @@
+import pytest
+
+
+def test_authz_request():
+ from moon_utilities import cache
+ c = cache.Cache()
+ assert isinstance(c.authz_requests, dict)
+
+
+def test_get_subject_success():
+ from moon_utilities import cache
+ cache_obj = cache.Cache()
+ policy_id = 'policy_id_1'
+ name = 'subject_name'
+ subject_id = cache_obj.get_subject(policy_id, name)
+ assert subject_id is not None
+
+
+def test_get_subject_failure():
+ from moon_utilities import cache
+ cache_obj = cache.Cache()
+ policy_id = 'policy_id_1'
+ name = 'invalid name'
+ with pytest.raises(Exception) as exception_info:
+ cache_obj.get_subject(policy_id, name)
+ assert str(exception_info.value) == '400: Subject Unknown'
+
+
+def test_get_object_success():
+ from moon_utilities import cache
+ cache_obj = cache.Cache()
+ policy_id = 'policy_id_1'
+ name = 'object_name'
+ object_id = cache_obj.get_object(policy_id, name)
+ assert object_id is not None
+
+
+def test_get_object_failure():
+ from moon_utilities import cache
+ cache_obj = cache.Cache()
+ policy_id = 'policy_id_1'
+ name = 'invalid name'
+ with pytest.raises(Exception) as exception_info:
+ cache_obj.get_object(policy_id, name)
+ assert str(exception_info.value) == '400: Subject Unknown'
+
+
+def test_get_action_success():
+ from moon_utilities import cache
+ cache_obj = cache.Cache()
+ policy_id = 'policy_id_1'
+ name = 'action_name'
+ action_id = cache_obj.get_action(policy_id, name)
+ assert action_id is not None
+
+
+def test_get_action_failure():
+ from moon_utilities import cache
+ cache_obj = cache.Cache()
+ policy_id = 'policy_id_1'
+ name = 'invalid name'
+ with pytest.raises(Exception) as exception_info:
+ cache_obj.get_action(policy_id, name)
+ assert str(exception_info.value) == '400: Subject Unknown'
+
+
+def test_cache_manager():
+ from moon_utilities import cache
+ cache_obj = cache.Cache()
+ assert cache_obj.pdp is not None
+ assert cache_obj.meta_rules is not None
+ assert len(cache_obj.meta_rules) == 2
+ assert cache_obj.policies is not None
+ assert len(cache_obj.policies) == 2
+ assert cache_obj.models is not None \ No newline at end of file
diff --git a/moonv4/moon_utilities/tests/unit_python/test_configuration.py b/moonv4/moon_utilities/tests/unit_python/test_configuration.py
new file mode 100644
index 00000000..0ebff995
--- /dev/null
+++ b/moonv4/moon_utilities/tests/unit_python/test_configuration.py
@@ -0,0 +1,5 @@
+
+def test_get_components():
+ from moon_utilities import configuration
+ assert isinstance(configuration.get_components(), dict)
+
diff --git a/moonv4/moon_utilities/tests/unit_python/utilities.py b/moonv4/moon_utilities/tests/unit_python/utilities.py
new file mode 100644
index 00000000..1d79d890
--- /dev/null
+++ b/moonv4/moon_utilities/tests/unit_python/utilities.py
@@ -0,0 +1,136 @@
+import base64
+import json
+
+
+CONF = {
+ "openstack": {
+ "keystone": {
+ "url": "http://keystone:5000/v3",
+ "user": "admin",
+ "check_token": False,
+ "password": "p4ssw0rd",
+ "domain": "default",
+ "certificate": False,
+ "project": "admin"
+ }
+ },
+ "components": {
+ "wrapper": {
+ "bind": "0.0.0.0",
+ "port": 8080,
+ "container": "wukongsun/moon_wrapper:v4.3",
+ "timeout": 5,
+ "hostname": "wrapper"
+ },
+ "manager": {
+ "bind": "0.0.0.0",
+ "port": 8082,
+ "container": "wukongsun/moon_manager:v4.3",
+ "hostname": "manager"
+ },
+ "port_start": 31001,
+ "orchestrator": {
+ "bind": "0.0.0.0",
+ "port": 8083,
+ "container": "wukongsun/moon_orchestrator:v4.3",
+ "hostname": "interface"
+ },
+ "interface": {
+ "bind": "0.0.0.0",
+ "port": 8080,
+ "container": "wukongsun/moon_interface:v4.3",
+ "hostname": "interface"
+ }
+ },
+ "plugins": {
+ "session": {
+ "port": 8082,
+ "container": "asteroide/session:latest"
+ },
+ "authz": {
+ "port": 8081,
+ "container": "wukongsun/moon_authz:v4.3"
+ }
+ },
+ "logging": {
+ "handlers": {
+ "file": {
+ "filename": "/tmp/moon.log",
+ "class": "logging.handlers.RotatingFileHandler",
+ "level": "DEBUG",
+ "formatter": "custom",
+ "backupCount": 3,
+ "maxBytes": 1048576
+ },
+ "console": {
+ "class": "logging.StreamHandler",
+ "formatter": "brief",
+ "level": "INFO",
+ "stream": "ext://sys.stdout"
+ }
+ },
+ "formatters": {
+ "brief": {
+ "format": "%(levelname)s %(name)s %(message)-30s"
+ },
+ "custom": {
+ "format": "%(asctime)-15s %(levelname)s %(name)s %(message)s"
+ }
+ },
+ "root": {
+ "handlers": [
+ "console"
+ ],
+ "level": "ERROR"
+ },
+ "version": 1,
+ "loggers": {
+ "moon": {
+ "handlers": [
+ "console",
+ "file"
+ ],
+ "propagate": False,
+ "level": "DEBUG"
+ }
+ }
+ },
+ "slave": {
+ "name": None,
+ "master": {
+ "url": None,
+ "login": None,
+ "password": None
+ }
+ },
+ "docker": {
+ "url": "tcp://172.88.88.1:2376",
+ "network": "moon"
+ },
+ "database": {
+ "url": "sqlite:///database.db",
+ # "url": "mysql+pymysql://moon:p4sswOrd1@db/moon",
+ "driver": "sql"
+ },
+ "messenger": {
+ "url": "rabbit://moon:p4sswOrd1@messenger:5672/moon"
+ }
+}
+
+
+def get_b64_conf(component=None):
+ if component == "components":
+ return base64.b64encode(
+ json.dumps(CONF["components"]).encode('utf-8')+b"\n").decode('utf-8')
+ elif component in CONF:
+ return base64.b64encode(
+ json.dumps(
+ CONF[component]).encode('utf-8')+b"\n").decode('utf-8')
+ elif not component:
+ return base64.b64encode(
+ json.dumps(CONF).encode('utf-8')+b"\n").decode('utf-8')
+ elif "/" in component:
+ key1, _, key2 = component.partition("/")
+ return base64.b64encode(
+ json.dumps(
+ CONF[key1][key2]).encode('utf-8')+b"\n").decode('utf-8')
diff --git a/moonv4/moon_wrapper/Dockerfile b/moonv4/moon_wrapper/Dockerfile
index 2f55c8da..55e7208d 100644
--- a/moonv4/moon_wrapper/Dockerfile
+++ b/moonv4/moon_wrapper/Dockerfile
@@ -6,6 +6,7 @@ RUN pip3 install pip --upgrade
ADD . /root
WORKDIR /root/
RUN pip3 install -r requirements.txt --upgrade
+RUN pip3 install /root/dist/* --upgrade
RUN pip3 install .
CMD ["python3", "-m", "moon_wrapper"]
diff --git a/moonv4/moon_wrapper/LICENSE b/moonv4/moon_wrapper/LICENSE
index 4143aac2..d6456956 100644
--- a/moonv4/moon_wrapper/LICENSE
+++ b/moonv4/moon_wrapper/LICENSE
@@ -174,31 +174,29 @@
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
---- License for python-keystoneclient versions prior to 2.1 ---
-
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
-
- 1. Redistributions of source code must retain the above copyright notice,
- this list of conditions and the following disclaimer.
-
- 2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-
- 3. Neither the name of this project nor the names of its contributors may
- be used to endorse or promote products derived from this software without
- specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
-FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
-SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
-CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
-OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ END OF TERMS AND CONDITIONS
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright [yyyy] [name of copyright owner]
+
+ 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.
diff --git a/moonv4/moon_wrapper/moon_wrapper/__main__.py b/moonv4/moon_wrapper/moon_wrapper/__main__.py
index 1a04e9ce..46cafa76 100644
--- a/moonv4/moon_wrapper/moon_wrapper/__main__.py
+++ b/moonv4/moon_wrapper/moon_wrapper/__main__.py
@@ -1,3 +1,4 @@
from moon_wrapper.server import main
-main()
+server = main()
+server.run()
diff --git a/moonv4/moon_wrapper/moon_wrapper/api/__init__.py b/moonv4/moon_wrapper/moon_wrapper/api/__init__.py
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/moonv4/moon_wrapper/moon_wrapper/api/__init__.py
diff --git a/moonv4/moon_consul/moon_consul/api/generic.py b/moonv4/moon_wrapper/moon_wrapper/api/generic.py
index 69f25eef..68687ddb 100644
--- a/moonv4/moon_consul/moon_consul/api/generic.py
+++ b/moonv4/moon_wrapper/moon_wrapper/api/generic.py
@@ -7,16 +7,70 @@ Those API are helping API used to manage the Moon platform.
"""
from flask_restful import Resource, request
-# from oslo_config import cfg
from oslo_log import log as logging
-# from moon_utilities.security_functions import call
-import moon_consul.api
-# from moon_utilities.auth import check_auth
+import moon_wrapper.api
+from moon_utilities.security_functions import check_auth
__version__ = "0.1.0"
-LOG = logging.getLogger(__name__)
-# CONF = cfg.CONF
+LOG = logging.getLogger("moon.manager.api." + __name__)
+
+
+class Status(Resource):
+ """
+ Endpoint for status requests
+ """
+
+ __urls__ = ("/status", "/status/", "/status/<string:component_id>")
+
+ def get(self, component_id=None):
+ """Retrieve status of all components
+
+ :return: {
+ "orchestrator": {
+ "status": "Running"
+ },
+ "security_router": {
+ "status": "Running"
+ }
+ }
+ """
+ raise NotImplemented
+
+
+class Logs(Resource):
+ """
+ Endpoint for logs requests
+ """
+
+ __urls__ = ("/logs", "/logs/", "/logs/<string:component_id>")
+
+ def get(self, component_id=None):
+ """Get logs from the Moon platform
+
+ :param component_id: the ID of the component your are looking for (optional)
+ :return: [
+ "2015-04-15-13:45:20
+ "2015-04-15-13:45:21
+ "2015-04-15-13:45:22
+ "2015-04-15-13:45:23
+ ]
+ """
+ filter_str = request.args.get('filter', '')
+ from_str = request.args.get('from', '')
+ to_str = request.args.get('to', '')
+ event_number = request.args.get('event_number', '')
+ try:
+ event_number = int(event_number)
+ except ValueError:
+ event_number = None
+ args = dict()
+ args["filter"] = filter_str
+ args["from"] = from_str
+ args["to"] = to_str
+ args["event_number"] = event_number
+
+ raise NotImplemented
class API(Resource):
@@ -31,7 +85,7 @@ class API(Resource):
"/api/<string:group_id>/",
"/api/<string:group_id>/<string:endpoint_id>")
- # @check_auth
+ @check_auth
def get(self, group_id="", endpoint_id="", user_id=""):
"""Retrieve all API endpoints or a specific endpoint if endpoint_id is given
@@ -49,7 +103,7 @@ class API(Resource):
}
"""
__methods = ("get", "post", "put", "delete", "options", "patch")
- api_list = filter(lambda x: "__" not in x, dir(moon_consul.api))
+ api_list = filter(lambda x: "__" not in x, dir(moon_wrapper.api))
api_desc = dict()
for api_name in api_list:
api_desc[api_name] = {}
@@ -75,4 +129,3 @@ class API(Resource):
return {"error": "Unknown endpoint_id {}".format(endpoint_id)}
return {group_id: api_desc[group_id]}
return api_desc
-
diff --git a/moonv4/moon_wrapper/moon_wrapper/api/wrapper.py b/moonv4/moon_wrapper/moon_wrapper/api/wrapper.py
new file mode 100644
index 00000000..32eb4e68
--- /dev/null
+++ b/moonv4/moon_wrapper/moon_wrapper/api/wrapper.py
@@ -0,0 +1,127 @@
+# Copyright 2015 Open Platform for NFV Project, Inc. and its contributors
+# This software is distributed under the terms and conditions of the 'Apache-2.0'
+# license which can be found in the file 'LICENSE' in this package distribution
+# or at 'http://www.apache.org/licenses/LICENSE-2.0'.
+"""
+Authz is the endpoint to get authorization response
+"""
+
+import flask
+from flask import request
+from flask_restful import Resource
+import logging
+import json
+import requests
+from moon_utilities import exceptions
+import time
+from uuid import uuid4
+
+# from moon_interface.api.authz import pdp_in_cache, pdp_in_manager, container_exist, \
+# create_containers, create_authz_request
+# from moon_interface.authz_requests import AuthzRequest
+from moon_utilities import configuration
+
+__version__ = "0.1.0"
+
+LOG = logging.getLogger("moon.wrapper.api." + __name__)
+
+
+class Wrapper(Resource):
+ """
+ Endpoint for authz requests
+ """
+
+ __urls__ = (
+ "/authz",
+ "/authz/",
+ )
+
+ def __init__(self, **kwargs):
+ self.port = kwargs.get("port")
+ self.CACHE = kwargs.get("cache", {})
+ self.TIMEOUT = 5
+
+ # def get(self):
+ # LOG.info("GET")
+ # return self.manage_data()
+
+ def post(self):
+ LOG.debug("POST {}".format(request.form))
+ response = flask.make_response("False")
+ if self.manage_data():
+ response = flask.make_response("True")
+ response.headers['content-type'] = 'application/octet-stream'
+ return response
+
+ @staticmethod
+ def __get_subject(target, credentials):
+ _subject = target.get("user_id", "")
+ if not _subject:
+ _subject = credentials.get("user_id", "none")
+ return _subject
+
+ @staticmethod
+ def __get_object(target, credentials):
+ try:
+ # note: case of Glance
+ return target['target']['name']
+ except KeyError:
+ pass
+
+ # note: default case
+ return target.get("project_id", "none")
+
+ @staticmethod
+ def __get_project_id(target, credentials):
+ LOG.info("__get_project_id {}".format(target))
+ return target.get("project_id", "none")
+
+ def get_interface_url(self, project_id):
+ LOG.info("project_id {}".format(project_id))
+ for containers in self.CACHE.containers.values():
+ LOG.info("containers {}".format(containers))
+ for container in containers:
+ if container.get("keystone_project_id") == project_id:
+ if "interface" in container['name']:
+ return "http://{}:{}".format(
+ container['name'],
+ container['port'])
+ self.CACHE.update()
+ # Note (asteroide): test an other time after the update
+ for containers in self.CACHE.containers.values():
+ for container in containers:
+ if container.get("keystone_project_id") == project_id:
+ if "interface" in container['name']:
+ return "http://{}:{}".format(
+ container['name'],
+ container['port'])
+ raise exceptions.AuthzException("Keystone Project "
+ "ID ({}) is unknown or not mapped "
+ "to a PDP.".format(project_id))
+
+ def manage_data(self):
+ data = request.form
+ if not dict(request.form):
+ data = json.loads(request.data.decode("utf-8"))
+ target = json.loads(data.get('target', {}))
+ credentials = json.loads(data.get('credentials', {}))
+ rule = data.get('rule', "")
+ _subject = self.__get_subject(target, credentials)
+ _object = self.__get_object(target, credentials)
+ _project_id = self.__get_project_id(target, credentials)
+ LOG.debug("POST with args project={} / "
+ "subject={} - object={} - action={}".format(
+ _project_id, _subject, _object, rule))
+ interface_url = self.get_interface_url(_project_id)
+ LOG.debug("interface_url={}".format(interface_url))
+ req = requests.get("{}/authz/{}/{}/{}/{}".format(
+ interface_url,
+ _project_id,
+ _subject,
+ _object,
+ rule
+ ))
+ LOG.debug("Get interface {}".format(req.text))
+ if req.status_code == 200:
+ if req.json().get("result", False):
+ return True
diff --git a/moonv4/moon_wrapper/moon_wrapper/http_server.py b/moonv4/moon_wrapper/moon_wrapper/http_server.py
index f50213c7..39951089 100644
--- a/moonv4/moon_wrapper/moon_wrapper/http_server.py
+++ b/moonv4/moon_wrapper/moon_wrapper/http_server.py
@@ -3,74 +3,139 @@
# license which can be found in the file 'LICENSE' in this package distribution
# or at 'http://www.apache.org/licenses/LICENSE-2.0'.
-import requests
-import json
-from flask import Flask, request
+from flask import Flask, jsonify
+from flask_cors import CORS, cross_origin
+from flask_restful import Resource, Api
import logging
-from moon_utilities import configuration
+from moon_wrapper import __version__
+from moon_wrapper.api.generic import Status, Logs, API
+from moon_wrapper.api.wrapper import Wrapper
+from moon_utilities.cache import Cache
+from moon_utilities import configuration, exceptions
logger = logging.getLogger("moon.wrapper.http")
-def __get_subject(target, credentials):
- _subject = target.get("user_id", "")
- if not _subject:
- _subject = credentials.get("user_id", "")
- return _subject
-
-
-def __get_object(target, credentials):
- try:
- # note: case of Glance
- return target['target']['name']
- except KeyError:
- pass
-
- # note: default case
- return target.get("project_id", "")
-
-
-def __get_project_id(target, credentials):
- return target.get("project_id", "")
-
-
-def HTTPServer(host, port):
- app = Flask(__name__)
- conf = configuration.get_configuration("components/wrapper")
- timeout = conf["components/wrapper"].get("timeout", 5)
- conf = configuration.get_configuration("components/interface")
- interface_hostname = conf["components/interface"].get("hostname", "interface")
- interface_port = conf["components/interface"].get("port", 80)
- conf = configuration.get_configuration("logging")
- try:
- debug = conf["logging"]["loggers"]['moon']['level'] == "DEBUG"
- except KeyError:
- debug = False
-
- @app.route("/", methods=['POST', 'GET'])
- def wrapper():
- try:
- target = json.loads(request.form.get('target', {}))
- credentials = json.loads(request.form.get('credentials', {}))
- rule = request.form.get('rule', "")
- _subject = __get_subject(target, credentials)
- _object = __get_object(target, credentials)
- _project_id = __get_project_id(target, credentials)
- logger.info("GET with args {} / {} - {} - {}".format(_project_id, _subject, _object, rule))
- _url = "http://{}:{}/authz/{}/{}/{}/{}".format(
- interface_hostname,
- interface_port,
- _project_id,
- _subject,
- _object,
- rule
- )
- req = requests.get(url=_url, timeout=timeout)
- logger.info("req txt={}".format(req.text))
- if req.json()["result"] == True:
- return "True"
- except Exception as e:
- logger.exception("An exception occurred: {}".format(e))
- return "False"
-
- app.run(debug=debug, host=host, port=port)
+CACHE = Cache()
+
+
+class Server:
+ """Base class for HTTP server"""
+
+ def __init__(self, host="localhost", port=80, api=None, **kwargs):
+ """Run a server
+
+ :param host: hostname of the server
+ :param port: port for the running server
+ :param kwargs: optional parameters
+ :return: a running server
+ """
+ self._host = host
+ self._port = port
+ self._api = api
+ self._extra = kwargs
+
+ @property
+ def host(self):
+ return self._host
+
+ @host.setter
+ def host(self, name):
+ self._host = name
+
+ @host.deleter
+ def host(self):
+ self._host = ""
+
+ @property
+ def port(self):
+ return self._port
+
+ @port.setter
+ def port(self, number):
+ self._port = number
+
+ @port.deleter
+ def port(self):
+ self._port = 80
+
+ def run(self):
+ raise NotImplementedError()
+
+__API__ = (
+ Status, Logs, API
+ )
+
+
+class Root(Resource):
+ """
+ The root of the web service
+ """
+ __urls__ = ("/", )
+ __methods = ("get", "post", "put", "delete", "options")
+
+ def get(self):
+ tree = {"/": {"methods": ("get",),
+ "description": "List all methods for that service."}}
+ for item in __API__:
+ tree[item.__name__] = {"urls": item.__urls__}
+ _methods = []
+ for _method in self.__methods:
+ if _method in dir(item):
+ _methods.append(_method)
+ tree[item.__name__]["methods"] = _methods
+ tree[item.__name__]["description"] = item.__doc__.strip()
+ return {
+ "version": __version__,
+ "tree": tree
+ }
+
+
+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.port = port
+ conf = configuration.get_configuration("components/orchestrator")
+ _hostname = conf["components/orchestrator"].get("hostname",
+ "orchestrator")
+ _port = conf["components/orchestrator"].get("port", 80)
+ _protocol = conf["components/orchestrator"].get("protocol", "http")
+ self.orchestrator_url = "{}://{}:{}".format(
+ _protocol, _hostname, _port)
+ # Todo : specify only few urls instead of *
+ # CORS(self.app)
+ self.api = Api(self.app)
+ 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, '/')
+
+ for api in __API__:
+ self.api.add_resource(api, *api.__urls__)
+ self.api.add_resource(Wrapper, *Wrapper.__urls__,
+ resource_class_kwargs={
+ "orchestrator_url": self.orchestrator_url,
+ "cache": CACHE,
+ }
+ )
+
+ def run(self):
+ self.app.run(host=self._host, port=self._port) # nosec
+ # self.app.run(debug=True, host=self._host, port=self._port) # nosec
+
diff --git a/moonv4/moon_wrapper/moon_wrapper/server.py b/moonv4/moon_wrapper/moon_wrapper/server.py
index 2e5f15b9..a3461018 100644
--- a/moonv4/moon_wrapper/moon_wrapper/server.py
+++ b/moonv4/moon_wrapper/moon_wrapper/server.py
@@ -25,8 +25,9 @@ def main():
configuration.add_component(uuid="wrapper", name=hostname, port=port, bind=bind)
LOG.info("Starting server with IP {} on port {} bind to {}".format(hostname, port, bind))
server = HTTPServer(host=bind, port=port)
- server.run()
+ return server
if __name__ == '__main__':
- main()
+ server = main()
+ server.run()
diff --git a/moonv4/moon_wrapper/requirements.txt b/moonv4/moon_wrapper/requirements.txt
index 51b57277..85ec611f 100644
--- a/moonv4/moon_wrapper/requirements.txt
+++ b/moonv4/moon_wrapper/requirements.txt
@@ -1,4 +1,5 @@
flask
flask_restful
-babel
+flask_cors
+werkzeug
moon_utilities \ No newline at end of file
diff --git a/moonv4/moon_wrapper/tests/README.md b/moonv4/moon_wrapper/tests/README.md
new file mode 100644
index 00000000..73a9fcd2
--- /dev/null
+++ b/moonv4/moon_wrapper/tests/README.md
@@ -0,0 +1,35 @@
+# Tests
+
+## Python Unit Test for moon_db
+
+- launch Docker for Python unit tests
+
+
+ cd ${MOON_HOME}/moonv4/moon_db/
+ docker run -ti --volume ${PWD}:/data asteroide/moon_tests
+
+
+## Build and upload python packages
+
+- build python packages
+
+
+ python setup.py sdist bdist_wheel
+
+
+- upload moon_db to PIP
+
+
+ python setup.py upload
+
+
+or
+
+
+ gpg --detach-sign -u "${GPG_ID}" -a dist/moon_db-X.Y.Z-py3-none-any.whl
+ gpg --detach-sign -u "${GPG_ID}" -a dist/moon_db-X.Y.Z.tar.gz
+ twine upload dist/moon_db-X.Y.Z-py3-none-any.whl dist/moon_db-X.Y.Z-py3-none-any.whl.asc
+ twine upload dist/moon_db-X.Y.Z.tar.gz dist/moon_db-X.Y.Z.tar.gz.asc
+
+
+
diff --git a/moonv4/moon_wrapper/tests/unit_python/api/__init__.py b/moonv4/moon_wrapper/tests/unit_python/api/__init__.py
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/moonv4/moon_wrapper/tests/unit_python/api/__init__.py
diff --git a/moonv4/moon_wrapper/tests/unit_python/api/test_wrapper.py b/moonv4/moon_wrapper/tests/unit_python/api/test_wrapper.py
new file mode 100644
index 00000000..7e9a7421
--- /dev/null
+++ b/moonv4/moon_wrapper/tests/unit_python/api/test_wrapper.py
@@ -0,0 +1,28 @@
+import json
+
+
+def get_json(data):
+ return json.loads(data.decode("utf-8"))
+
+
+def test_authz_true(context):
+ import moon_wrapper.server
+ server = moon_wrapper.server.main()
+ client = server.app.test_client()
+ _target = {
+ 'target': {
+ "name": context.get('object_name'),
+ },
+ "project_id": context.get('project_id'),
+ "user_id": context.get('subject_name')
+ }
+ authz_data = {
+ 'rule': context.get('action_name'),
+ 'target': json.dumps(_target),
+ 'credentials': 'null'}
+ req = client.post("/authz", data=json.dumps(authz_data))
+ assert req.status_code == 200
+ assert req.data
+ assert isinstance(req.data, bytes)
+ assert req.data == b"True"
+
diff --git a/moonv4/moon_wrapper/tests/unit_python/conftest.py b/moonv4/moon_wrapper/tests/unit_python/conftest.py
new file mode 100644
index 00000000..61c3da71
--- /dev/null
+++ b/moonv4/moon_wrapper/tests/unit_python/conftest.py
@@ -0,0 +1,687 @@
+import base64
+import json
+import os
+import pickle
+import pytest
+import requests_mock
+from uuid import uuid4
+from requests.packages.urllib3.response import HTTPResponse
+
+CONF = {
+ "openstack": {
+ "keystone": {
+ "url": "http://keystone:5000/v3",
+ "user": "admin",
+ "check_token": False,
+ "password": "p4ssw0rd",
+ "domain": "default",
+ "certificate": False,
+ "project": "admin"
+ }
+ },
+ "components": {
+ "wrapper": {
+ "bind": "0.0.0.0",
+ "port": 8080,
+ "container": "wukongsun/moon_wrapper:v4.3",
+ "timeout": 5,
+ "hostname": "wrapper"
+ },
+ "manager": {
+ "bind": "0.0.0.0",
+ "port": 8082,
+ "container": "wukongsun/moon_manager:v4.3",
+ "hostname": "manager"
+ },
+ "port_start": 31001,
+ "orchestrator": {
+ "bind": "0.0.0.0",
+ "port": 8083,
+ "container": "wukongsun/moon_orchestrator:v4.3",
+ "hostname": "orchestrator"
+ },
+ "interface": {
+ "bind": "0.0.0.0",
+ "port": 8080,
+ "container": "wukongsun/moon_interface:v4.3",
+ "hostname": "interface"
+ }
+ },
+ "plugins": {
+ "session": {
+ "port": 8082,
+ "container": "asteroide/session:latest"
+ },
+ "authz": {
+ "port": 8081,
+ "container": "wukongsun/moon_authz:v4.3"
+ }
+ },
+ "logging": {
+ "handlers": {
+ "file": {
+ "filename": "/tmp/moon.log",
+ "class": "logging.handlers.RotatingFileHandler",
+ "level": "DEBUG",
+ "formatter": "custom",
+ "backupCount": 3,
+ "maxBytes": 1048576
+ },
+ "console": {
+ "class": "logging.StreamHandler",
+ "formatter": "brief",
+ "level": "INFO",
+ "stream": "ext://sys.stdout"
+ }
+ },
+ "formatters": {
+ "brief": {
+ "format": "%(levelname)s %(name)s %(message)-30s"
+ },
+ "custom": {
+ "format": "%(asctime)-15s %(levelname)s %(name)s %(message)s"
+ }
+ },
+ "root": {
+ "handlers": [
+ "console"
+ ],
+ "level": "ERROR"
+ },
+ "version": 1,
+ "loggers": {
+ "moon": {
+ "handlers": [
+ "console",
+ "file"
+ ],
+ "propagate": False,
+ "level": "DEBUG"
+ }
+ }
+ },
+ "slave": {
+ "name": None,
+ "master": {
+ "url": None,
+ "login": None,
+ "password": None
+ }
+ },
+ "docker": {
+ "url": "tcp://172.88.88.1:2376",
+ "network": "moon"
+ },
+ "database": {
+ "url": "sqlite:///database.db",
+ # "url": "mysql+pymysql://moon:p4sswOrd1@db/moon",
+ "driver": "sql"
+ },
+ "messenger": {
+ "url": "rabbit://moon:p4sswOrd1@messenger:5672/moon"
+ }
+}
+
+COMPONENTS = (
+ "logging",
+ "openstack/keystone",
+ "database",
+ "slave",
+ "components/manager",
+ "components/orchestrator",
+ "components/interface",
+ "components/wrapper",
+)
+
+CONTEXT = {
+ "project_id": "a64beb1cc224474fb4badd43173e7101",
+ "subject_name": "testuser",
+ "object_name": "vm1",
+ "action_name": "boot",
+ "request_id": uuid4().hex,
+ "interface_name": "interface",
+ "manager_url": "http://{}:{}".format(
+ CONF["components"]["manager"]["hostname"],
+ CONF["components"]["manager"]["port"]
+ ),
+ "cookie": uuid4().hex
+ }
+
+
+def get_b64_conf(component=None):
+ if component == "components":
+ return base64.b64encode(
+ json.dumps(CONF["components"]).encode('utf-8')+b"\n").decode('utf-8')
+ elif component in CONF:
+ return base64.b64encode(
+ json.dumps(
+ CONF[component]).encode('utf-8')+b"\n").decode('utf-8')
+ elif not component:
+ return base64.b64encode(
+ json.dumps(CONF).encode('utf-8')+b"\n").decode('utf-8')
+ elif "/" in component:
+ key1, _, key2 = component.partition("/")
+ return base64.b64encode(
+ json.dumps(
+ CONF[key1][key2]).encode('utf-8')+b"\n").decode('utf-8')
+
+
+MOCK_URLS = [
+ ('GET', 'http://consul:8500/v1/kv/components?recurse=true',
+ {'json': {"Key": key, "Value": get_b64_conf(key)}
+ for key in COMPONENTS}
+ ),
+ ('POST', 'http://keystone:5000/v3/auth/tokens',
+ {'headers': {'X-Subject-Token': "111111111"}}),
+ ('DELETE', 'http://keystone:5000/v3/auth/tokens',
+ {'headers': {'X-Subject-Token': "111111111"}}),
+ ('POST', 'http://keystone:5000/v3/users?name=testuser&domain_id=default',
+ {'json': {"users": {}}}),
+ ('GET', 'http://keystone:5000/v3/users?name=testuser&domain_id=default',
+ {'json': {"users": {}}}),
+ ('POST', 'http://keystone:5000/v3/users/',
+ {'json': {"users": [{
+ "id": "1111111111111"
+ }]}}),
+]
+
+
+@pytest.fixture
+def db():
+ return CONF['database']
+
+
+@pytest.fixture
+def context():
+ return CONTEXT
+
+
+def set_env_variables():
+ os.environ['UUID'] = "1111111111"
+ os.environ['TYPE'] = "authz"
+ os.environ['PORT'] = "8081"
+ os.environ['PDP_ID'] = "b3d3e18abf3340e8b635fd49e6634ccd"
+ os.environ['META_RULE_ID'] = "f8f49a779ceb47b3ac810f01ef71b4e0"
+ os.environ['KEYSTONE_PROJECT_ID'] = CONTEXT['project_id']
+
+
+def get_pickled_context():
+ from moon_utilities.security_functions import Context
+ from moon_utilities.cache import Cache
+ CACHE = Cache()
+ CACHE.update()
+ _context = Context(context(), CACHE)
+ _context.increment_index()
+ _context.pdp_set['effect'] = 'grant'
+ _context.pdp_set[os.environ['META_RULE_ID']]['effect'] = 'grant'
+ return pickle.dumps(_context)
+
+
+@pytest.fixture(autouse=True)
+def set_consul_and_db(monkeypatch):
+ """ Modify the response from Requests module
+ """
+ set_env_variables()
+ with requests_mock.Mocker(real_http=True) as m:
+ for component in COMPONENTS:
+ m.register_uri(
+ 'GET', 'http://consul:8500/v1/kv/{}'.format(component),
+ json=[{'Key': component, 'Value': get_b64_conf(component)}]
+ )
+ # for _data in MOCK_URLS:
+ # m.register_uri(_data[0], _data[1], **_data[2])
+ m.register_uri(
+ 'GET', 'http://consul:8500/v1/kv/components?recurse=true',
+ json=[
+ {"Key": key, "Value": get_b64_conf(key)} for key in COMPONENTS
+ ],
+ )
+ m.register_uri(
+ 'GET', 'http://consul:8500/v1/kv/plugins/authz',
+ json=[
+ {
+ "LockIndex": 0,
+ "Key": "plugins/authz",
+ "Flags": 0,
+ "Value": "eyJjb250YWluZXIiOiAid3Vrb25nc3VuL21vb25fYXV0aHo6djQuMyIsICJwb3J0IjogODA4MX0=",
+ "CreateIndex": 14,
+ "ModifyIndex": 656
+ }
+ ],
+ )
+ 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"
+ }]}
+ )
+ m.register_uri(
+ 'GET', 'http://orchestrator:8083/pods',
+ json={
+ "pods": {
+ "721760dd-de5f-11e7-8001-3863bbb766f3": [
+ {
+ "pdp_id": "b3d3e18abf3340e8b635fd49e6634ccd",
+ "port": 8080,
+ "genre": "interface",
+ "name": "interface-paltry",
+ "keystone_project_id": "a64beb1cc224474fb4badd43173e7101",
+ "namespace": "moon",
+ "container": "wukongsun/moon_interface:v4.3"
+ },
+ {
+ "pdp_id": "b3d3e18abf3340e8b635fd49e6634ccd",
+ "meta_rule_id": "f8f49a779ceb47b3ac810f01ef71b4e0",
+ "port": 8081,
+ "genre": "authz",
+ "name": "authz-economic",
+ "policy_id": "f8f49a779ceb47b3ac810f01ef71b4e0",
+ "keystone_project_id": "a64beb1cc224474fb4badd43173e7101",
+ "namespace": "moon",
+ "container": "wukongsun/moon_authz:v4.3"
+ }
+ ],
+ "232399a4-de5f-11e7-8001-3863bbb766f3": [
+ {
+ "port": 8080,
+ "namespace": "moon",
+ "name": "wrapper-paltry",
+ "container": "wukongsun/moon_wrapper:v4.3.1"
+ }
+ ]
+ }
+ }
+ )
+ m.register_uri(
+ 'GET', 'http://orchestrator:8083/pods/authz-economic',
+ json={
+ "pods": None
+ }
+ )
+ m.register_uri(
+ 'GET', 'http://manager:8082/pdp',
+ json={
+ "pdps": {
+ "b3d3e18abf3340e8b635fd49e6634ccd": {
+ "description": "test",
+ "security_pipeline": [
+ "f8f49a779ceb47b3ac810f01ef71b4e0"
+ ],
+ "name": "pdp_rbac",
+ "keystone_project_id": "a64beb1cc224474fb4badd43173e7101"
+ }
+ }
+ }
+ )
+ m.register_uri(
+ 'GET', 'http://manager:8082/policies',
+ json={
+ "policies": {
+ "f8f49a779ceb47b3ac810f01ef71b4e0": {
+ "name": "RBAC policy example",
+ "model_id": "cd923d8633ff4978ab0e99938f5153d6",
+ "description": "test",
+ "genre": "authz"
+ }
+ }
+ }
+ )
+ m.register_uri(
+ 'GET', 'http://manager:8082/models',
+ json={
+ "models": {
+ "cd923d8633ff4978ab0e99938f5153d6": {
+ "name": "RBAC",
+ "meta_rules": [
+ "f8f49a779ceb47b3ac810f01ef71b4e0"
+ ],
+ "description": "test"
+ }
+ }
+ }
+ )
+ m.register_uri(
+ 'GET', 'http://manager:8082/meta_rules',
+ json={
+ "meta_rules": {
+ "f8f49a779ceb47b3ac810f01ef71b4e0": {
+ "subject_categories": [
+ "14e6ae0ba34d458b876c791b73aa17bd"
+ ],
+ "action_categories": [
+ "241a2a791554421a91c9f1bc564aa94d"
+ ],
+ "description": "",
+ "name": "rbac",
+ "object_categories": [
+ "6d48500f639d4c2cab2b1f33ef93a1e8"
+ ]
+ }
+ }
+ }
+ )
+ m.register_uri(
+ 'GET', 'http://manager:8082/policies/f8f49a779ceb47b3ac810f01ef71b4e0/subjects',
+ json={
+ "subjects": {
+ "89ba91c18dd54abfbfde7a66936c51a6": {
+ "description": "test",
+ "policy_list": [
+ "f8f49a779ceb47b3ac810f01ef71b4e0",
+ "636cd473324f4c0bbd9102cb5b62a16d"
+ ],
+ "name": "testuser",
+ "email": "mail",
+ "id": "89ba91c18dd54abfbfde7a66936c51a6",
+ "partner_id": ""
+ },
+ "31fd15ad14784a9696fcc887dddbfaf9": {
+ "description": "test",
+ "policy_list": [
+ "f8f49a779ceb47b3ac810f01ef71b4e0",
+ "636cd473324f4c0bbd9102cb5b62a16d"
+ ],
+ "name": "adminuser",
+ "email": "mail",
+ "id": "31fd15ad14784a9696fcc887dddbfaf9",
+ "partner_id": ""
+ }
+ }
+ }
+ )
+ m.register_uri(
+ 'GET', 'http://manager:8082/policies/f8f49a779ceb47b3ac810f01ef71b4e0/objects',
+ json={
+ "objects": {
+ "67b8008a3f8d4f8e847eb628f0f7ca0e": {
+ "name": "vm1",
+ "description": "test",
+ "id": "67b8008a3f8d4f8e847eb628f0f7ca0e",
+ "partner_id": "",
+ "policy_list": [
+ "f8f49a779ceb47b3ac810f01ef71b4e0",
+ "636cd473324f4c0bbd9102cb5b62a16d"
+ ]
+ },
+ "9089b3d2ce5b4e929ffc7e35b55eba1a": {
+ "name": "vm0",
+ "description": "test",
+ "id": "9089b3d2ce5b4e929ffc7e35b55eba1a",
+ "partner_id": "",
+ "policy_list": [
+ "f8f49a779ceb47b3ac810f01ef71b4e0",
+ "636cd473324f4c0bbd9102cb5b62a16d"
+ ]
+ }
+ }
+ }
+ )
+ m.register_uri(
+ 'GET', 'http://manager:8082/policies/f8f49a779ceb47b3ac810f01ef71b4e0/actions',
+ json={
+ "actions": {
+ "cdb3df220dc05a6ea3334b994827b068": {
+ "name": "boot",
+ "description": "test",
+ "id": "cdb3df220dc04a6ea3334b994827b068",
+ "partner_id": "",
+ "policy_list": [
+ "f8f49a779ceb47b3ac810f01ef71b4e0",
+ "636cd473324f4c0bbd9102cb5b62a16d"
+ ]
+ },
+ "cdb3df220dc04a6ea3334b994827b068": {
+ "name": "stop",
+ "description": "test",
+ "id": "cdb3df220dc04a6ea3334b994827b068",
+ "partner_id": "",
+ "policy_list": [
+ "f8f49a779ceb47b3ac810f01ef71b4e0",
+ "636cd473324f4c0bbd9102cb5b62a16d"
+ ]
+ },
+ "9f5112afe9b34a6c894eb87246ccb7aa": {
+ "name": "start",
+ "description": "test",
+ "id": "9f5112afe9b34a6c894eb87246ccb7aa",
+ "partner_id": "",
+ "policy_list": [
+ "f8f49a779ceb47b3ac810f01ef71b4e0",
+ "636cd473324f4c0bbd9102cb5b62a16d"
+ ]
+ }
+ }
+ }
+ )
+ m.register_uri(
+ 'GET', 'http://manager:8082/policies/f8f49a779ceb47b3ac810f01ef71b4e0/subject_assignments',
+ json={
+ "subject_assignments": {
+ "826c1156d0284fc9b4b2ddb279f63c52": {
+ "category_id": "14e6ae0ba34d458b876c791b73aa17bd",
+ "assignments": [
+ "24ea95256c5f4c888c1bb30a187788df",
+ "6b227b77184c48b6a5e2f3ed1de0c02a",
+ "31928b17ec90438ba5a2e50ae7650e63",
+ "4e60f554dd3147af87595fb6b37dcb13",
+ "7a5541b63a024fa88170a6b59f99ccd7",
+ "dd2af27812f742029d289df9687d6126"
+ ],
+ "id": "826c1156d0284fc9b4b2ddb279f63c52",
+ "subject_id": "89ba91c18dd54abfbfde7a66936c51a6",
+ "policy_id": "f8f49a779ceb47b3ac810f01ef71b4e0"
+ },
+ "7407ffc1232944279b0cbcb0847c86f7": {
+ "category_id": "315072d40d774c43a89ff33937ed24eb",
+ "assignments": [
+ "6b227b77184c48b6a5e2f3ed1de0c02a",
+ "31928b17ec90438ba5a2e50ae7650e63",
+ "7a5541b63a024fa88170a6b59f99ccd7",
+ "dd2af27812f742029d289df9687d6126"
+ ],
+ "id": "7407ffc1232944279b0cbcb0847c86f7",
+ "subject_id": "89ba91c18dd54abfbfde7a66936c51a6",
+ "policy_id": "3e65256389b448cb9897917ea235f0bb"
+ }
+ }
+ }
+ )
+ m.register_uri(
+ 'GET', 'http://manager:8082/policies/f8f49a779ceb47b3ac810f01ef71b4e0/object_assignments',
+ json={
+ "object_assignments": {
+ "201ad05fd3f940948b769ab9214fe295": {
+ "object_id": "9089b3d2ce5b4e929ffc7e35b55eba1a",
+ "assignments": [
+ "030fbb34002e4236a7b74eeb5fd71e35",
+ "06bcb8655b9d46a9b90e67ef7c825b50",
+ "34eb45d7f46d4fb6bc4965349b8e4b83",
+ "4b7793dbae434c31a77da9d92de9fa8c"
+ ],
+ "id": "201ad05fd3f940948b769ab9214fe295",
+ "category_id": "6d48500f639d4c2cab2b1f33ef93a1e8",
+ "policy_id": "f8f49a779ceb47b3ac810f01ef71b4e0"
+ },
+ "90c5e86f8be34c0298fbd1973e4fb043": {
+ "object_id": "67b8008a3f8d4f8e847eb628f0f7ca0e",
+ "assignments": [
+ "a098918e915b4b12bccb89f9a3f3b4e4",
+ "06bcb8655b9d46a9b90e67ef7c825b50",
+ "7dc76c6142af47c88b60cc2b0df650ba",
+ "4b7793dbae434c31a77da9d92de9fa8c"
+ ],
+ "id": "90c5e86f8be34c0298fbd1973e4fb043",
+ "category_id": "33aece52d45b4474a20dc48a76800daf",
+ "policy_id": "3e65256389b448cb9897917ea235f0bb"
+ }
+ }
+ }
+ )
+ m.register_uri(
+ 'GET', 'http://manager:8082/policies/f8f49a779ceb47b3ac810f01ef71b4e0/action_assignments',
+ json={
+ "action_assignments": {
+ "2128e3ffbd1c4ef5be515d625745c2d4": {
+ "category_id": "241a2a791554421a91c9f1bc564aa94d",
+ "action_id": "cdb3df220dc05a6ea3334b994827b068",
+ "policy_id": "f8f49a779ceb47b3ac810f01ef71b4e0",
+ "id": "2128e3ffbd1c4ef5be515d625745c2d4",
+ "assignments": [
+ "570c036781e540dc9395b83098c40ba7",
+ "7fe17d7a2e3542719f8349c3f2273182",
+ "015ca6f40338422ba3f692260377d638",
+ "23d44c17bf88480f83e8d57d2aa1ea79"
+ ]
+ },
+ "cffb98852f3a4110af7a0ddfc4e19201": {
+ "category_id": "4a2c5abaeaf644fcaf3ca8df64000d53",
+ "action_id": "cdb3df220dc04a6ea3334b994827b068",
+ "policy_id": "3e65256389b448cb9897917ea235f0bb",
+ "id": "cffb98852f3a4110af7a0ddfc4e19201",
+ "assignments": [
+ "570c036781e540dc9395b83098c40ba7",
+ "7fe17d7a2e3542719f8349c3f2273182",
+ "015ca6f40338422ba3f692260377d638",
+ "23d44c17bf88480f83e8d57d2aa1ea79"
+ ]
+ }
+ }
+ }
+ )
+ m.register_uri(
+ 'GET', 'http://manager:8082/policies/f8f49a779ceb47b3ac810f01ef71b4e0/subject_assignments/89ba91c18dd54abfbfde7a66936c51a6',
+ json={
+ "subject_assignments": {
+ "826c1156d0284fc9b4b2ddb279f63c52": {
+ "category_id": "14e6ae0ba34d458b876c791b73aa17bd",
+ "assignments": [
+ "24ea95256c5f4c888c1bb30a187788df",
+ "6b227b77184c48b6a5e2f3ed1de0c02a",
+ "31928b17ec90438ba5a2e50ae7650e63",
+ "4e60f554dd3147af87595fb6b37dcb13",
+ "7a5541b63a024fa88170a6b59f99ccd7",
+ "dd2af27812f742029d289df9687d6126"
+ ],
+ "id": "826c1156d0284fc9b4b2ddb279f63c52",
+ "subject_id": "89ba91c18dd54abfbfde7a66936c51a6",
+ "policy_id": "f8f49a779ceb47b3ac810f01ef71b4e0"
+ }
+ }
+ }
+ )
+ m.register_uri(
+ 'GET', 'http://manager:8082/policies/f8f49a779ceb47b3ac810f01ef71b4e0/object_assignments/67b8008a3f8d4f8e847eb628f0f7ca0e',
+ json={
+ "object_assignments": {
+ "201ad05fd3f940948b769ab9214fe295": {
+ "object_id": "67b8008a3f8d4f8e847eb628f0f7ca0e",
+ "assignments": [
+ "030fbb34002e4236a7b74eeb5fd71e35",
+ "06bcb8655b9d46a9b90e67ef7c825b50",
+ "34eb45d7f46d4fb6bc4965349b8e4b83",
+ "4b7793dbae434c31a77da9d92de9fa8c"
+ ],
+ "id": "201ad05fd3f940948b769ab9214fe295",
+ "category_id": "6d48500f639d4c2cab2b1f33ef93a1e8",
+ "policy_id": "f8f49a779ceb47b3ac810f01ef71b4e0"
+ }
+ }
+ }
+ )
+ m.register_uri(
+ 'GET', 'http://manager:8082/policies/f8f49a779ceb47b3ac810f01ef71b4e0/action_assignments/cdb3df220dc05a6ea3334b994827b068',
+ json={
+ "action_assignments": {
+ "2128e3ffbd1c4ef5be515d625745c2d4": {
+ "category_id": "241a2a791554421a91c9f1bc564aa94d",
+ "action_id": "cdb3df220dc05a6ea3334b994827b068",
+ "policy_id": "f8f49a779ceb47b3ac810f01ef71b4e0",
+ "id": "2128e3ffbd1c4ef5be515d625745c2d4",
+ "assignments": [
+ "570c036781e540dc9395b83098c40ba7",
+ "7fe17d7a2e3542719f8349c3f2273182",
+ "015ca6f40338422ba3f692260377d638",
+ "23d44c17bf88480f83e8d57d2aa1ea79"
+ ]
+ }
+ }
+ }
+ )
+ m.register_uri(
+ 'GET', 'http://manager:8082/policies/f8f49a779ceb47b3ac810f01ef71b4e0/rules',
+ json={
+ "rules": {
+ "policy_id": "f8f49a779ceb47b3ac810f01ef71b4e0",
+ "rules": [
+ {
+ "policy_id": "f8f49a779ceb47b3ac810f01ef71b4e0",
+ "rule": [
+ "24ea95256c5f4c888c1bb30a187788df",
+ "030fbb34002e4236a7b74eeb5fd71e35",
+ "570c036781e540dc9395b83098c40ba7"
+ ],
+ "enabled": True,
+ "id": "0201a2bcf56943c1904dbac016289b71",
+ "instructions": [
+ {
+ "decision": "grant"
+ }
+ ],
+ "meta_rule_id": "f8f49a779ceb47b3ac810f01ef71b4e0"
+ },
+ {
+ "policy_id": "ecc2451c494e47b5bca7250cd324a360",
+ "rule": [
+ "54f574cd2043468da5d65e4f6ed6e3c9",
+ "6559686961a3490a978f246ac9f85fbf",
+ "ac0d1f600bf447e8bd2f37b7cc47f2dc"
+ ],
+ "enabled": True,
+ "id": "a83fed666af8436192dfd8b3c83a6fde",
+ "instructions": [
+ {
+ "decision": "grant"
+ }
+ ],
+ "meta_rule_id": "f8f49a779ceb47b3ac810f01ef71b4e0"
+ }
+ ]
+ }
+ }
+ )
+ m.register_uri(
+ 'POST', 'http://127.0.0.1:8081/authz',
+ content=get_pickled_context()
+ )
+ m.register_uri(
+ 'GET', 'http://interface-paltry:8080/authz/{}/{}/{}/{}'.format(
+ CONTEXT.get("project_id"),
+ CONTEXT.get("subject_name"),
+ CONTEXT.get("object_name"),
+ CONTEXT.get("action_name"),
+ ),
+ json={"result": True, "message": "================"}
+ )
+ # from moon_db.db_manager import init_engine, run
+ # engine = init_engine()
+ # run("upgrade", logging.getLogger("db_manager"), engine)
+ yield m
+ # os.unlink(CONF['database']['url'].replace("sqlite:///", ""))
+
+
diff --git a/moonv4/moon_wrapper/tests/unit_python/requirements.txt b/moonv4/moon_wrapper/tests/unit_python/requirements.txt
new file mode 100644
index 00000000..8bd8449f
--- /dev/null
+++ b/moonv4/moon_wrapper/tests/unit_python/requirements.txt
@@ -0,0 +1,5 @@
+flask
+flask_cors
+flask_restful
+moon_db
+moon_utilities \ No newline at end of file
diff --git a/moonv4/moon_consul/Changelog b/moonv4/python_moonclient/Changelog
index 5ccc3c27..854200cb 100644
--- a/moonv4/moon_consul/Changelog
+++ b/moonv4/python_moonclient/Changelog
@@ -9,5 +9,4 @@ CHANGES
0.1.0
-----
-- First version of the moon_consul component.
-
+- First version of the python-moonclient \ No newline at end of file
diff --git a/moonv4/moon_router/LICENSE b/moonv4/python_moonclient/LICENSE
index 4143aac2..d6456956 100644
--- a/moonv4/moon_router/LICENSE
+++ b/moonv4/python_moonclient/LICENSE
@@ -174,31 +174,29 @@
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
---- License for python-keystoneclient versions prior to 2.1 ---
-
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
-
- 1. Redistributions of source code must retain the above copyright notice,
- this list of conditions and the following disclaimer.
-
- 2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-
- 3. Neither the name of this project nor the names of its contributors may
- be used to endorse or promote products derived from this software without
- specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
-FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
-SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
-CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
-OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ END OF TERMS AND CONDITIONS
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright [yyyy] [name of copyright owner]
+
+ 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.
diff --git a/moonv4/moon_router/MANIFEST.in b/moonv4/python_moonclient/MANIFEST.in
index 1f674d50..2a5ac509 100644
--- a/moonv4/moon_router/MANIFEST.in
+++ b/moonv4/python_moonclient/MANIFEST.in
@@ -3,7 +3,8 @@
# 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 Changelog
include setup.py
include requirements.txt
diff --git a/moonv4/python_moonclient/README.md b/moonv4/python_moonclient/README.md
new file mode 100644
index 00000000..d091cdf5
--- /dev/null
+++ b/moonv4/python_moonclient/README.md
@@ -0,0 +1,33 @@
+# python-moonclient Package
+This package contains the core module for the Moon project.
+It is designed to provide authorization feature to all OpenStack components.
+
+For any other information, refer to the parent project:
+
+ https://git.opnfv.org/moon
+
+moon_utilities is a common Python lib for other Moon Python packages
+
+## Build
+### Build Python Package
+```bash
+cd ${MOON_HOME}/moonv4/python_moonclient
+python3 setup.py sdist bdist_wheel
+```
+
+### Push Python Package to PIP
+```bash
+cd ${MOON_HOME}/moonv4/python_moonclient
+gpg --detach-sign -u "${GPG_ID}" -a dist/python_moonclient-X.Y.Z-py3-none-any.whl
+gpg --detach-sign -u "${GPG_ID}" -a dist/python_moonclient-X.Y.Z.tar.gz
+twine upload dist/python_moonclient-X.Y.Z-py3-none-any.whl dist/python_moonclient-X.Y.Z-py3-none-any.whl.asc
+twine upload dist/python_moonclient-X.Y.Z.tar.gz dist/python_moonclient-X.Y.Z.tar.gz.asc
+```
+
+## Test
+### Python Unit Test
+launch Docker for Python unit tests
+```bash
+cd ${MOON_HOME}/moonv4/python_moonclient
+docker run --rm --volume $(pwd):/data wukongsun/moon_python_unit_test:latest
+```
diff --git a/moonv4/python_moonclient/python_moonclient/__init__.py b/moonv4/python_moonclient/python_moonclient/__init__.py
new file mode 100644
index 00000000..d7cdd111
--- /dev/null
+++ b/moonv4/python_moonclient/python_moonclient/__init__.py
@@ -0,0 +1,6 @@
+# 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'.
+
+__version__ = "0.0.1"
diff --git a/moonv4/python_moonclient/python_moonclient/config.py b/moonv4/python_moonclient/python_moonclient/config.py
new file mode 100644
index 00000000..d6317820
--- /dev/null
+++ b/moonv4/python_moonclient/python_moonclient/config.py
@@ -0,0 +1,44 @@
+import base64
+import json
+import requests
+
+
+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")
+ data = req.json()
+ if len(data) == 1:
+ data = data[0]
+ return {data["Key"]: json.loads(base64.b64decode(data["Value"]).decode("utf-8"))}
+ else:
+ return [
+ {item["Key"]: json.loads(base64.b64decode(item["Value"]).decode("utf-8"))}
+ for item in data
+ ]
+
+
+def get_config_data(consul_host, consul_port):
+ conf_data = dict()
+ conf_data['manager_host'] = get_configuration(consul_host, consul_port,
+ 'components/manager')['components/manager']['external']['hostname']
+ conf_data['manager_port'] = get_configuration(consul_host, consul_port,
+ 'components/manager')['components/manager']['external']['port']
+ # conf_data['authz_host'] = get_configuration(consul_host, consul_port,
+ # 'components/interface')['components/interface']['external']['hostname']
+ # conf_data['authz_port'] = get_configuration(consul_host, consul_port,
+ # 'components/interface')['components/interface']['external']['port']
+ conf_data['keystone_host'] = get_configuration(consul_host, consul_port,
+ 'openstack/keystone')['openstack/keystone']['external']['url']
+ # conf_data['keystone_port'] = '5000'
+ conf_data['keystone_user'] = get_configuration(consul_host, consul_port,
+ 'openstack/keystone')['openstack/keystone']['user']
+ conf_data['keystone_password'] = get_configuration(consul_host, consul_port,
+ 'openstack/keystone')['openstack/keystone']['password']
+ conf_data['keystone_project'] = get_configuration(consul_host, consul_port,
+ 'openstack/keystone')['openstack/keystone']['project']
+ return conf_data
+
+# get_conf_data('88.88.88.2', '30005')
+# get_conf_data('127.0.0.1', 8082)
diff --git a/moonv4/python_moonclient/requirements.txt b/moonv4/python_moonclient/requirements.txt
new file mode 100644
index 00000000..5b80e5f2
--- /dev/null
+++ b/moonv4/python_moonclient/requirements.txt
@@ -0,0 +1,3 @@
+werkzeug
+flask
+requests \ No newline at end of file
diff --git a/moonv4/python_moonclient/setup.py b/moonv4/python_moonclient/setup.py
new file mode 100644
index 00000000..000e87ca
--- /dev/null
+++ b/moonv4/python_moonclient/setup.py
@@ -0,0 +1,42 @@
+# 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 python_moonclient
+
+with open('requirements.txt') as f:
+ required = f.read().splitlines()
+
+setup(
+
+ name='python-moonclient',
+
+ version=python_moonclient.__version__,
+
+ packages=find_packages(),
+
+ author='Thomas Duval & Ruan He',
+
+ author_email='thomas.duval@orange.com, ruan.he@orange.com',
+
+ description='client lib for all the Moon components',
+
+ long_description=open('README.md').read(),
+
+ install_requires=required,
+
+ include_package_data=True,
+
+ url='https://git.opnfv.org/cgit/moon',
+
+ classifiers=[
+ 'Programming Language :: Python :: 3',
+ 'Development Status :: 1 - Planning',
+ 'License :: OSI Approved',
+ 'Natural Language :: English',
+ 'Operating System :: OS Independent',
+ ],
+
+)
diff --git a/moonv4/python_moonclient/tests/unit_python/conftest.py b/moonv4/python_moonclient/tests/unit_python/conftest.py
new file mode 100644
index 00000000..d26df946
--- /dev/null
+++ b/moonv4/python_moonclient/tests/unit_python/conftest.py
@@ -0,0 +1,12 @@
+import pytest
+import requests_mock
+import mock_config
+
+
+@pytest.fixture(autouse=True)
+def no_requests(monkeypatch):
+ """ Modify the response from Requests module
+ """
+ with requests_mock.Mocker(real_http=True) as m:
+ mock_config.register_consul(m)
+ yield m
diff --git a/moonv4/python_moonclient/tests/unit_python/mock_config.py b/moonv4/python_moonclient/tests/unit_python/mock_config.py
new file mode 100644
index 00000000..a3084485
--- /dev/null
+++ b/moonv4/python_moonclient/tests/unit_python/mock_config.py
@@ -0,0 +1,35 @@
+import utilities
+
+
+components_manager_mock = {
+ "port": 8082,
+ "bind": "0.0.0.0",
+ "hostname": "manager",
+ "container": "wukongsun/moon_manager:v4.3.1",
+ "external": {
+ "port": 30001,
+ "hostname": "88.88.88.2"
+ }
+}
+
+
+openstack_keystone_mock = {
+ "url": "http://keystone:5000/v3",
+ "user": "admin",
+ "password": "p4ssw0rd",
+ "domain": "default",
+ "project": "admin",
+ "check_token": False,
+ "certificate": False,
+ "external": {
+ "url": "http://88.88.88.2:30006/v3"
+ }
+}
+
+
+def register_consul(m):
+ for component in utilities.COMPONENTS:
+ m.register_uri(
+ 'GET', 'http://consul:8500/v1/kv/{}'.format(component),
+ json=[{'Key': component, 'Value': utilities.get_b64_conf(component)}]
+ )
diff --git a/moonv4/python_moonclient/tests/unit_python/requirements.txt b/moonv4/python_moonclient/tests/unit_python/requirements.txt
new file mode 100644
index 00000000..3c1ad607
--- /dev/null
+++ b/moonv4/python_moonclient/tests/unit_python/requirements.txt
@@ -0,0 +1,2 @@
+pytest
+requests_mock \ No newline at end of file
diff --git a/moonv4/python_moonclient/tests/unit_python/test_config.py b/moonv4/python_moonclient/tests/unit_python/test_config.py
new file mode 100644
index 00000000..21b5f630
--- /dev/null
+++ b/moonv4/python_moonclient/tests/unit_python/test_config.py
@@ -0,0 +1,8 @@
+import pytest
+import utilities
+
+
+def test_authz_request():
+ from python_moonclient import config
+ conf_data = config.get_config_data("consul", 8500)
+ assert isinstance(conf_data, dict)
diff --git a/moonv4/python_moonclient/tests/unit_python/utilities.py b/moonv4/python_moonclient/tests/unit_python/utilities.py
new file mode 100644
index 00000000..ae2932c7
--- /dev/null
+++ b/moonv4/python_moonclient/tests/unit_python/utilities.py
@@ -0,0 +1,153 @@
+import base64
+import json
+
+CONF = {
+ "openstack": {
+ "keystone": {
+ "url": "http://keystone:5000/v3",
+ "user": "admin",
+ "check_token": False,
+ "password": "p4ssw0rd",
+ "domain": "default",
+ "certificate": False,
+ "project": "admin",
+ "external": {
+ "url": "http://keystone:5000/v3",
+ }
+ }
+ },
+ "components": {
+ "wrapper": {
+ "bind": "0.0.0.0",
+ "port": 8080,
+ "container": "wukongsun/moon_wrapper:v4.3",
+ "timeout": 5,
+ "hostname": "wrapper"
+ },
+ "manager": {
+ "bind": "0.0.0.0",
+ "port": 8082,
+ "container": "wukongsun/moon_manager:v4.3",
+ "hostname": "manager",
+ "external": {
+ "hostname": "manager",
+ "port": 30001
+ }
+ },
+ "port_start": 31001,
+ "orchestrator": {
+ "bind": "0.0.0.0",
+ "port": 8083,
+ "container": "wukongsun/moon_orchestrator:v4.3",
+ "hostname": "orchestrator"
+ },
+ "interface": {
+ "bind": "0.0.0.0",
+ "port": 8080,
+ "container": "wukongsun/moon_interface:v4.3",
+ "hostname": "interface"
+ }
+ },
+ "plugins": {
+ "session": {
+ "port": 8082,
+ "container": "asteroide/session:latest"
+ },
+ "authz": {
+ "port": 8081,
+ "container": "wukongsun/moon_authz:v4.3"
+ }
+ },
+ "logging": {
+ "handlers": {
+ "file": {
+ "filename": "/tmp/moon.log",
+ "class": "logging.handlers.RotatingFileHandler",
+ "level": "DEBUG",
+ "formatter": "custom",
+ "backupCount": 3,
+ "maxBytes": 1048576
+ },
+ "console": {
+ "class": "logging.StreamHandler",
+ "formatter": "brief",
+ "level": "INFO",
+ "stream": "ext://sys.stdout"
+ }
+ },
+ "formatters": {
+ "brief": {
+ "format": "%(levelname)s %(name)s %(message)-30s"
+ },
+ "custom": {
+ "format": "%(asctime)-15s %(levelname)s %(name)s %(message)s"
+ }
+ },
+ "root": {
+ "handlers": [
+ "console"
+ ],
+ "level": "ERROR"
+ },
+ "version": 1,
+ "loggers": {
+ "moon": {
+ "handlers": [
+ "console",
+ "file"
+ ],
+ "propagate": False,
+ "level": "DEBUG"
+ }
+ }
+ },
+ "slave": {
+ "name": None,
+ "master": {
+ "url": None,
+ "login": None,
+ "password": None
+ }
+ },
+ "docker": {
+ "url": "tcp://172.88.88.1:2376",
+ "network": "moon"
+ },
+ "database": {
+ "url": "sqlite:///database.db",
+ # "url": "mysql+pymysql://moon:p4sswOrd1@db/moon",
+ "driver": "sql"
+ },
+ "messenger": {
+ "url": "rabbit://moon:p4sswOrd1@messenger:5672/moon"
+ }
+}
+
+COMPONENTS = (
+ "logging",
+ "openstack/keystone",
+ "database",
+ "slave",
+ "components/manager",
+ "components/orchestrator",
+ "components/interface",
+ "components/wrapper",
+)
+
+
+def get_b64_conf(component=None):
+ if component == "components":
+ return base64.b64encode(
+ json.dumps(CONF["components"]).encode('utf-8')+b"\n").decode('utf-8')
+ elif component in CONF:
+ return base64.b64encode(
+ json.dumps(
+ CONF[component]).encode('utf-8')+b"\n").decode('utf-8')
+ elif not component:
+ return base64.b64encode(
+ json.dumps(CONF).encode('utf-8')+b"\n").decode('utf-8')
+ elif "/" in component:
+ key1, _, key2 = component.partition("/")
+ return base64.b64encode(
+ json.dumps(
+ CONF[key1][key2]).encode('utf-8')+b"\n").decode('utf-8')
diff --git a/moonv4/templates/glance/policy.json b/moonv4/templates/glance/policy.json
new file mode 100644
index 00000000..5505f67f
--- /dev/null
+++ b/moonv4/templates/glance/policy.json
@@ -0,0 +1,62 @@
+{
+ "context_is_admin": "role:admin",
+ "default": "role:admin",
+
+ "add_image": "http://my_hostname:31001/authz",
+ "delete_image": "http://my_hostname:31001/authz",
+ "get_image": "http://my_hostname:31001/authz",
+ "get_images": "http://my_hostname:31001/authz",
+ "modify_image": "http://my_hostname:31001/authz",
+ "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": "role:admin",
+ "get_tasks": "role:admin",
+ "add_task": "role:admin",
+ "modify_task": "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/moonv4/templates/moonforming/Dockerfile b/moonv4/templates/moonforming/Dockerfile
new file mode 100644
index 00000000..87a067f9
--- /dev/null
+++ b/moonv4/templates/moonforming/Dockerfile
@@ -0,0 +1,10 @@
+FROM python:3
+WORKDIR /usr/src/app
+RUN pip install --no-cache-dir --upgrade requests pyyaml moon_utilities moon_db
+
+ENV POPULATE_ARGS "-v"
+
+ADD . /root
+WORKDIR /root
+
+CMD sh /root/run.sh ${POPULATE_ARGS} \ No newline at end of file
diff --git a/moonv4/templates/moonforming/README.md b/moonv4/templates/moonforming/README.md
new file mode 100644
index 00000000..f6327693
--- /dev/null
+++ b/moonv4/templates/moonforming/README.md
@@ -0,0 +1,12 @@
+Introduction
+============
+
+moonforming is a container used to automatize the configuration of the Moon patform
+
+Usage
+=====
+
+```bash
+docker run asteroide/moonforming:v1.1
+```
+
diff --git a/moonv4/moon_interface/tests/apitests/scenario/mls.py b/moonv4/templates/moonforming/conf/mls.py
index 3a3ded43..0e6285c9 100644
--- a/moonv4/moon_interface/tests/apitests/scenario/mls.py
+++ b/moonv4/templates/moonforming/conf/mls.py
@@ -1,9 +1,10 @@
-pdp_name = "pdp1"
+pdp_name = "pdp_mls"
policy_name = "MLS Policy example"
model_name = "MLS"
+policy_genre = "authz"
-subjects = {"user0": "", "user1": "", "user2": "", }
+subjects = {"adminuser": "", "user1": "", "user2": "", }
objects = {"vm0": "", "vm1": "", }
actions = {"start": "", "stop": ""}
@@ -20,7 +21,7 @@ object_data = {
action_data = {"action-type": {"vm-action": "", "storage-action": "", }}
subject_assignments = {
- "user0": {"subject-security-level": "high"},
+ "adminuser": {"subject-security-level": "high"},
"user1": {"subject-security-level": "medium"},
}
object_assignments = {
@@ -33,21 +34,25 @@ action_assignments = {
}
meta_rule = {
- "mls": {"id": "", "value": ("subject-security-level", "object-security-level", "action-type")},
+ "mls": {
+ "id": "",
+ "value": ("subject-security-level",
+ "object-security-level",
+ "action-type")},
}
rules = {
"mls": (
{
- "rules": ("high", "medium", "vm-action"),
+ "rule": ("high", "medium", "vm-action"),
"instructions": ({"decision": "grant"})
},
{
- "rules": ("high", "low", "vm-action"),
+ "rule": ("high", "low", "vm-action"),
"instructions": ({"decision": "grant"})
},
{
- "rules": ("medium", "low", "vm-action"),
+ "rule": ("medium", "low", "vm-action"),
"instructions": ({"decision": "grant"})
},
)
diff --git a/moonv4/moon_interface/tests/apitests/scenario/rbac.py b/moonv4/templates/moonforming/conf/rbac.py
index 89fd7de8..25c010fd 100644
--- a/moonv4/moon_interface/tests/apitests/scenario/rbac.py
+++ b/moonv4/templates/moonforming/conf/rbac.py
@@ -1,10 +1,10 @@
-pdp_name = "pdp1"
+pdp_name = "pdp_rbac"
policy_name = "RBAC policy example"
model_name = "RBAC"
policy_genre = "authz"
-subjects = {"user0": "", "user1": "", }
+subjects = {"adminuser": "", "user1": "", }
objects = {"vm0": "", "vm1": "", }
actions = {"start": "", "stop": ""}
@@ -16,9 +16,24 @@ subject_data = {"role": {"admin": "", "employee": "", "*": ""}}
object_data = {"id": {"vm0": "", "vm1": "", "*": ""}}
action_data = {"action-type": {"vm-action": "", "*": ""}}
-subject_assignments = {"user0": ({"role": "employee"}, {"role": "*"}), "user1": ({"role": "employee"}, {"role": "*"}), }
-object_assignments = {"vm0": ({"id": "vm0"}, {"id": "*"}), "vm1": ({"id": "vm1"}, {"id": "*"})}
-action_assignments = {"start": ({"action-type": "vm-action"}, {"action-type": "*"}), "stop": ({"action-type": "vm-action"}, {"action-type": "*"})}
+subject_assignments = {
+ "adminuser":
+ ({"role": "admin"}, {"role": "employee"}, {"role": "*"}),
+ "user1":
+ ({"role": "employee"}, {"role": "*"}),
+}
+object_assignments = {
+ "vm0":
+ ({"id": "vm0"}, {"id": "*"}),
+ "vm1":
+ ({"id": "vm1"}, {"id": "*"})
+}
+action_assignments = {
+ "start":
+ ({"action-type": "vm-action"}, {"action-type": "*"}),
+ "stop":
+ ({"action-type": "vm-action"}, {"action-type": "*"})
+}
meta_rule = {
"rbac": {"id": "", "value": ("role", "id", "action-type")},
@@ -29,7 +44,9 @@ rules = {
{
"rule": ("admin", "vm0", "vm-action"),
"instructions": (
- {"decision": "grant"}, # "grant" to immediately exit, "continue" to wait for the result of next policy
+ {"decision": "grant"},
+ # "grant" to immediately exit,
+ # "continue" to wait for the result of next policy
)
},
{
diff --git a/moonv4/templates/moonforming/conf2consul.py b/moonv4/templates/moonforming/conf2consul.py
new file mode 100644
index 00000000..46c99d5c
--- /dev/null
+++ b/moonv4/templates/moonforming/conf2consul.py
@@ -0,0 +1,103 @@
+import os
+import sys
+import requests
+import yaml
+import logging
+import json
+import base64
+
+logging.basicConfig(level=logging.INFO)
+log = logging.getLogger("moon.conf2consul")
+requests_log = logging.getLogger("requests.packages.urllib3")
+requests_log.setLevel(logging.WARNING)
+requests_log.propagate = True
+
+if len(sys.argv) == 2:
+ if os.path.isfile(sys.argv[1]):
+ CONF_FILENAME = sys.argv[1]
+ CONSUL_HOST = "consul"
+ else:
+ CONF_FILENAME = "moon.conf"
+ CONSUL_HOST = sys.argv[1]
+ CONSUL_PORT = 8500
+else:
+ CONSUL_HOST = sys.argv[1] if len(sys.argv) > 1 else "consul"
+ CONSUL_PORT = sys.argv[2] if len(sys.argv) > 2 else 8500
+ CONF_FILENAME = sys.argv[3] if len(sys.argv) > 3 else "moon.conf"
+HEADERS = {"content-type": "application/json"}
+
+
+def search_config_file():
+ data_config = None
+ for _file in (
+ CONF_FILENAME,
+ "conf/moon.conf",
+ "../moon.conf",
+ "../conf/moon.conf",
+ "/etc/moon/moon.conf",
+ ):
+ try:
+ data_config = yaml.safe_load(open(_file))
+ except FileNotFoundError:
+ data_config = None
+ continue
+ else:
+ break
+ if not data_config:
+ raise Exception("Configuration file not found...")
+ return data_config
+
+
+def put(key, value):
+ url = "http://{host}:{port}/v1/kv/{key}".format(host=CONSUL_HOST, port=CONSUL_PORT, key=key)
+ log.info(url)
+ req = requests.put(
+ url,
+ headers=HEADERS,
+ json=value
+ )
+ if req.status_code != 200:
+ raise Exception("Error connecting to Consul ({}, {})".format(req.status_code, req.text))
+
+
+def get(key):
+ url = "http://{host}:{port}/v1/kv/{key}".format(host=CONSUL_HOST, port=CONSUL_PORT, key=key)
+ req = requests.get(url)
+ data = req.json()
+ for item in data:
+ log.info("{} {} -> {}".format(
+ req.status_code,
+ item["Key"],
+ json.loads(base64.b64decode(item["Value"]).decode("utf-8"))
+ ))
+ yield json.loads(base64.b64decode(item["Value"]).decode("utf-8"))
+
+
+def main():
+ data_config = search_config_file()
+ req = requests.head("http://{}:{}/ui/".format(CONSUL_HOST, CONSUL_PORT))
+ if req.status_code != 200:
+ log.critical("Consul is down...")
+ log.critical("request info: {}/{}".format(req, req.text))
+ sys.exit(1)
+
+ put("database", data_config["database"])
+ # put("messenger", data_config["messenger"])
+ # put("slave", data_config["slave"])
+ # put("docker", data_config["docker"])
+ put("logging", data_config["logging"])
+ put("components_port_start", data_config["components"]["port_start"])
+
+ for _key, _value in data_config["components"].items():
+ if type(_value) is dict:
+ put("components/{}".format(_key), data_config["components"][_key])
+
+ for _key, _value in data_config["plugins"].items():
+ put("plugins/{}".format(_key), data_config["plugins"][_key])
+
+ for _key, _value in data_config["openstack"].items():
+ put("openstack/{}".format(_key), data_config["openstack"][_key])
+
+
+main()
+
diff --git a/moonv4/templates/moonforming/moon.conf b/moonv4/templates/moonforming/moon.conf
new file mode 100644
index 00000000..dc498e34
--- /dev/null
+++ b/moonv4/templates/moonforming/moon.conf
@@ -0,0 +1,79 @@
+database:
+ url: mysql+pymysql://moon:p4sswOrd1@db/moon
+ driver: sql
+
+openstack:
+ keystone:
+ url: http://keystone:5000/v3
+ user: admin
+ password: p4ssw0rd
+ domain: default
+ project: admin
+ check_token: false
+ certificate: false
+
+plugins:
+ authz:
+ container: wukongsun/moon_authz:v4.3
+ port: 8081
+ session:
+ container: asteroide/session:latest
+ port: 8082
+
+components:
+ interface:
+ port: 8080
+ bind: 0.0.0.0
+ hostname: interface
+ container: wukongsun/moon_interface:v4.3
+ orchestrator:
+ port: 8083
+ bind: 0.0.0.0
+ hostname: orchestrator
+ container: wukongsun/moon_orchestrator:v4.3
+ wrapper:
+ port: 8080
+ bind: 0.0.0.0
+ hostname: wrapper
+ container: wukongsun/moon_wrapper:v4.3.1
+ timeout: 5
+ manager:
+ port: 8082
+ bind: 0.0.0.0
+ hostname: manager
+ container: wukongsun/moon_manager:v4.3.1
+ port_start: 31001
+
+logging:
+ version: 1
+
+ formatters:
+ brief:
+ format: "%(levelname)s %(name)s %(message)-30s"
+ custom:
+ format: "%(asctime)-15s %(levelname)s %(name)s %(message)s"
+
+ handlers:
+ console:
+ class : logging.StreamHandler
+ formatter: brief
+ level : INFO
+ stream : ext://sys.stdout
+ file:
+ class : logging.handlers.RotatingFileHandler
+ formatter: custom
+ level : DEBUG
+ filename: /tmp/moon.log
+ maxBytes: 1048576
+ backupCount: 3
+
+ loggers:
+ moon:
+ level: DEBUG
+ handlers: [console, file]
+ propagate: no
+
+ root:
+ level: ERROR
+ handlers: [console]
+
diff --git a/moonv4/moon_interface/tests/apitests/populate_default_values.py b/moonv4/templates/moonforming/populate_default_values.py
index 740ad8ed..fa099458 100644
--- a/moonv4/moon_interface/tests/apitests/populate_default_values.py
+++ b/moonv4/templates/moonforming/populate_default_values.py
@@ -7,8 +7,11 @@ from utils.policies import *
parser = argparse.ArgumentParser()
parser.add_argument('filename', help='scenario filename', nargs=1)
-parser.add_argument("--verbose", "-v", action='store_true', help="verbose mode")
+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("--keystone-pid", "-k", dest="keystone_pid", default="",
+ help="Force a particular Keystone Project ID")
args = parser.parse_args()
FORMAT = '%(asctime)-15s %(levelname)s %(message)s'
@@ -29,7 +32,7 @@ requests_log = logging.getLogger("requests.packages.urllib3")
requests_log.setLevel(logging.WARNING)
requests_log.propagate = True
-logger = logging.getLogger(__name__)
+logger = logging.getLogger("moonforming")
if args.filename:
print("Loading: {}".format(args.filename[0]))
@@ -202,11 +205,12 @@ def create_policy(model_id, meta_rule_list):
def create_pdp(policy_id=None):
logger.info("Creating PDP {}".format(scenario.pdp_name))
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
+ project_id = args.keystone_pid
+ if not project_id:
+ for _project in projects['projects']:
+ if _project['name'] == "admin":
+ project_id = _project['id']
+ assert project_id
pdps = check_pdp()["pdps"]
for pdp_id, pdp_value in pdps.items():
if scenario.pdp_name == pdp_value["name"]:
@@ -214,7 +218,7 @@ def create_pdp(policy_id=None):
logger.debug("Found existing PDP named {} (will add policy {})".format(scenario.pdp_name, policy_id))
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=admin_project_id)
+ map_to_keystone(pdp_id=_pdp_id, keystone_project_id=project_id)
return _pdp_id
if __name__ == "__main__":
diff --git a/moonv4/templates/moonforming/run.sh b/moonv4/templates/moonforming/run.sh
new file mode 100644
index 00000000..71543f9e
--- /dev/null
+++ b/moonv4/templates/moonforming/run.sh
@@ -0,0 +1,44 @@
+#!/usr/bin/env bash
+
+populate_args=$*
+
+echo "Waiting for Consul (http://consul:8500)"
+while ! python -c "import requests; req = requests.get('http://consul:8500')" 2>/dev/null ; do
+ sleep 5 ;
+ echo "."
+done
+
+echo "Consul (http://consul:8500) is up."
+
+python3 /root/conf2consul.py /etc/moon/moon.conf
+
+echo "Waiting for DB (tcp://db:3306)"
+while ! python -c "import socket, sys; s = socket.socket(socket.AF_INET, socket.SOCK_STREAM); s.connect(('db', 3306)); sys.exit(0)" 2>/dev/null ; do
+ sleep 5 ;
+ echo "."
+done
+
+echo "Database (http://db:3306) is up."
+
+moon_db_manager upgrade
+
+echo "Waiting for Keystone (http://keystone:5000)"
+while ! python -c "import requests; req = requests.get('http://keystone:5000')" 2>/dev/null ; do
+ sleep 5 ;
+ echo "."
+done
+
+echo "Keystone (http://keystone:5000) is up."
+
+echo "Waiting for Manager (http://manager:8082)"
+while ! python -c "import requests; req = requests.get('http://manager:8082')" 2>/dev/null ; do
+ sleep 5 ;
+ echo "."
+done
+
+echo "Manager (http://manager:8082) is up."
+
+cd /root
+
+python3 populate_default_values.py $populate_args /root/conf/rbac.py
+python3 populate_default_values.py $populate_args /root/conf/mls.py
diff --git a/moonv4/templates/moonforming/utils/__init__.py b/moonv4/templates/moonforming/utils/__init__.py
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/moonv4/templates/moonforming/utils/__init__.py
diff --git a/moonv4/templates/moonforming/utils/config.py b/moonv4/templates/moonforming/utils/config.py
new file mode 100644
index 00000000..30c8ea4f
--- /dev/null
+++ b/moonv4/templates/moonforming/utils/config.py
@@ -0,0 +1,22 @@
+import yaml
+
+
+def get_config_data(filename="moon.conf"):
+ data_config = None
+ for _file in (
+ filename,
+ "conf/moon.conf",
+ "../moon.conf",
+ "../conf/moon.conf",
+ "/etc/moon/moon.conf",
+ ):
+ try:
+ data_config = yaml.safe_load(open(_file))
+ except FileNotFoundError:
+ data_config = None
+ continue
+ else:
+ break
+ if not data_config:
+ raise Exception("Configuration file not found...")
+ return data_config
diff --git a/moonv4/moon_interface/tests/apitests/utils/models.py b/moonv4/templates/moonforming/utils/models.py
index 68133b5b..3cf31354 100644
--- a/moonv4/moon_interface/tests/apitests/utils/models.py
+++ b/moonv4/templates/moonforming/utils/models.py
@@ -1,27 +1,12 @@
-import os
-import yaml
import requests
import copy
+import utils.config
+config = utils.config.get_config_data()
-for path in (
- "moon.conf",
- "../moon.conf",
- "{}/moon_orchestrator/conf/moon.conf".format(os.getenv("MOON_HOME")),
- "/etc/moon/moon.conf"
-):
- try:
- config = yaml.safe_load(open(path))
- except FileNotFoundError:
- config = None
- continue
- else:
- print("Using {}".format(path))
- break
-if not config:
- raise Exception("Configuration file not found...")
-
-URL = "http://{}:{}".format(config['components']['interface']['hostname'], config['components']['interface']['port'])
+URL = "http://{}:{}".format(
+ config['components']['manager']['hostname'],
+ config['components']['manager']['port'])
URL = URL + "{}"
HEADERS = {"content-type": "application/json"}
diff --git a/moonv4/moon_interface/tests/apitests/utils/pdp.py b/moonv4/templates/moonforming/utils/pdp.py
index c0c83441..f3c6df37 100644
--- a/moonv4/moon_interface/tests/apitests/utils/pdp.py
+++ b/moonv4/templates/moonforming/utils/pdp.py
@@ -1,25 +1,13 @@
-import os
-import yaml
+import logging
import requests
+import utils.config
-for path in (
- "moon.conf",
- "../moon.conf",
- "{}/moon_orchestrator/conf/moon.conf".format(os.getenv("MOON_HOME")),
- "/etc/moon/moon.conf"
-):
- try:
- config = yaml.safe_load(open(path))
- except FileNotFoundError:
- config = None
- continue
- else:
- print("Using {}".format(path))
- break
-if not config:
- raise Exception("Configuration file not found...")
-
-URL = "http://{}:{}".format(config['components']['interface']['hostname'], config['components']['interface']['port'])
+config = utils.config.get_config_data()
+logger = logging.getLogger("moonforming.utils.policies")
+
+URL = "http://{}:{}".format(
+ config['components']['manager']['hostname'],
+ config['components']['manager']['port'])
HEADERS = {"content-type": "application/json"}
KEYSTONE_USER = config['openstack']['keystone']['user']
KEYSTONE_PASSWORD = config['openstack']['keystone']['password']
@@ -29,7 +17,7 @@ KEYSTONE_SERVER = config['openstack']['keystone']['url']
pdp_template = {
"name": "test_pdp",
"security_pipeline": [],
- "keystone_project_id": "",
+ "keystone_project_id": None,
"description": "test",
}
@@ -60,6 +48,8 @@ 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)
TOKEN = req.headers['X-Subject-Token']
HEADERS['X-Auth-Token'] = TOKEN
@@ -109,6 +99,8 @@ def add_pdp(name="test_pdp", policy_id=None):
if policy_id:
pdp_template['security_pipeline'].append(policy_id)
req = requests.post(URL + "/pdp", json=pdp_template, headers=HEADERS)
+ logger.debug(req.status_code)
+ logger.debug(req)
assert req.status_code == 200
result = req.json()
assert type(result) is dict
diff --git a/moonv4/moon_interface/tests/apitests/utils/policies.py b/moonv4/templates/moonforming/utils/policies.py
index fdde92ef..bd08291a 100644
--- a/moonv4/moon_interface/tests/apitests/utils/policies.py
+++ b/moonv4/templates/moonforming/utils/policies.py
@@ -1,25 +1,11 @@
-import os
-import yaml
+import logging
import requests
+import utils.config
-for path in (
- "moon.conf",
- "../moon.conf",
- "{}/moon_orchestrator/conf/moon.conf".format(os.getenv("MOON_HOME")),
- "/etc/moon/moon.conf"
-):
- try:
- config = yaml.safe_load(open(path))
- except FileNotFoundError:
- config = None
- continue
- else:
- print("Using {}".format(path))
- break
-if not config:
- raise Exception("Configuration file not found...")
+config = utils.config.get_config_data()
+logger = logging.getLogger("moonforming.utils.policies")
-URL = "http://{}:{}".format(config['components']['interface']['hostname'], config['components']['interface']['port'])
+URL = "http://{}:{}".format(config['components']['manager']['hostname'], config['components']['manager']['port'])
URL = URL + "{}"
HEADERS = {"content-type": "application/json"}
FILE = open("/tmp/test.log", "w")
@@ -124,10 +110,13 @@ def delete_policy(policy_id):
def add_subject(policy_id=None, name="test_subject"):
subject_template['name'] = name
if policy_id:
+ logger.debug(URL.format("/policies/{}/subjects".format(policy_id)))
req = requests.post(URL.format("/policies/{}/subjects".format(policy_id)),
json=subject_template, headers=HEADERS)
else:
+ 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
result = req.json()
assert "subjects" in result
diff --git a/moonv4/templates/nova/policy.json b/moonv4/templates/nova/policy.json
new file mode 100644
index 00000000..29763ce3
--- /dev/null
+++ b/moonv4/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": "rule:admin_or_owner",
+
+ "cells_scheduler_filter:TargetCellFilter": "is_admin:True",
+
+ "compute:create": "http://my_hostname:31001/authz",
+ "compute:create:attach_network": "",
+ "compute:create:attach_volume": "",
+ "compute:create:forced_host": "is_admin:True",
+
+ "compute:get": "http://my_hostname:31001/authz",
+ "compute:get_all": "http://my_hostname:31001/authz",
+ "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:delete": "",
+ "compute:soft_delete": "",
+ "compute:force_delete": "",
+ "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": "http://my_hostname:31001/authz",
+ "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": "http://my_hostname:31001/authz",
+ "os_compute_api:servers:update": "http://my_hostname:31001/authz",
+ "os_compute_api:servers:detail": "http://my_hostname:31001/authz",
+ "os_compute_api:servers:index": "http://my_hostname:31001/authz",
+ "os_compute_api:servers:reboot": "http://my_hostname:31001/authz",
+ "os_compute_api:servers:rebuild": "http://my_hostname:31001/authz",
+ "os_compute_api:servers:resize": "http://my_hostname:31001/authz",
+ "os_compute_api:servers:revert_resize": "http://my_hostname:31001/authz",
+ "os_compute_api:servers:show": "http://my_hostname:31001/authz",
+ "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"
+}
diff --git a/moonv4/templates/python_unit_test/Dockerfile b/moonv4/templates/python_unit_test/Dockerfile
new file mode 100644
index 00000000..b8fb5151
--- /dev/null
+++ b/moonv4/templates/python_unit_test/Dockerfile
@@ -0,0 +1,8 @@
+FROM python:3
+
+RUN pip install pytest requests_mock requests --upgrade
+ADD requirements.txt /root
+RUN pip install -r /root/requirements.txt --upgrade
+
+ADD run_tests.sh /root
+CMD ["sh", "/root/run_tests.sh"] \ No newline at end of file
diff --git a/moonv4/templates/python_unit_test/README.md b/moonv4/templates/python_unit_test/README.md
new file mode 100644
index 00000000..45d3a988
--- /dev/null
+++ b/moonv4/templates/python_unit_test/README.md
@@ -0,0 +1,8 @@
+# Python Unit Test Docker
+
+## Build
+- `docker image build -t wukongsun/moon_python_unit_test .`
+
+## Push to DockerHub
+- `docker login --username=wukongsun`
+- `docker image push wukongsun/moon_python_unit_test` \ No newline at end of file
diff --git a/moonv4/moon_router/requirements.txt b/moonv4/templates/python_unit_test/requirements.txt
index 9eb4e201..b611b008 100644
--- a/moonv4/moon_router/requirements.txt
+++ b/moonv4/templates/python_unit_test/requirements.txt
@@ -1,7 +1,10 @@
kombu !=4.0.1,!=4.0.0
oslo.messaging
oslo.config
-vine
oslo.log
-babel
-moon_utilities \ No newline at end of file
+vine
+werkzeug
+flask
+requests
+pytest
+requests_mock \ No newline at end of file
diff --git a/moonv4/templates/python_unit_test/run_tests.sh b/moonv4/templates/python_unit_test/run_tests.sh
new file mode 100644
index 00000000..6c586f87
--- /dev/null
+++ b/moonv4/templates/python_unit_test/run_tests.sh
@@ -0,0 +1,13 @@
+#!/usr/bin/env bash
+
+cd /data
+pip3 install -r tests/unit_python/requirements.txt --upgrade
+pip3 install .
+
+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 .
diff --git a/moonv4/tests/get_keystone_projects.py b/moonv4/tests/get_keystone_projects.py
new file mode 100644
index 00000000..7b37b0e7
--- /dev/null
+++ b/moonv4/tests/get_keystone_projects.py
@@ -0,0 +1,19 @@
+from utils import pdp
+from utils import parse
+from utils import models
+from utils import policies
+from utils import pdp
+
+if __name__ == "__main__":
+ 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']))
diff --git a/moonv4/tests/populate_default_values.py b/moonv4/tests/populate_default_values.py
index 740ad8ed..28795526 100644
--- a/moonv4/tests/populate_default_values.py
+++ b/moonv4/tests/populate_default_values.py
@@ -1,42 +1,11 @@
-import argparse
import logging
from importlib.machinery import SourceFileLoader
-from utils.pdp import *
-from utils.models import *
-from utils.policies import *
+from utils import parse
+from utils import models
+from utils import policies
+from utils import pdp
-parser = argparse.ArgumentParser()
-parser.add_argument('filename', help='scenario filename', nargs=1)
-parser.add_argument("--verbose", "-v", action='store_true', help="verbose mode")
-parser.add_argument("--debug", "-d", action='store_true', help="debug mode")
-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)
-
-requests_log = logging.getLogger("requests.packages.urllib3")
-requests_log.setLevel(logging.WARNING)
-requests_log.propagate = True
-
-logger = logging.getLogger(__name__)
-
-if args.filename:
- print("Loading: {}".format(args.filename[0]))
-
-m = SourceFileLoader("scenario", args.filename[0])
-
-scenario = m.load_module()
+logger = None
def create_model(model_id=None):
@@ -44,16 +13,16 @@ def create_model(model_id=None):
logger.info("Creating model {}".format(scenario.model_name))
if not model_id:
logger.info("Add model")
- model_id = add_model(name=scenario.model_name)
+ model_id = models.add_model(name=scenario.model_name)
logger.info("Add subject categories")
for cat in scenario.subject_categories:
- scenario.subject_categories[cat] = add_subject_category(name=cat)
+ scenario.subject_categories[cat] = models.add_subject_category(name=cat)
logger.info("Add object categories")
for cat in scenario.object_categories:
- scenario.object_categories[cat] = add_object_category(name=cat)
+ scenario.object_categories[cat] = models.add_object_category(name=cat)
logger.info("Add action categories")
for cat in scenario.action_categories:
- scenario.action_categories[cat] = add_action_category(name=cat)
+ scenario.action_categories[cat] = models.add_action_category(name=cat)
sub_cat = []
ob_cat = []
act_cat = []
@@ -66,14 +35,14 @@ def create_model(model_id=None):
ob_cat.append(scenario.object_categories[item])
elif item in scenario.action_categories:
act_cat.append(scenario.action_categories[item])
- meta_rules = check_meta_rule(meta_rule_id=None)
+ meta_rules = models.check_meta_rule(meta_rule_id=None)
for _meta_rule_id, _meta_rule_value in meta_rules['meta_rules'].items():
if _meta_rule_value['name'] == item_name:
meta_rule_id = _meta_rule_id
break
else:
logger.info("Add meta rule")
- meta_rule_id = add_meta_rule(item_name, sub_cat, ob_cat, act_cat)
+ meta_rule_id = models.add_meta_rule(item_name, sub_cat, ob_cat, act_cat)
item_value["id"] = meta_rule_id
if meta_rule_id not in meta_rule_list:
meta_rule_list.append(meta_rule_id)
@@ -83,51 +52,51 @@ def create_model(model_id=None):
def create_policy(model_id, meta_rule_list):
if args.verbose:
logger.info("Creating policy {}".format(scenario.policy_name))
- _policies = check_policy()
+ _policies = policies.check_policy()
for _policy_id, _policy_value in _policies["policies"].items():
if _policy_value['name'] == scenario.policy_name:
policy_id = _policy_id
break
else:
- policy_id = add_policy(name=scenario.policy_name, genre=scenario.policy_genre)
+ policy_id = policies.add_policy(name=scenario.policy_name, genre=scenario.policy_genre)
- update_policy(policy_id, model_id)
+ policies.update_policy(policy_id, model_id)
for meta_rule_id in meta_rule_list:
logger.debug("add_meta_rule_to_model {} {}".format(model_id, meta_rule_id))
- add_meta_rule_to_model(model_id, meta_rule_id)
+ models.add_meta_rule_to_model(model_id, meta_rule_id)
logger.info("Add subject data")
for subject_cat_name in scenario.subject_data:
for subject_data_name in scenario.subject_data[subject_cat_name]:
- data_id = scenario.subject_data[subject_cat_name][subject_data_name] = add_subject_data(
+ data_id = scenario.subject_data[subject_cat_name][subject_data_name] = policies.add_subject_data(
policy_id=policy_id,
category_id=scenario.subject_categories[subject_cat_name], name=subject_data_name)
scenario.subject_data[subject_cat_name][subject_data_name] = data_id
logger.info("Add object data")
for object_cat_name in scenario.object_data:
for object_data_name in scenario.object_data[object_cat_name]:
- data_id = scenario.object_data[object_cat_name][object_data_name] = add_object_data(
+ data_id = scenario.object_data[object_cat_name][object_data_name] = policies.add_object_data(
policy_id=policy_id,
category_id=scenario.object_categories[object_cat_name], name=object_data_name)
scenario.object_data[object_cat_name][object_data_name] = data_id
logger.info("Add action data")
for action_cat_name in scenario.action_data:
for action_data_name in scenario.action_data[action_cat_name]:
- data_id = scenario.action_data[action_cat_name][action_data_name] = add_action_data(
+ data_id = scenario.action_data[action_cat_name][action_data_name] = policies.add_action_data(
policy_id=policy_id,
category_id=scenario.action_categories[action_cat_name], name=action_data_name)
scenario.action_data[action_cat_name][action_data_name] = data_id
logger.info("Add subjects")
for name in scenario.subjects:
- scenario.subjects[name] = add_subject(policy_id, name=name)
+ scenario.subjects[name] = policies.add_subject(policy_id, name=name)
logger.info("Add objects")
for name in scenario.objects:
- scenario.objects[name] = add_object(policy_id, name=name)
+ scenario.objects[name] = policies.add_object(policy_id, name=name)
logger.info("Add actions")
for name in scenario.actions:
- scenario.actions[name] = add_action(policy_id, name=name)
+ scenario.actions[name] = policies.add_action(policy_id, name=name)
logger.info("Add subject assignments")
for subject_name in scenario.subject_assignments:
@@ -138,14 +107,14 @@ def create_policy(model_id, meta_rule_list):
subject_cat_id = scenario.subject_categories[subject_category_name]
for data in scenario.subject_assignments[subject_name]:
subject_data_id = scenario.subject_data[subject_category_name][data[subject_category_name]]
- add_subject_assignments(policy_id, subject_id, subject_cat_id, subject_data_id)
+ policies.add_subject_assignments(policy_id, subject_id, subject_cat_id, subject_data_id)
else:
for subject_category_name in scenario.subject_assignments[subject_name]:
subject_id = scenario.subjects[subject_name]
subject_cat_id = scenario.subject_categories[subject_category_name]
subject_data_id = scenario.subject_data[subject_category_name][scenario.subject_assignments[subject_name][subject_category_name]]
- add_subject_assignments(policy_id, subject_id, subject_cat_id, subject_data_id)
-
+ policies.add_subject_assignments(policy_id, subject_id, subject_cat_id, subject_data_id)
+
logger.info("Add object assignments")
for object_name in scenario.object_assignments:
if type(scenario.object_assignments[object_name]) in (list, tuple):
@@ -155,13 +124,13 @@ def create_policy(model_id, meta_rule_list):
object_cat_id = scenario.object_categories[object_category_name]
for data in scenario.object_assignments[object_name]:
object_data_id = scenario.object_data[object_category_name][data[object_category_name]]
- add_object_assignments(policy_id, object_id, object_cat_id, object_data_id)
+ policies.add_object_assignments(policy_id, object_id, object_cat_id, object_data_id)
else:
for object_category_name in scenario.object_assignments[object_name]:
object_id = scenario.objects[object_name]
object_cat_id = scenario.object_categories[object_category_name]
object_data_id = scenario.object_data[object_category_name][scenario.object_assignments[object_name][object_category_name]]
- add_object_assignments(policy_id, object_id, object_cat_id, object_data_id)
+ policies.add_object_assignments(policy_id, object_id, object_cat_id, object_data_id)
logger.info("Add action assignments")
for action_name in scenario.action_assignments:
@@ -172,13 +141,13 @@ def create_policy(model_id, meta_rule_list):
action_cat_id = scenario.action_categories[action_category_name]
for data in scenario.action_assignments[action_name]:
action_data_id = scenario.action_data[action_category_name][data[action_category_name]]
- add_action_assignments(policy_id, action_id, action_cat_id, action_data_id)
+ policies.add_action_assignments(policy_id, action_id, action_cat_id, action_data_id)
else:
for action_category_name in scenario.action_assignments[action_name]:
action_id = scenario.actions[action_name]
action_cat_id = scenario.action_categories[action_category_name]
action_data_id = scenario.action_data[action_category_name][scenario.action_assignments[action_name][action_category_name]]
- add_action_assignments(policy_id, action_id, action_cat_id, action_data_id)
+ policies.add_action_assignments(policy_id, action_id, action_cat_id, action_data_id)
logger.info("Add rules")
for meta_rule_name in scenario.rules:
@@ -195,30 +164,50 @@ def create_policy(model_id, meta_rule_list):
elif category_name in scenario.action_categories:
data_list.append(scenario.action_data[category_name][data_name])
instructions = rule["instructions"]
- add_rule(policy_id, meta_rule_value["id"], data_list, instructions)
+ policies.add_rule(policy_id, meta_rule_value["id"], data_list, instructions)
return policy_id
-def create_pdp(policy_id=None):
+def create_pdp(policy_id=None, project_id=None):
logger.info("Creating PDP {}".format(scenario.pdp_name))
- 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
- pdps = check_pdp()["pdps"]
+ projects = pdp.get_keystone_projects()
+ if not project_id:
+ for _project in projects['projects']:
+ if _project['name'] == "admin":
+ project_id = _project['id']
+ assert project_id
+ pdps = pdp.check_pdp()["pdps"]
for pdp_id, pdp_value in pdps.items():
if scenario.pdp_name == pdp_value["name"]:
- update_pdp(pdp_id, policy_id=policy_id)
+ pdp.update_pdp(pdp_id, policy_id=policy_id)
logger.debug("Found existing PDP named {} (will add policy {})".format(scenario.pdp_name, policy_id))
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=admin_project_id)
+ _pdp_id = pdp.add_pdp(name=scenario.pdp_name, policy_id=policy_id)
+ pdp.map_to_keystone(pdp_id=_pdp_id, keystone_project_id=project_id)
return _pdp_id
+
if __name__ == "__main__":
- _models = check_model()
+ logger = logging.getLogger("moonforming")
+ 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:
+ print("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
@@ -228,4 +217,4 @@ if __name__ == "__main__":
else:
model_id, meta_rule_list = create_model()
policy_id = create_policy(model_id, meta_rule_list)
- pdp_id = create_pdp(policy_id)
+ pdp_id = create_pdp(policy_id=policy_id, project_id=project_id)
diff --git a/moonv4/tests/send_authz.py b/moonv4/tests/send_authz.py
new file mode 100644
index 00000000..5766a0ec
--- /dev/null
+++ b/moonv4/tests/send_authz.py
@@ -0,0 +1,243 @@
+import sys
+import copy
+import logging
+import threading
+from importlib.machinery import SourceFileLoader
+import requests
+import time
+import json
+import random
+from uuid import uuid4
+from utils.pdp import check_pdp
+from utils.parse import parse
+import utils.config
+
+
+logger = None
+HOST_MANAGER = None
+PORT_MANAGER = None
+HOST_AUTHZ = None
+PORT_AUTHZ = None
+HOST_KEYSTONE = None
+PORT_KEYSTONE = None
+
+lock = threading.Lock()
+logger = logging.getLogger(__name__)
+
+
+def get_scenario(args):
+ m = SourceFileLoader("scenario", args.filename[0])
+ return m.load_module()
+
+
+def get_keystone_id(pdp_name):
+ global HOST_MANAGER, PORT_MANAGER
+ keystone_project_id = None
+ for pdp_key, pdp_value in check_pdp(moon_url="http://{}:{}".format(HOST_MANAGER, PORT_MANAGER))["pdps"].items():
+ if pdp_name:
+ if pdp_name != pdp_value["name"]:
+ continue
+ if pdp_value['security_pipeline'] and pdp_value["keystone_project_id"]:
+ logger.debug("Found pdp with keystone_project_id={}".format(pdp_value["keystone_project_id"]))
+ keystone_project_id = pdp_value["keystone_project_id"]
+
+ if not keystone_project_id:
+ logger.error("Cannot find PDP with keystone project ID")
+ sys.exit(1)
+ return keystone_project_id
+
+
+def _construct_payload(creds, current_rule, enforcer, target):
+ # Convert instances of object() in target temporarily to
+ # empty dict to avoid circular reference detection
+ # errors in jsonutils.dumps().
+ temp_target = copy.deepcopy(target)
+ for key in target.keys():
+ element = target.get(key)
+ if type(element) is object:
+ temp_target[key] = {}
+ _data = _json = None
+ if enforcer:
+ _data = {'rule': json.dumps(current_rule),
+ 'target': json.dumps(temp_target),
+ 'credentials': json.dumps(creds)}
+ else:
+ _json = {'rule': current_rule,
+ 'target': temp_target,
+ 'credentials': creds}
+ return _data, _json
+
+
+def _send(url, data=None, stress_test=False):
+ current_request = dict()
+ current_request['url'] = url
+ try:
+ if stress_test:
+ current_request['start'] = time.time()
+ # with lock:
+ res = requests.get(url)
+ current_request['end'] = time.time()
+ current_request['delta'] = current_request["end"] - current_request["start"]
+ else:
+ with lock:
+ current_request['start'] = time.time()
+ if data:
+ data, _ = _construct_payload(data['credentials'], data['rule'], True, data['target'])
+ res = requests.post(url, json=data,
+ headers={'content-type': "application/x-www-form-urlencode"}
+ )
+ else:
+ res = requests.get(url)
+ current_request['end'] = time.time()
+ current_request['delta'] = current_request["end"] - current_request["start"]
+ except requests.exceptions.ConnectionError:
+ logger.warning("Unable to connect to server")
+ return {}
+ if not stress_test:
+ try:
+ j = res.json()
+ if res.status_code == 200:
+ logger.warning("\033[1m{}\033[m \033[32mGrant\033[m".format(url))
+ elif res.status_code == 401:
+ logger.warning("\033[1m{}\033[m \033[31mDeny\033[m".format(url))
+ else:
+ logger.error("\033[1m{}\033[m {} {}".format(url, res.status_code, res.text))
+ except Exception as e:
+ if res.text == "True":
+ logger.warning("\033[1m{}\033[m \033[32mGrant\033[m".format(url))
+ elif res.text == "False":
+ logger.warning("\033[1m{}\033[m \033[31mDeny\033[m".format(url))
+ else:
+ logger.error("\033[1m{}\033[m {} {}".format(url, res.status_code, res.text))
+ logger.exception(e)
+ logger.error(res.text)
+ else:
+ if j.get("result"):
+ # logger.warning("{} \033[32m{}\033[m".format(url, j.get("result")))
+ logger.debug("{}".format(j.get("error", "")))
+ current_request['result'] = "Grant"
+ else:
+ # logger.warning("{} \033[31m{}\033[m".format(url, "Deny"))
+ logger.debug("{}".format(j))
+ current_request['result'] = "Deny"
+ return current_request
+
+
+class AsyncGet(threading.Thread):
+
+ def __init__(self, url, semaphore=None, **kwargs):
+ threading.Thread.__init__(self)
+ self.url = url
+ self.kwargs = kwargs
+ self.sema = semaphore
+ self.result = dict()
+ self.uuid = uuid4().hex
+ self.index = kwargs.get("index", 0)
+
+ def run(self):
+ self.result = _send(self.url,
+ data=self.kwargs.get("data"),
+ stress_test=self.kwargs.get("stress_test", False))
+ self.result['index'] = self.index
+
+
+def send_requests(scenario, keystone_project_id, request_second=1, limit=500,
+ dry_run=None, stress_test=False, destination="wrapper"):
+ global HOST_AUTHZ, PORT_AUTHZ
+ backgrounds = []
+ time_data = list()
+ start_timing = time.time()
+ request_cpt = 0
+ SUBJECTS = tuple(scenario.subjects.keys())
+ OBJECTS = tuple(scenario.objects.keys())
+ ACTIONS = tuple(scenario.actions.keys())
+ while request_cpt < limit:
+ rule = (random.choice(SUBJECTS), random.choice(OBJECTS), random.choice(ACTIONS))
+ if destination.lower() == "wrapper":
+ url = "http://{}:{}/authz".format(HOST_AUTHZ, PORT_AUTHZ)
+ data = {
+ 'target': {
+ "user_id": random.choice(SUBJECTS),
+ "target": {
+ "name": random.choice(OBJECTS)
+ },
+ "project_id": keystone_project_id
+ },
+ 'credentials': None,
+ 'rule': random.choice(ACTIONS)
+ }
+ else:
+ url = "http://{}:{}/authz/{}/{}".format(HOST_AUTHZ, PORT_AUTHZ, keystone_project_id, "/".join(rule))
+ data = None
+ if dry_run:
+ logger.info(url)
+ continue
+ request_cpt += 1
+ if stress_test:
+ time_data.append(copy.deepcopy(_send(url, stress_test=stress_test)))
+ else:
+ background = AsyncGet(url, stress_test=stress_test, data=data,
+ index=request_cpt)
+ backgrounds.append(background)
+ background.start()
+ if request_second > 0:
+ if request_cpt % request_second == 0:
+ if time.time()-start_timing < 1:
+ while True:
+ if time.time()-start_timing > 1:
+ break
+ start_timing = time.time()
+ if not stress_test:
+ for background in backgrounds:
+ background.join()
+ if background.result:
+ time_data.append(copy.deepcopy(background.result))
+ return time_data
+
+
+def save_data(filename, time_data):
+ json.dump(time_data, open(filename, "w"))
+
+
+def get_delta(time_data):
+ time_delta = list()
+ time_delta_sum1 = 0
+ for item in time_data:
+ time_delta.append(item['delta'])
+ time_delta_sum1 += item['delta']
+ time_delta_average1 = time_delta_sum1 / len(time_data)
+ return time_delta, time_delta_average1
+
+
+def main():
+ global HOST_MANAGER, PORT_MANAGER, HOST_AUTHZ, PORT_AUTHZ
+
+ args = parse()
+ consul_host = args.consul_host
+ consul_port = args.consul_port
+ conf_data = utils.config.get_config_data(consul_host, consul_port)
+
+ HOST_MANAGER = conf_data['manager_host']
+ PORT_MANAGER = conf_data['manager_port']
+ HOST_AUTHZ = args.authz_host
+ PORT_AUTHZ = args.authz_port
+ # HOST_KEYSTONE = conf_data['keystone_host']
+ # PORT_KEYSTONE = conf_data['manager_host']
+
+ scenario = get_scenario(args)
+ keystone_project_id = get_keystone_id(args.pdp)
+ time_data = send_requests(
+ scenario,
+ 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:
+ save_data(args.write, time_data)
+
+
+if __name__ == "__main__":
+ main()
diff --git a/moonv4/tests/utils/config.py b/moonv4/tests/utils/config.py
index 30c8ea4f..d6317820 100644
--- a/moonv4/tests/utils/config.py
+++ b/moonv4/tests/utils/config.py
@@ -1,22 +1,44 @@
-import yaml
+import base64
+import json
+import requests
-def get_config_data(filename="moon.conf"):
- data_config = None
- for _file in (
- filename,
- "conf/moon.conf",
- "../moon.conf",
- "../conf/moon.conf",
- "/etc/moon/moon.conf",
- ):
- try:
- data_config = yaml.safe_load(open(_file))
- except FileNotFoundError:
- data_config = None
- continue
- else:
- break
- if not data_config:
- raise Exception("Configuration file not found...")
- return data_config
+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")
+ data = req.json()
+ if len(data) == 1:
+ data = data[0]
+ return {data["Key"]: json.loads(base64.b64decode(data["Value"]).decode("utf-8"))}
+ else:
+ return [
+ {item["Key"]: json.loads(base64.b64decode(item["Value"]).decode("utf-8"))}
+ for item in data
+ ]
+
+
+def get_config_data(consul_host, consul_port):
+ conf_data = dict()
+ conf_data['manager_host'] = get_configuration(consul_host, consul_port,
+ 'components/manager')['components/manager']['external']['hostname']
+ conf_data['manager_port'] = get_configuration(consul_host, consul_port,
+ 'components/manager')['components/manager']['external']['port']
+ # conf_data['authz_host'] = get_configuration(consul_host, consul_port,
+ # 'components/interface')['components/interface']['external']['hostname']
+ # conf_data['authz_port'] = get_configuration(consul_host, consul_port,
+ # 'components/interface')['components/interface']['external']['port']
+ conf_data['keystone_host'] = get_configuration(consul_host, consul_port,
+ 'openstack/keystone')['openstack/keystone']['external']['url']
+ # conf_data['keystone_port'] = '5000'
+ conf_data['keystone_user'] = get_configuration(consul_host, consul_port,
+ 'openstack/keystone')['openstack/keystone']['user']
+ conf_data['keystone_password'] = get_configuration(consul_host, consul_port,
+ 'openstack/keystone')['openstack/keystone']['password']
+ conf_data['keystone_project'] = get_configuration(consul_host, consul_port,
+ 'openstack/keystone')['openstack/keystone']['project']
+ return conf_data
+
+# get_conf_data('88.88.88.2', '30005')
+# get_conf_data('127.0.0.1', 8082)
diff --git a/moonv4/tests/utils/models.py b/moonv4/tests/utils/models.py
index 3cf31354..61fa6179 100644
--- a/moonv4/tests/utils/models.py
+++ b/moonv4/tests/utils/models.py
@@ -2,13 +2,8 @@ import requests
import copy
import utils.config
-config = utils.config.get_config_data()
-
-URL = "http://{}:{}".format(
- config['components']['manager']['hostname'],
- config['components']['manager']['port'])
-URL = URL + "{}"
-HEADERS = {"content-type": "application/json"}
+URL = None
+HEADERS = None
model_template = {
"name": "test_model",
@@ -29,6 +24,16 @@ meta_rule_template = {
}
+def init(consul_host, consul_port):
+ conf_data = utils.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 check_model(model_id=None, check_model_name=True):
req = requests.get(URL.format("/models"))
assert req.status_code == 200
diff --git a/moonv4/tests/utils/parse.py b/moonv4/tests/utils/parse.py
new file mode 100644
index 00000000..34a4a996
--- /dev/null
+++ b/moonv4/tests/utils/parse.py
@@ -0,0 +1,83 @@
+import logging
+import argparse
+
+
+logger = None
+
+
+def parse():
+ global logger
+ logger = logging.getLogger(__name__)
+ 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=1)
+ 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: 8082).",
+ default="8082")
+ 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/moonv4/tests/utils/pdp.py b/moonv4/tests/utils/pdp.py
index 4f513aa6..50998507 100644
--- a/moonv4/tests/utils/pdp.py
+++ b/moonv4/tests/utils/pdp.py
@@ -1,27 +1,42 @@
+import logging
import requests
import utils.config
-config = utils.config.get_config_data()
+logger = logging.getLogger("moonforming.utils.policies")
+URL = None
+HEADER = None
+KEYSTONE_USER = None
+KEYSTONE_PASSWORD = None
+KEYSTONE_PROJECT = None
+KEYSTONE_SERVER = None
+
+# config = utils.config.get_config_data()
-URL = "http://{}:{}".format(
- config['components']['manager']['hostname'],
- config['components']['manager']['port'])
-HEADERS = {"content-type": "application/json"}
-KEYSTONE_USER = config['openstack']['keystone']['user']
-KEYSTONE_PASSWORD = config['openstack']['keystone']['password']
-KEYSTONE_PROJECT = config['openstack']['keystone']['project']
-KEYSTONE_SERVER = config['openstack']['keystone']['url']
pdp_template = {
"name": "test_pdp",
"security_pipeline": [],
- "keystone_project_id": "",
+ "keystone_project_id": None,
"description": "test",
}
-def get_keystone_projects():
+def init(consul_host, consul_port):
+ conf_data = utils.config.get_config_data(consul_host, consul_port)
+ global URL, HEADER, KEYSTONE_USER, KEYSTONE_PASSWORD, KEYSTONE_PROJECT, KEYSTONE_SERVER
+ URL = "http://{}:{}".format(
+ conf_data['manager_host'],
+ conf_data['manager_port'])
+ # URL = URL + "{}"
+ HEADER = {"content-type": "application/json"}
+ KEYSTONE_USER = conf_data['keystone_user']
+ KEYSTONE_PASSWORD = conf_data['keystone_password']
+ KEYSTONE_PROJECT = conf_data['keystone_project']
+ KEYSTONE_SERVER = conf_data['keystone_host']
+
+def get_keystone_projects():
+ global HEADERS
HEADERS = {
"Content-Type": "application/json"
}
@@ -46,6 +61,8 @@ 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)
TOKEN = req.headers['X-Subject-Token']
HEADERS['X-Auth-Token'] = TOKEN
@@ -95,6 +112,8 @@ def add_pdp(name="test_pdp", policy_id=None):
if policy_id:
pdp_template['security_pipeline'].append(policy_id)
req = requests.post(URL + "/pdp", json=pdp_template, headers=HEADERS)
+ logger.debug(req.status_code)
+ logger.debug(req)
assert req.status_code == 200
result = req.json()
assert type(result) is dict
@@ -154,4 +173,3 @@ def delete_pdp(pdp_id):
assert type(result) is dict
assert "result" in result
assert result["result"]
-
diff --git a/moonv4/tests/utils/policies.py b/moonv4/tests/utils/policies.py
index 2180317e..fd4d238f 100644
--- a/moonv4/tests/utils/policies.py
+++ b/moonv4/tests/utils/policies.py
@@ -1,12 +1,11 @@
+import logging
import requests
import utils.config
-config = utils.config.get_config_data()
-
-URL = "http://{}:{}".format(config['components']['manager']['hostname'], config['components']['manager']['port'])
-URL = URL + "{}"
-HEADERS = {"content-type": "application/json"}
+URL = None
+HEADERS = None
FILE = open("/tmp/test.log", "w")
+logger = logging.getLogger("utils.policies")
policy_template = {
"name": "test_policy",
@@ -54,8 +53,17 @@ subject_assignment_template = {
}
+def init(consul_host, consul_port):
+ conf_data = utils.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 check_policy(policy_id=None):
- print("URL={}".format(URL.format("/policies")))
req = requests.get(URL.format("/policies"))
assert req.status_code == 200
result = req.json()
@@ -109,10 +117,13 @@ def delete_policy(policy_id):
def add_subject(policy_id=None, name="test_subject"):
subject_template['name'] = name
if policy_id:
+ logger.debug(URL.format("/policies/{}/subjects".format(policy_id)))
req = requests.post(URL.format("/policies/{}/subjects".format(policy_id)),
json=subject_template, headers=HEADERS)
else:
+ 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
result = req.json()
assert "subjects" in result