From 7d782eff123e5b44d41437377ccca66ad1e8b21b Mon Sep 17 00:00:00 2001 From: tierno Date: Fri, 4 Oct 2019 12:56:31 +0000 Subject: [PATCH] feature 8029 change RO to python3. Using vim plugins Change-Id: I1e7bf61db9c39c66e0233c81bd8b4caa6650d389 Signed-off-by: tierno --- Dockerfile | 48 +- Dockerfile-local | 99 +++ MANIFEST.in | 7 - Makefile | 112 +-- RO-VIM-aws/Makefile | 23 + .../osm_rovim_aws}/vimconn_aws.py | 17 +- RO-VIM-aws/requirements.txt | 21 + RO-VIM-aws/setup.py | 55 ++ RO-VIM-aws/stdeb.cfg | 18 + RO-VIM-aws/tox.ini | 41 ++ RO-VIM-azure/Makefile | 25 + .../debian/python3-osm-rovim-azure.postinst | 24 + .../osm_rovim_azure}/vimconn_azure.py | 4 +- RO-VIM-azure/requirements.txt | 20 + RO-VIM-azure/setup.py | 53 ++ RO-VIM-azure/stdeb.cfg | 19 + RO-VIM-azure/tox.ini | 41 ++ RO-VIM-fos/Makefile | 24 + .../debian/python3-osm-rovim-fos.postinst | 24 + .../osm_rovim_fos}/vimconn_fos.py | 2 +- RO-VIM-fos/requirements.txt | 21 + RO-VIM-fos/setup.py | 55 ++ RO-VIM-fos/stdeb.cfg | 18 + RO-VIM-fos/tox.ini | 41 ++ RO-VIM-opennebula/Makefile | 26 + .../python3-osm-rovim-opennebula.postinst | 26 + .../vimconn_opennebula.py | 16 +- RO-VIM-opennebula/requirements.txt | 24 + RO-VIM-opennebula/setup.py | 54 ++ RO-VIM-opennebula/stdeb.cfg | 20 + RO-VIM-opennebula/tox.ini | 42 ++ RO-VIM-openstack/Makefile | 25 + .../python3-osm-rovim-openstack.postinst | 23 + .../tests/test_vimconn_openstack.py | 0 .../osm_rovim_openstack}/vimconn_openstack.py | 62 +- RO-VIM-openstack/requirements.txt | 27 + RO-VIM-openstack/setup.py | 58 ++ RO-VIM-openstack/stdeb.cfg | 20 + RO-VIM-openstack/tox.ini | 41 ++ RO-VIM-openvim/Makefile | 24 + .../osm_rovim_openvim}/vimconn_openvim.py | 124 ++-- RO-VIM-openvim/requirements.txt | 20 + RO-VIM-openvim/setup.py | 55 ++ RO-VIM-openvim/stdeb.cfg | 18 + RO-VIM-openvim/tox.ini | 41 ++ RO-VIM-vmware/Makefile | 26 + .../debian/python3-osm-rovim-vmware.postinst | 29 + .../tests/test_vimconn_vmware.py | 2 +- .../tests/test_vimconn_vmware_xml_response.py | 0 .../osm_rovim_vmware}/vimconn_vmware.py | 32 +- RO-VIM-vmware/requirements.txt | 25 + RO-VIM-vmware/setup.py | 58 ++ RO-VIM-vmware/stdeb.cfg | 20 + RO-VIM-vmware/tox.ini | 42 ++ RO-client/Makefile | 25 + RO-client/README.rst | 6 + .../debian/python3-osm-roclient.postinst | 25 + .../osm_roclient/roclient.py | 662 +++++++++--------- RO-client/requirements.txt | 18 + RO-client/setup.py | 58 ++ RO-client/stdeb.cfg | 18 + RO-client/tox.ini | 41 ++ RO/MANIFEST.in | 21 + RO/Makefile | 120 ++++ README.rst => RO/README.rst | 0 RO/debian/python3-osm-ro.postinst | 21 + {osm_ro => RO/osm_ro}/__init__.py | 0 {osm_ro => RO/osm_ro}/console_proxy_thread.py | 26 +- .../osm_ro/database_utils}/dump_db.sh | 0 .../osm_ro/database_utils}/init_mano_db.sh | 0 .../database_utils}/install-db-server.sh | 0 .../database_utils}/mano_db_structure.sql | 0 .../osm_ro/database_utils}/migrate_mano_db.sh | 0 .../migrations/down/34_remove_wim_tables.sql | 0 .../down/35_remove_sfc_ingress_and_egress.sql | 0 .../migrations/up/34_add_wim_tables.sql | 0 .../up/35_add_sfc_ingress_and_egress.sql | 0 {osm_ro => RO/osm_ro}/db_base.py | 35 +- {osm_ro => RO/osm_ro}/http_tools/__init__.py | 0 {osm_ro => RO/osm_ro}/http_tools/errors.py | 0 {osm_ro => RO/osm_ro}/http_tools/handler.py | 0 .../osm_ro}/http_tools/request_processing.py | 13 +- .../osm_ro}/http_tools/tests/__init__.py | 0 .../osm_ro}/http_tools/tests/test_errors.py | 0 .../osm_ro}/http_tools/tests/test_handler.py | 0 {osm_ro => RO/osm_ro}/http_tools/tox.ini | 0 {osm_ro => RO/osm_ro}/httpserver.py | 24 +- {osm_ro => RO/osm_ro}/nfvo.py | 300 ++++---- {osm_ro => RO/osm_ro}/nfvo_db.py | 22 +- {osm_ro => RO/osm_ro}/openmano_schemas.py | 0 {osm_ro => RO/osm_ro}/openmanoclient.py | 13 +- {osm_ro => RO/osm_ro}/openmanod.cfg | 0 openmanod => RO/osm_ro/openmanod.py | 8 +- {osm_ro => RO/osm_ro}/osm-ro.service | 0 {scripts => RO/osm_ro/scripts}/RO-of | 0 {scripts => RO/osm_ro/scripts}/RO-start.sh | 51 +- {scripts => RO/osm_ro/scripts}/get-options.sh | 0 .../scripts}/install-lib-osm-openvim.sh | 2 + .../scripts}/install-openmano-service.sh | 0 .../osm_ro/scripts}/install-openmano.sh | 0 .../osm_ro/scripts}/install-osm-im.sh | 8 +- .../osm_ro/scripts}/openmano-report | 0 .../osm_ro/scripts}/service-openmano | 0 {osm_ro => RO/osm_ro}/tests/__init__.py | 0 {osm_ro => RO/osm_ro}/tests/db_helpers.py | 0 {osm_ro => RO/osm_ro}/tests/helpers.py | 4 +- {osm_ro => RO/osm_ro}/tests/test_db.py | 2 - {osm_ro => RO/osm_ro}/tests/test_utils.py | 0 {osm_ro => RO/osm_ro}/utils.py | 74 +- {osm_ro => RO/osm_ro}/vim_thread.py | 65 +- {osm_ro => RO/osm_ro}/vimconn.py | 8 +- {osm_ro => RO/osm_ro}/vmwarecli.py | 57 +- {osm_ro => RO/osm_ro}/wim/__init__.py | 0 {osm_ro => RO/osm_ro}/wim/actions.py | 5 +- {osm_ro => RO/osm_ro}/wim/engine.py | 12 +- {osm_ro => RO/osm_ro}/wim/errors.py | 2 +- .../osm_ro}/wim/failing_connector.py | 0 {osm_ro => RO/osm_ro}/wim/http_handler.py | 0 {osm_ro => RO/osm_ro}/wim/persistence.py | 13 +- {osm_ro => RO/osm_ro}/wim/schemas.py | 0 {osm_ro => RO/osm_ro}/wim/tests/__init__.py | 0 {osm_ro => RO/osm_ro}/wim/tests/fixtures.py | 5 +- .../osm_ro}/wim/tests/test_actions.py | 4 +- .../osm_ro}/wim/tests/test_engine.py | 4 +- .../osm_ro}/wim/tests/test_http_handler.py | 4 +- .../osm_ro}/wim/tests/test_persistence.py | 7 +- .../osm_ro}/wim/tests/test_wim_thread.py | 4 +- {osm_ro => RO/osm_ro}/wim/tox.ini | 0 {osm_ro => RO/osm_ro}/wim/wan_link_actions.py | 8 +- {osm_ro => RO/osm_ro}/wim/wim_thread.py | 11 +- {osm_ro => RO/osm_ro}/wim/wimconn.py | 0 {osm_ro => RO/osm_ro}/wim/wimconn_dynpac.py | 2 +- {osm_ro => RO/osm_ro}/wim/wimconn_fake.py | 0 .../osm_ro}/wim/wimconn_ietfl2vpn.py | 0 {osm_ro => RO/osm_ro}/wim/wimconn_odl.py | 0 RO/requirements.txt | 9 + RO/setup.py | 76 ++ RO/stdeb.cfg | 23 + .../scenario_simple_2_vnf_afinnity.yaml | 0 .../vnfd_linux_2_vnfc_affinity.yaml | 0 ...scenario_additional_disk_empty_volume.yaml | 0 .../vnfd_additional_disk_empty_volume.yaml | 0 .../floating_ip/scenario_floating_ip.yaml | 0 .../floating_ip/vnfd_floating_ip.yaml | 0 .../scenario_additional_disk_based_image.yaml | 0 .../vnfd_additional_disk_based_image.yaml | 0 .../scenario_vnf_no_port_security.yaml | 0 .../vnfd_no_port_security.yaml | 0 .../passthrough/scenario_p2p_passthrough.yaml | 0 .../passthrough/vnfd_1passthrough.yaml | 0 .../scenario_pmp_passthrough.yaml | 0 .../pmp_passthrough/vnfd_1passthrough.yaml | 0 .../pmp_sriov/scenario_pmp_sriov.yaml | 0 .../test}/RO_tests/pmp_sriov/vnfd_1sriov.yaml | 0 .../scenario_pmp_sriov_passthrough.yaml | 0 .../vnfd_1passthrough.yaml | 0 .../pmp_sriov_passthrough/vnfd_1sriov.yaml | 0 .../simple_2_vnf/scenario_simple_2_vnf.yaml | 0 .../RO_tests/simple_2_vnf/vnfd_linux.yaml | 0 .../scenario_simple-cloud-init.yaml | 0 .../vnfd_linux-cloud-init.yaml | 0 .../simple_count3/scenario_linux_count3.yaml | 0 .../RO_tests/simple_count3/vnfd_count3.yaml | 0 .../simple_linux/scenario_simple_linux.yaml | 0 .../RO_tests/simple_linux/vnfd_linux.yaml | 0 .../scenario_multi_vnfc.yaml | 0 .../vnfd_linux_2VMs_v02.yaml | 0 .../RO_tests/sr_iov/scenario_p2p_sriov.yaml | 0 .../test}/RO_tests/sr_iov/vnfd_1sriov.yaml | 0 .../scenario_p2p_sriov_passthrough.yaml | 0 .../sriov_passthrough/vnfd_1passthrough.yaml | 0 .../sriov_passthrough/vnfd_1sriov.yaml | 0 .../scenario_2vdu_set_ip_mac.yaml | 0 .../vnfd_2vdu_set_ip_mac.yaml | 0 .../vnfd_2vdu_set_ip_mac2.yaml | 0 {test => RO/test}/basictest.sh | 0 {test => RO/test}/test-multivim.sh | 0 {test => RO/test}/test_RO.py | 12 +- {test => RO/test}/test_on_container.sh | 0 {test => RO/test}/test_openmanocli.sh | 0 {test => RO/test}/test_openmanoclient.py | 0 {test => RO/test}/test_osconnector.py | 116 +-- {test => RO/test}/test_vimconn.sh | 0 RO/tox.ini | 35 + devops-stages/stage-archive.sh | 16 +- devops-stages/stage-build.sh | 57 +- devops-stages/stage-test.sh | 2 +- docker/Dockerfile-local | 92 --- requirements.txt | 25 - scripts/python-osm-ro.postinst | 58 -- setup.py | 73 -- stdeb.cfg | 6 - test-docker/Dockerfile-devops | 65 ++ test-docker/test-gen-devops.sh | 65 ++ test-docker/test-gen-local.sh | 32 + tox.ini | 23 - 196 files changed, 3031 insertions(+), 1354 deletions(-) create mode 100644 Dockerfile-local delete mode 100644 MANIFEST.in create mode 100644 RO-VIM-aws/Makefile rename {osm_ro => RO-VIM-aws/osm_rovim_aws}/vimconn_aws.py (99%) create mode 100644 RO-VIM-aws/requirements.txt create mode 100644 RO-VIM-aws/setup.py create mode 100644 RO-VIM-aws/stdeb.cfg create mode 100644 RO-VIM-aws/tox.ini create mode 100644 RO-VIM-azure/Makefile create mode 100755 RO-VIM-azure/debian/python3-osm-rovim-azure.postinst rename {osm_ro => RO-VIM-azure/osm_rovim_azure}/vimconn_azure.py (99%) create mode 100644 RO-VIM-azure/requirements.txt create mode 100644 RO-VIM-azure/setup.py create mode 100644 RO-VIM-azure/stdeb.cfg create mode 100644 RO-VIM-azure/tox.ini create mode 100644 RO-VIM-fos/Makefile create mode 100755 RO-VIM-fos/debian/python3-osm-rovim-fos.postinst rename {osm_ro => RO-VIM-fos/osm_rovim_fos}/vimconn_fos.py (99%) create mode 100644 RO-VIM-fos/requirements.txt create mode 100644 RO-VIM-fos/setup.py create mode 100644 RO-VIM-fos/stdeb.cfg create mode 100644 RO-VIM-fos/tox.ini create mode 100644 RO-VIM-opennebula/Makefile create mode 100755 RO-VIM-opennebula/debian/python3-osm-rovim-opennebula.postinst rename {osm_ro => RO-VIM-opennebula/osm_rovim_opennebula}/vimconn_opennebula.py (98%) create mode 100644 RO-VIM-opennebula/requirements.txt create mode 100644 RO-VIM-opennebula/setup.py create mode 100644 RO-VIM-opennebula/stdeb.cfg create mode 100644 RO-VIM-opennebula/tox.ini create mode 100644 RO-VIM-openstack/Makefile create mode 100755 RO-VIM-openstack/debian/python3-osm-rovim-openstack.postinst rename {osm_ro => RO-VIM-openstack/osm_rovim_openstack}/tests/test_vimconn_openstack.py (100%) rename {osm_ro => RO-VIM-openstack/osm_rovim_openstack}/vimconn_openstack.py (98%) create mode 100644 RO-VIM-openstack/requirements.txt create mode 100644 RO-VIM-openstack/setup.py create mode 100644 RO-VIM-openstack/stdeb.cfg create mode 100644 RO-VIM-openstack/tox.ini create mode 100644 RO-VIM-openvim/Makefile rename {osm_ro => RO-VIM-openvim/osm_rovim_openvim}/vimconn_openvim.py (92%) create mode 100644 RO-VIM-openvim/requirements.txt create mode 100644 RO-VIM-openvim/setup.py create mode 100644 RO-VIM-openvim/stdeb.cfg create mode 100644 RO-VIM-openvim/tox.ini create mode 100644 RO-VIM-vmware/Makefile create mode 100755 RO-VIM-vmware/debian/python3-osm-rovim-vmware.postinst rename {osm_ro => RO-VIM-vmware/osm_rovim_vmware}/tests/test_vimconn_vmware.py (99%) rename {osm_ro => RO-VIM-vmware/osm_rovim_vmware}/tests/test_vimconn_vmware_xml_response.py (100%) rename {osm_ro => RO-VIM-vmware/osm_rovim_vmware}/vimconn_vmware.py (99%) create mode 100644 RO-VIM-vmware/requirements.txt create mode 100644 RO-VIM-vmware/setup.py create mode 100644 RO-VIM-vmware/stdeb.cfg create mode 100644 RO-VIM-vmware/tox.ini create mode 100644 RO-client/Makefile create mode 100644 RO-client/README.rst create mode 100755 RO-client/debian/python3-osm-roclient.postinst rename openmano => RO-client/osm_roclient/roclient.py (83%) create mode 100644 RO-client/requirements.txt create mode 100644 RO-client/setup.py create mode 100644 RO-client/stdeb.cfg create mode 100644 RO-client/tox.ini create mode 100644 RO/MANIFEST.in create mode 100644 RO/Makefile rename README.rst => RO/README.rst (100%) create mode 100755 RO/debian/python3-osm-ro.postinst rename {osm_ro => RO/osm_ro}/__init__.py (100%) rename {osm_ro => RO/osm_ro}/console_proxy_thread.py (89%) rename {database_utils => RO/osm_ro/database_utils}/dump_db.sh (100%) rename {database_utils => RO/osm_ro/database_utils}/init_mano_db.sh (100%) rename {database_utils => RO/osm_ro/database_utils}/install-db-server.sh (100%) rename {database_utils => RO/osm_ro/database_utils}/mano_db_structure.sql (100%) rename {database_utils => RO/osm_ro/database_utils}/migrate_mano_db.sh (100%) rename {database_utils => RO/osm_ro/database_utils}/migrations/down/34_remove_wim_tables.sql (100%) rename {database_utils => RO/osm_ro/database_utils}/migrations/down/35_remove_sfc_ingress_and_egress.sql (100%) rename {database_utils => RO/osm_ro/database_utils}/migrations/up/34_add_wim_tables.sql (100%) rename {database_utils => RO/osm_ro/database_utils}/migrations/up/35_add_sfc_ingress_and_egress.sql (100%) rename {osm_ro => RO/osm_ro}/db_base.py (97%) rename {osm_ro => RO/osm_ro}/http_tools/__init__.py (100%) rename {osm_ro => RO/osm_ro}/http_tools/errors.py (100%) rename {osm_ro => RO/osm_ro}/http_tools/handler.py (100%) rename {osm_ro => RO/osm_ro}/http_tools/request_processing.py (94%) rename {osm_ro => RO/osm_ro}/http_tools/tests/__init__.py (100%) rename {osm_ro => RO/osm_ro}/http_tools/tests/test_errors.py (100%) rename {osm_ro => RO/osm_ro}/http_tools/tests/test_handler.py (100%) rename {osm_ro => RO/osm_ro}/http_tools/tox.ini (100%) rename {osm_ro => RO/osm_ro}/httpserver.py (99%) rename {osm_ro => RO/osm_ro}/nfvo.py (97%) rename {osm_ro => RO/osm_ro}/nfvo_db.py (99%) rename {osm_ro => RO/osm_ro}/openmano_schemas.py (100%) rename {osm_ro => RO/osm_ro}/openmanoclient.py (99%) rename {osm_ro => RO/osm_ro}/openmanod.cfg (100%) rename openmanod => RO/osm_ro/openmanod.py (99%) rename {osm_ro => RO/osm_ro}/osm-ro.service (100%) rename {scripts => RO/osm_ro/scripts}/RO-of (100%) rename {scripts => RO/osm_ro/scripts}/RO-start.sh (74%) rename {scripts => RO/osm_ro/scripts}/get-options.sh (100%) rename {scripts => RO/osm_ro/scripts}/install-lib-osm-openvim.sh (98%) rename {scripts => RO/osm_ro/scripts}/install-openmano-service.sh (100%) rename {scripts => RO/osm_ro/scripts}/install-openmano.sh (100%) rename {scripts => RO/osm_ro/scripts}/install-osm-im.sh (93%) rename {scripts => RO/osm_ro/scripts}/openmano-report (100%) rename {scripts => RO/osm_ro/scripts}/service-openmano (100%) rename {osm_ro => RO/osm_ro}/tests/__init__.py (100%) rename {osm_ro => RO/osm_ro}/tests/db_helpers.py (100%) rename {osm_ro => RO/osm_ro}/tests/helpers.py (98%) rename {osm_ro => RO/osm_ro}/tests/test_db.py (99%) rename {osm_ro => RO/osm_ro}/tests/test_utils.py (100%) rename {osm_ro => RO/osm_ro}/utils.py (87%) rename {osm_ro => RO/osm_ro}/vim_thread.py (97%) rename {osm_ro => RO/osm_ro}/vimconn.py (99%) rename {osm_ro => RO/osm_ro}/vmwarecli.py (95%) rename {osm_ro => RO/osm_ro}/wim/__init__.py (100%) rename {osm_ro => RO/osm_ro}/wim/actions.py (99%) rename {osm_ro => RO/osm_ro}/wim/engine.py (98%) rename {osm_ro => RO/osm_ro}/wim/errors.py (99%) rename {osm_ro => RO/osm_ro}/wim/failing_connector.py (100%) rename {osm_ro => RO/osm_ro}/wim/http_handler.py (100%) rename {osm_ro => RO/osm_ro}/wim/persistence.py (99%) rename {osm_ro => RO/osm_ro}/wim/schemas.py (100%) rename {osm_ro => RO/osm_ro}/wim/tests/__init__.py (100%) rename {osm_ro => RO/osm_ro}/wim/tests/fixtures.py (99%) rename {osm_ro => RO/osm_ro}/wim/tests/test_actions.py (99%) rename {osm_ro => RO/osm_ro}/wim/tests/test_engine.py (99%) rename {osm_ro => RO/osm_ro}/wim/tests/test_http_handler.py (99%) rename {osm_ro => RO/osm_ro}/wim/tests/test_persistence.py (98%) rename {osm_ro => RO/osm_ro}/wim/tests/test_wim_thread.py (99%) rename {osm_ro => RO/osm_ro}/wim/tox.ini (100%) rename {osm_ro => RO/osm_ro}/wim/wan_link_actions.py (99%) rename {osm_ro => RO/osm_ro}/wim/wim_thread.py (98%) rename {osm_ro => RO/osm_ro}/wim/wimconn.py (100%) rename {osm_ro => RO/osm_ro}/wim/wimconn_dynpac.py (99%) rename {osm_ro => RO/osm_ro}/wim/wimconn_fake.py (100%) rename {osm_ro => RO/osm_ro}/wim/wimconn_ietfl2vpn.py (100%) rename {osm_ro => RO/osm_ro}/wim/wimconn_odl.py (100%) create mode 100644 RO/requirements.txt create mode 100755 RO/setup.py create mode 100644 RO/stdeb.cfg rename {test => RO/test}/RO_tests/afiinity_vnf/scenario_simple_2_vnf_afinnity.yaml (100%) rename {test => RO/test}/RO_tests/afiinity_vnf/vnfd_linux_2_vnfc_affinity.yaml (100%) rename {test => RO/test}/RO_tests/empy_volume/scenario_additional_disk_empty_volume.yaml (100%) rename {test => RO/test}/RO_tests/empy_volume/vnfd_additional_disk_empty_volume.yaml (100%) rename {test => RO/test}/RO_tests/floating_ip/scenario_floating_ip.yaml (100%) rename {test => RO/test}/RO_tests/floating_ip/vnfd_floating_ip.yaml (100%) rename {test => RO/test}/RO_tests/image_based_volume/scenario_additional_disk_based_image.yaml (100%) rename {test => RO/test}/RO_tests/image_based_volume/vnfd_additional_disk_based_image.yaml (100%) rename {test => RO/test}/RO_tests/no_port_security/scenario_vnf_no_port_security.yaml (100%) rename {test => RO/test}/RO_tests/no_port_security/vnfd_no_port_security.yaml (100%) rename {test => RO/test}/RO_tests/passthrough/scenario_p2p_passthrough.yaml (100%) rename {test => RO/test}/RO_tests/passthrough/vnfd_1passthrough.yaml (100%) rename {test => RO/test}/RO_tests/pmp_passthrough/scenario_pmp_passthrough.yaml (100%) rename {test => RO/test}/RO_tests/pmp_passthrough/vnfd_1passthrough.yaml (100%) rename {test => RO/test}/RO_tests/pmp_sriov/scenario_pmp_sriov.yaml (100%) rename {test => RO/test}/RO_tests/pmp_sriov/vnfd_1sriov.yaml (100%) rename {test => RO/test}/RO_tests/pmp_sriov_passthrough/scenario_pmp_sriov_passthrough.yaml (100%) rename {test => RO/test}/RO_tests/pmp_sriov_passthrough/vnfd_1passthrough.yaml (100%) rename {test => RO/test}/RO_tests/pmp_sriov_passthrough/vnfd_1sriov.yaml (100%) rename {test => RO/test}/RO_tests/simple_2_vnf/scenario_simple_2_vnf.yaml (100%) rename {test => RO/test}/RO_tests/simple_2_vnf/vnfd_linux.yaml (100%) rename {test => RO/test}/RO_tests/simple_cloud_init/scenario_simple-cloud-init.yaml (100%) rename {test => RO/test}/RO_tests/simple_cloud_init/vnfd_linux-cloud-init.yaml (100%) rename {test => RO/test}/RO_tests/simple_count3/scenario_linux_count3.yaml (100%) rename {test => RO/test}/RO_tests/simple_count3/vnfd_count3.yaml (100%) rename {test => RO/test}/RO_tests/simple_linux/scenario_simple_linux.yaml (100%) rename {test => RO/test}/RO_tests/simple_linux/vnfd_linux.yaml (100%) rename {test => RO/test}/RO_tests/simple_multi_vnfc/scenario_multi_vnfc.yaml (100%) rename {test => RO/test}/RO_tests/simple_multi_vnfc/vnfd_linux_2VMs_v02.yaml (100%) rename {test => RO/test}/RO_tests/sr_iov/scenario_p2p_sriov.yaml (100%) rename {test => RO/test}/RO_tests/sr_iov/vnfd_1sriov.yaml (100%) rename {test => RO/test}/RO_tests/sriov_passthrough/scenario_p2p_sriov_passthrough.yaml (100%) rename {test => RO/test}/RO_tests/sriov_passthrough/vnfd_1passthrough.yaml (100%) rename {test => RO/test}/RO_tests/sriov_passthrough/vnfd_1sriov.yaml (100%) rename {test => RO/test}/RO_tests/v3_2vdu_set_ip_mac/scenario_2vdu_set_ip_mac.yaml (100%) rename {test => RO/test}/RO_tests/v3_2vdu_set_ip_mac/vnfd_2vdu_set_ip_mac.yaml (100%) rename {test => RO/test}/RO_tests/v3_2vdu_set_ip_mac/vnfd_2vdu_set_ip_mac2.yaml (100%) rename {test => RO/test}/basictest.sh (100%) rename {test => RO/test}/test-multivim.sh (100%) rename {test => RO/test}/test_RO.py (99%) rename {test => RO/test}/test_on_container.sh (100%) rename {test => RO/test}/test_openmanocli.sh (100%) rename {test => RO/test}/test_openmanoclient.py (100%) rename {test => RO/test}/test_osconnector.py (69%) rename {test => RO/test}/test_vimconn.sh (100%) create mode 100644 RO/tox.ini delete mode 100644 docker/Dockerfile-local delete mode 100644 requirements.txt delete mode 100755 scripts/python-osm-ro.postinst delete mode 100755 setup.py delete mode 100644 stdeb.cfg create mode 100644 test-docker/Dockerfile-devops create mode 100755 test-docker/test-gen-devops.sh create mode 100755 test-docker/test-gen-local.sh delete mode 100644 tox.ini diff --git a/Dockerfile b/Dockerfile index a0f45ba9..c758db93 100644 --- a/Dockerfile +++ b/Dockerfile @@ -18,30 +18,36 @@ # Use docker/Dockerfile-local for running osm/RO in a docker container from source FROM ubuntu:16.04 - RUN apt-get update && \ - DEBIAN_FRONTEND=noninteractive apt-get -y install git make python python-pip debhelper python3 python3-all python3-pip python3-setuptools && \ - DEBIAN_FRONTEND=noninteractive apt-get -y install wget tox apt-utils flake8 python-nose python-mock && \ - DEBIAN_FRONTEND=noninteractive pip install pip==9.0.3 && \ - DEBIAN_FRONTEND=noninteractive pip3 install pip==9.0.3 && \ - DEBIAN_FRONTEND=noninteractive pip install -U setuptools setuptools-version-command stdeb && \ - DEBIAN_FRONTEND=noninteractive pip install -U pyang pyangbind && \ - DEBIAN_FRONTEND=noninteractive pip3 install -U pyang pyangbind && \ - DEBIAN_FRONTEND=noninteractive apt-get -y install python-yaml python-netaddr python-boto && \ - DEBIAN_FRONTEND=noninteractive apt-get -y install software-properties-common && \ - DEBIAN_FRONTEND=noninteractive add-apt-repository -y cloud-archive:queens && \ - DEBIAN_FRONTEND=noninteractive apt-get update && \ - DEBIAN_FRONTEND=noninteractive apt-get -y install python-novaclient python-keystoneclient python-glanceclient python-cinderclient python-neutronclient python-networking-l2gw && \ - DEBIAN_FRONTEND=noninteractive pip install -U progressbar pyvmomi pyvcloud==19.1.1 && \ - DEBIAN_FRONTEND=noninteractive pip install -U fog05rest && \ - DEBIAN_FRONTEND=noninteractive pip install -U azure && \ - DEBIAN_FRONTEND=noninteractive apt-get -y install python-argcomplete python-bottle python-cffi python-packaging python-paramiko python-pkgconfig libmysqlclient-dev libssl-dev libffi-dev python-mysqldb && \ - DEBIAN_FRONTEND=noninteractive apt-get -y install python-logutils python-openstackclient python-openstacksdk && \ - DEBIAN_FRONTEND=noninteractive pip install untangle && \ - DEBIAN_FRONTEND=noninteractive pip install pyone && \ - DEBIAN_FRONTEND=noninteractive pip install -e git+https://github.com/python-oca/python-oca#egg=oca + DEBIAN_FRONTEND=noninteractive apt-get --yes install git tox make python-all python3 python3-pip debhelper wget && \ + DEBIAN_FRONTEND=noninteractive apt-get --yes install python3-all libssl-dev && \ + DEBIAN_FRONTEND=noninteractive pip3 install -U setuptools setuptools-version-command stdeb + +# FROM ubuntu:16.04 +# RUN apt-get update && \ +# DEBIAN_FRONTEND=noninteractive apt-get -y install git make python python-pip debhelper python3 python3-all python3-pip python3-setuptools && \ +# DEBIAN_FRONTEND=noninteractive apt-get -y install wget tox apt-utils flake8 python-nose python-mock && \ +# DEBIAN_FRONTEND=noninteractive pip install pip==9.0.3 && \ +# DEBIAN_FRONTEND=noninteractive pip3 install pip==9.0.3 && \ +# DEBIAN_FRONTEND=noninteractive pip install -U setuptools setuptools-version-command stdeb && \ +# DEBIAN_FRONTEND=noninteractive pip install -U pyang pyangbind && \ +# DEBIAN_FRONTEND=noninteractive pip3 install -U pyang pyangbind && \ +# DEBIAN_FRONTEND=noninteractive apt-get -y install python-yaml python-netaddr python-boto && \ +# DEBIAN_FRONTEND=noninteractive apt-get -y install software-properties-common && \ +# DEBIAN_FRONTEND=noninteractive add-apt-repository -y cloud-archive:queens && \ +# DEBIAN_FRONTEND=noninteractive apt-get update && \ +# DEBIAN_FRONTEND=noninteractive apt-get -y install python-novaclient python-keystoneclient python-glanceclient python-cinderclient python-neutronclient python-networking-l2gw && \ +# DEBIAN_FRONTEND=noninteractive pip install -U progressbar pyvmomi pyvcloud==19.1.1 && \ +# DEBIAN_FRONTEND=noninteractive pip install -U fog05rest && \ +# DEBIAN_FRONTEND=noninteractive pip install -U azure && \ +# DEBIAN_FRONTEND=noninteractive apt-get -y install python-argcomplete python-bottle python-cffi python-packaging python-paramiko python-pkgconfig libmysqlclient-dev libssl-dev libffi-dev python-mysqldb && \ +# DEBIAN_FRONTEND=noninteractive apt-get -y install python-logutils python-openstackclient python-openstacksdk && \ +# DEBIAN_FRONTEND=noninteractive pip install untangle && \ +# DEBIAN_FRONTEND=noninteractive pip install pyone && \ +# DEBIAN_FRONTEND=noninteractive pip install -e git+https://github.com/python-oca/python-oca#egg=oca +# TODO py3 comment # Uncomment this block to generate automatically a debian package and show info # # Set the working directory to /app # WORKDIR /app diff --git a/Dockerfile-local b/Dockerfile-local new file mode 100644 index 00000000..48447acc --- /dev/null +++ b/Dockerfile-local @@ -0,0 +1,99 @@ +## +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +# implied. +# See the License for the specific language governing permissions and +# limitations under the License. +## + +FROM ubuntu:18.04 + +LABEL authors="Alfonso Tierno" + +RUN apt-get update && apt-get install -y git python3 python3-pip \ + && python3 -m pip install --upgrade pip \ + && DEBIAN_FRONTEND=noninteractive apt-get -y install libmysqlclient-dev mysql-client \ + && DEBIAN_FRONTEND=noninteractive python3 -m pip install -U networking-l2gw \ + && DEBIAN_FRONTEND=noninteractive python3 -m pip install -U progressbar pyvmomi pyvcloud==19.1.1 \ + && DEBIAN_FRONTEND=noninteractive apt-get -y install genisoimage + +# This is not needed, because package dependency will install anyway. +# But done here in order to harry up image generation using cache + +RUN DEBIAN_FRONTEND=noninteractive apt-get -y install python3-neutronclient python3-openstackclient \ + python3-requests python3-netaddr python3-argcomplete + +# DEBIAN_FRONTEND=noninteractive apt-get -y install python-openstacksdk python-openstackclient && \ +# TODO py3 DEBIAN_FRONTEND=noninteractive add-apt-repository -y cloud-archive:rocky && apt-get update && apt-get install -y python3-networking-l2gw \ + +# DEBIAN_FRONTEND=noninteractive apt-get -y install python-cffi libssl-dev libffi-dev python-mysqldb && \ +# DEBIAN_FRONTEND=noninteractive pip2 install -U azure && \ +# DEBIAN_FRONTEND=noninteractive pip2 install -U fog05rest && \ +# && DEBIAN_FRONTEND=noninteractive apt-get -y install software-properties-common && \ +# DEBIAN_FRONTEND=noninteractive apt-get -y install wget tox && \ +# DEBIAN_FRONTEND=noninteractive pip2 install untangle && \ +# DEBIAN_FRONTEND=noninteractive pip2 install pyone && \ +# DEBIAN_FRONTEND=noninteractive pip2 install -e git+https://github.com/python-oca/python-oca#egg=oca && \ + +COPY . /root/RO + +RUN /root/RO/RO/osm_ro/scripts/install-osm-im.sh --develop && \ + /root/RO/RO/osm_ro/scripts/install-lib-osm-openvim.sh --develop && \ + mkdir -p /var/log/osm && \ + python3 -m pip install -e /root/RO/RO && \ + python3 -m pip install -e /root/RO/RO-client && \ + python3 -m pip install -e /root/RO/RO-VIM-vmware && \ + python3 -m pip install -e /root/RO/RO-VIM-openstack && \ + python3 -m pip install -e /root/RO/RO-VIM-openvim && \ + python3 -m pip install -e /root/RO/RO-VIM-aws && \ + python3 -m pip install -e /root/RO/RO-VIM-fos && \ + rm -rf /root/.cache && \ + apt-get clean && \ + rm -rf /var/lib/apt/lists/* + +VOLUME /var/log/osm + +EXPOSE 9090 + +# Two mysql databases are needed (DB and DB_OVIM). Can be hosted on same or separated containers +# These ENV must be provided +# RO_DB_HOST: host of the main +# RO_DB_OVIM_HOST: ... if empty RO_DB_HOST is assumed +# RO_DB_ROOT_PASSWORD: this has to be provided first time for creating database. It will create and init only if empty! +# RO_DB_OVIM_ROOT_PASSWORD: ... if empty RO_DB_ROOT_PASSWORD is assumed +# RO_DB_USER: default value 'mano' +# RO_DB_OVIM_USER: default value 'mano' +# RO_DB_PASSWORD: default value 'manopw' +# RO_DB_OVIM_PASSWORD: default value 'manopw' +# RO_DB_PORT: default value '3306' +# RO_DB_OVIM_PORT: default value '3306' +# RO_DB_NAME: default value 'mano_db' +# RO_DB_OVIM_NAME: default value 'mano_vim_db' +# RO_LOG_FILE: default log to stderr if not defined + +ENV RO_DB_HOST="" \ + RO_DB_OVIM_HOST="" \ + RO_DB_ROOT_PASSWORD="" \ + RO_DB_OVIM_ROOT_PASSWORD="" \ + RO_DB_USER=mano \ + RO_DB_OVIM_USER=mano \ + RO_DB_PASSWORD=manopw \ + RO_DB_OVIM_PASSWORD=manopw \ + RO_DB_PORT=3306 \ + RO_DB_OVIM_PORT=3306 \ + RO_DB_NAME=mano_db \ + RO_DB_OVIM_NAME=mano_vim_db \ + OPENMANO_TENANT=osm \ + RO_LOG_LEVEL=DEBUG + +CMD RO-start.sh + +# HEALTHCHECK --start-period=30s --interval=10s --timeout=5s --retries=12 \ +# CMD curl --silent --fail localhost:9090/openmano/tenants || exit 1 diff --git a/MANIFEST.in b/MANIFEST.in deleted file mode 100644 index 483b709e..00000000 --- a/MANIFEST.in +++ /dev/null @@ -1,7 +0,0 @@ -#include MANIFEST.in -#include requirements.txt -include README.rst -include openmano -include openmanod -recursive-include osm_ro * - diff --git a/Makefile b/Makefile index 33deb4e9..90ee12c3 100644 --- a/Makefile +++ b/Makefile @@ -1,5 +1,3 @@ -# Copyright 2018 Telefonica S.A. -# # 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 @@ -13,110 +11,14 @@ # See the License for the specific language governing permissions and # limitations under the License. -.PHONY: all test clean - -SHELL := /bin/bash - -BRANCH ?= master - -all: # lib-openvim # osm-im - $(MAKE) clean_build build - $(MAKE) clean_build package - -clean: clean_build - rm -rf .build openvim IM - -clean_build: - rm -rf build - find osm_ro -name '*.pyc' -delete - find osm_ro -name '*.pyo' -delete - -prepare: -# ip install --user --upgrade setuptools - mkdir -p build/ -# VER1=$(shell git describe | sed -e 's/^v//' |cut -d- -f1); \ -# VER2=$(shell git describe | cut -d- -f2); \ -# VER3=$(shell git describe | cut -d- -f3); \ -# echo "$$VER1.dev$$VER2+$$VER3" > build/RO_VERSION - cp tox.ini build/ - cp MANIFEST.in build/ - cp requirements.txt build/ - cp README.rst build/ - cp setup.py build/ - cp stdeb.cfg build/ - cp -r osm_ro build/ - cp openmano build/ - cp openmanod build/ - cp -r vnfs build/osm_ro - cp -r scenarios build/osm_ro - cp -r instance-scenarios build/osm_ro - cp -r scripts build/osm_ro - cp -r database_utils build/osm_ro - cp LICENSE build/osm_ro - -connectors: prepare - # python-novaclient is required for that - rm -f build/osm_ro/openmanolinkervimconn.py - cd build/osm_ro; for i in `ls vimconn_*.py |sed "s/\.py//"` ; do echo "import $$i" >> openmanolinkervimconn.py; done - python build/osm_ro/openmanolinkervimconn.py 2>&1 - rm -f build/osm_ro/openmanolinkervimconn.py - -build: connectors prepare - python -m py_compile build/osm_ro/*.py -# cd build && tox -e flake8 - -lib-openvim: - $(shell git clone https://osm.etsi.org/gerrit/osm/openvim) - LIB_BRANCH=$(shell git -C openvim branch -a|grep -oP 'remotes/origin/\K$(BRANCH)'); \ - [ -z "$$LIB_BRANCH" ] && LIB_BRANCH='master'; \ - echo "BRANCH: $(BRANCH)"; \ - echo "LIB_OPENVIM_BRANCH: $$LIB_BRANCH"; \ - git -C openvim checkout $$LIB_BRANCH - make -C openvim clean lite - -osm-im: - $(shell git clone https://osm.etsi.org/gerrit/osm/IM) - make -C IM clean all - -package: prepare -# apt-get install -y python-stdeb - cd build && python setup.py --command-packages=stdeb.command sdist_dsc --with-python2=True - cd build && cp osm_ro/scripts/python-osm-ro.postinst deb_dist/osm-ro*/debian/ - cd build/deb_dist/osm-ro* && dpkg-buildpackage -rfakeroot -uc -us - mkdir -p .build - cp build/deb_dist/python-*.deb .build/ - -snap: - echo "Nothing to be done yet" - -install: lib-openvim osm-im - dpkg -i IM/deb_dist/python-osm-im*.deb - dpkg -i openvim/.build/python-lib-osm-openvim*.deb - dpkg -i .build/python-osm-ro*.deb - cd .. && \ - OSMLIBOVIM_PATH=`python -c 'import lib_osm_openvim; print lib_osm_openvim.__path__[0]'` || FATAL "lib-osm-openvim was not properly installed" && \ - OSMRO_PATH=`python -c 'import osm_ro; print osm_ro.__path__[0]'` || FATAL "osm-ro was not properly installed" && \ - USER=root DEBIAN_FRONTEND=noninteractive $$OSMRO_PATH/database_utils/install-db-server.sh --updatedb || FATAL "osm-ro db installation failed" && \ - USER=root DEBIAN_FRONTEND=noninteractive $$OSMLIBOVIM_PATH/database_utils/install-db-server.sh -u mano -p manopw -d mano_vim_db --updatedb || FATAL "lib-osm-openvim db installation failed" - service osm-ro restart - -develop: prepare -# pip install -r requirements.txt - cd build && ./setup.py develop - -test: - . ./test/basictest.sh -f --insert-bashrc --install-openvim --init-openvim - . ./test/basictest.sh -f reset add-openvim - ./test/test_RO.py deploy -n mgmt -t osm -i cirros034 -d local-openvim --timeout=30 --failfast - ./test/test_RO.py vim -t osm -d local-openvim --timeout=30 --failfast - -build-docker-from-source: - docker build -t osm/openmano -f docker/Dockerfile-local . +SUBDIRS := $(wildcard */Makefile) -run-docker: - docker-compose -f docker/openmano-compose.yml up +all: clean package +clean: $(SUBDIRS) +package: $(SUBDIRS) -stop-docker: - docker-compose -f docker/openmano-compose.yml down +$(SUBDIRS): + $(MAKE) -C $(@:Makefile=) $(MAKECMDGOALS) +.PHONY: all $(SUBDIRS) diff --git a/RO-VIM-aws/Makefile b/RO-VIM-aws/Makefile new file mode 100644 index 00000000..edf3eb7a --- /dev/null +++ b/RO-VIM-aws/Makefile @@ -0,0 +1,23 @@ +## +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +# implied. +# See the License for the specific language governing permissions and +# limitations under the License. +## + +all: clean package + +clean: + rm -rf dist deb_dist osm_rovim_aws-*.tar.gz osm_rovim_aws.egg-info .eggs + +package: + python3 setup.py --command-packages=stdeb.command sdist_dsc + cd deb_dist/osm-rovim-aws*/ && dpkg-buildpackage -rfakeroot -uc -us diff --git a/osm_ro/vimconn_aws.py b/RO-VIM-aws/osm_rovim_aws/vimconn_aws.py similarity index 99% rename from osm_ro/vimconn_aws.py rename to RO-VIM-aws/osm_rovim_aws/vimconn_aws.py index bcd8cbc8..8173662e 100644 --- a/osm_ro/vimconn_aws.py +++ b/RO-VIM-aws/osm_rovim_aws/vimconn_aws.py @@ -28,18 +28,15 @@ AWS-connector implements all the methods to interact with AWS using the BOTO cli __author__ = "Saboor Ahmad" __date__ = "10-Apr-2017" -import vimconn +from osm_ro import vimconn import yaml import logging import netaddr import time -try: - import boto - import boto.ec2 - import boto.vpc -except: - exit("Boto not avialable. Try activating your virtualenv OR `pip install boto`") +import boto +import boto.ec2 +import boto.vpc class vimconnector(vimconn.vimconnector): @@ -111,9 +108,9 @@ class vimconnector(vimconn.vimconnector): try: if flavor_data[0] == "@": # read from a file with open(flavor_data[1:], 'r') as stream: - self.flavor_info = yaml.load(stream) + self.flavor_info = yaml.load(stream, Loader=yaml.Loader) else: - self.flavor_info = yaml.load(flavor_data) + self.flavor_info = yaml.load(flavor_data, Loader=yaml.Loader) except yaml.YAMLError as e: self.flavor_info = None raise vimconn.vimconnException("Bad format at file '{}': {}".format(flavor_data[1:], e)) @@ -481,7 +478,7 @@ class vimconnector(vimconn.vimconnector): self.logger.debug("Getting flavor id from data") try: flavor = None - for key, values in self.flavor_info.iteritems(): + for key, values in self.flavor_info.items(): if (values["ram"], values["cpus"], values["disk"]) == ( flavor_dict["ram"], flavor_dict["vcpus"], flavor_dict["disk"]): flavor = (key, values) diff --git a/RO-VIM-aws/requirements.txt b/RO-VIM-aws/requirements.txt new file mode 100644 index 00000000..ed019dcf --- /dev/null +++ b/RO-VIM-aws/requirements.txt @@ -0,0 +1,21 @@ +## +# 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. +## + +PyYAML +requests +netaddr +boto +git+https://osm.etsi.org/gerrit/osm/RO.git#egg=osm-ro + diff --git a/RO-VIM-aws/setup.py b/RO-VIM-aws/setup.py new file mode 100644 index 00000000..30b90bd3 --- /dev/null +++ b/RO-VIM-aws/setup.py @@ -0,0 +1,55 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- + +## +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +# implied. +# See the License for the specific language governing permissions and +# limitations under the License. +## + +from setuptools import setup + +_name = "osm_rovim_aws" + +README = """ +=========== +osm-rovim_aws +=========== + +osm-ro pluging for aws VIM +""" + +setup( + name=_name, + description='OSM ro vim plugin for aws', + long_description=README, + version_command=('git describe --match v* --tags --long --dirty', 'pep440-git-full'), + # version=VERSION, + # python_requires='>3.5.0', + author='ETSI OSM', + # TODO py3 author_email='', + maintainer='OSM_TECH@LIST.ETSI.ORG', # TODO py3 + # TODO py3 maintainer_email='', + url='https://osm.etsi.org/gitweb/?p=osm/RO.git;a=summary', + license='Apache 2.0', + + packages=[_name], + include_package_data=True, + dependency_links=["git+https://osm.etsi.org/gerrit/osm/RO.git#egg=osm-ro"], + install_requires=[ + "requests", "netaddr", "PyYAML", "osm-ro", "boto" + ], + setup_requires=['setuptools-version-command'], + entry_points={ + 'osm_rovim.plugins': ['rovim_aws = osm_rovim_aws.vimconn_aws'], + }, +) diff --git a/RO-VIM-aws/stdeb.cfg b/RO-VIM-aws/stdeb.cfg new file mode 100644 index 00000000..2193709e --- /dev/null +++ b/RO-VIM-aws/stdeb.cfg @@ -0,0 +1,18 @@ +# +# 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. +# + +[DEFAULT] +X-Python3-Version : >= 3.5 +Depends3: python3-boto, python3-requests, python3-netaddr, python3-yaml, python3-osm-ro diff --git a/RO-VIM-aws/tox.ini b/RO-VIM-aws/tox.ini new file mode 100644 index 00000000..067b0d43 --- /dev/null +++ b/RO-VIM-aws/tox.ini @@ -0,0 +1,41 @@ +## +# 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. +## + +[tox] +envlist = py3 +toxworkdir={homedir}/.tox + +[testenv] +basepython = python3 +install_command = python3 -m pip install -r requirements.txt -U {opts} {packages} +# deps = -r{toxinidir}/test-requirements.txt +commands=python3 -m unittest discover -v + +[testenv:flake8] +basepython = python3 +deps = flake8 +commands = flake8 osm_rovim_aws --max-line-length 120 \ + --exclude .svn,CVS,.gz,.git,__pycache__,.tox,local,temp --ignore W291,W293,E226,W504 + +[testenv:unittest] +basepython = python3 +commands = python3 -m unittest osm_rovim_aws.tests + +[testenv:build] +basepython = python3 +deps = stdeb + setuptools-version-command +commands = python3 setup.py --command-packages=stdeb.command bdist_deb + diff --git a/RO-VIM-azure/Makefile b/RO-VIM-azure/Makefile new file mode 100644 index 00000000..d5b779a3 --- /dev/null +++ b/RO-VIM-azure/Makefile @@ -0,0 +1,25 @@ +## +# 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. +## + +all: clean package + +clean: + rm -rf dist deb_dist osm_rovim_azure-*.tar.gz osm_rovim_azure.egg-info .eggs + +package: + python3 setup.py --command-packages=stdeb.command sdist_dsc + cp debian/python3-osm-rovim-azure.postinst deb_dist/osm-rovim-azure*/debian/ + cd deb_dist/osm-rovim-azure*/ && dpkg-buildpackage -rfakeroot -uc -us + diff --git a/RO-VIM-azure/debian/python3-osm-rovim-azure.postinst b/RO-VIM-azure/debian/python3-osm-rovim-azure.postinst new file mode 100755 index 00000000..ebb69b1e --- /dev/null +++ b/RO-VIM-azure/debian/python3-osm-rovim-azure.postinst @@ -0,0 +1,24 @@ +#!/bin/bash + +## +# 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. +# +# For those usages not covered by the Apache License, Version 2.0 please +# contact with: OSM_TECH@list.etsi.org +## + +echo "POST INSTALL OSM-ROVIM-AZURE" + +#Pip packages required for azure connector +python3 -m pip install azure + diff --git a/osm_ro/vimconn_azure.py b/RO-VIM-azure/osm_rovim_azure/vimconn_azure.py similarity index 99% rename from osm_ro/vimconn_azure.py rename to RO-VIM-azure/osm_rovim_azure/vimconn_azure.py index 24a9878d..0cc143fa 100755 --- a/osm_ro/vimconn_azure.py +++ b/RO-VIM-azure/osm_rovim_azure/vimconn_azure.py @@ -3,7 +3,7 @@ __author__='Sergio Gonzalez' __date__ ='$18-apr-2019 23:59:59$' -import vimconn +from osm_ro import vimconn import logging from os import getenv @@ -492,4 +492,4 @@ if __name__ == "__main__": # azure.new_vminstance(virtualMachine['name'], virtualMachine['description'], virtualMachine['status'], # virtualMachine['image'], virtualMachine['hardware_profile']['vm_size'], subnets) - azure.get_flavor("Standard_A11") \ No newline at end of file + azure.get_flavor("Standard_A11") diff --git a/RO-VIM-azure/requirements.txt b/RO-VIM-azure/requirements.txt new file mode 100644 index 00000000..920d03a4 --- /dev/null +++ b/RO-VIM-azure/requirements.txt @@ -0,0 +1,20 @@ +## +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +# implied. +# See the License for the specific language governing permissions and +# limitations under the License. +## + +PyYAML +requests +netaddr +azure + diff --git a/RO-VIM-azure/setup.py b/RO-VIM-azure/setup.py new file mode 100644 index 00000000..557fedaf --- /dev/null +++ b/RO-VIM-azure/setup.py @@ -0,0 +1,53 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- + +## +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +# implied. +# See the License for the specific language governing permissions and +# limitations under the License. +## + +from setuptools import setup + +_name = "osm_rovim_azure" + +README = """ +=========== +osm-rovim_azure +=========== + +osm-ro pluging for azure VIM +""" + +setup( + name=_name, + description='OSM ro vim plugin for azure', + long_description=README, + version_command=('git describe --match v* --tags --long --dirty', 'pep440-git-full'), + # version=VERSION, + # python_requires='>3.5.0', + author='ETSI OSM', + author_email='alfonso.tiernosepulveda@telefonica.com', + maintainer='Alfonso Tierno', + maintainer_email='alfonso.tiernosepulveda@telefonica.com', + url='https://osm.etsi.org/gitweb/?p=osm/RO.git;a=summary', + license='Apache 2.0', + + packages=[_name], + include_package_data=True, + dependency_links=["git+https://osm.etsi.org/gerrit/osm/RO.git#egg=osm-ro"], + install_requires=["requests", "netaddr", "PyYAML", "azure", "osm-ro"], + setup_requires=['setuptools-version-command'], + entry_points={ + 'osm_rovim.plugins': ['rovim_azure = osm_rovim_azure.vimconn_azure'], + }, +) diff --git a/RO-VIM-azure/stdeb.cfg b/RO-VIM-azure/stdeb.cfg new file mode 100644 index 00000000..968c55e1 --- /dev/null +++ b/RO-VIM-azure/stdeb.cfg @@ -0,0 +1,19 @@ +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +# implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +[DEFAULT] +X-Python3-Version : >= 3.5 +Depends3: python3-requests, python3-netaddr, python3-yaml, python3-osm-ro, python3-pip + diff --git a/RO-VIM-azure/tox.ini b/RO-VIM-azure/tox.ini new file mode 100644 index 00000000..9bc1472c --- /dev/null +++ b/RO-VIM-azure/tox.ini @@ -0,0 +1,41 @@ +## +# 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. +## + +[tox] +envlist = py3 +toxworkdir={homedir}/.tox + +[testenv] +basepython = python3 +install_command = python3 -m pip install -r requirements.txt -U {opts} {packages} +# deps = -r{toxinidir}/test-requirements.txt +commands=python3 -m unittest discover -v + +[testenv:flake8] +basepython = python3 +deps = flake8 +commands = flake8 osm_rovim_azure --max-line-length 120 \ + --exclude .svn,CVS,.gz,.git,__pycache__,.tox,local,temp --ignore W291,W293,E226,W504 + +[testenv:unittest] +basepython = python3 +commands = python3 -m unittest osm_rovim_azure.tests + +[testenv:build] +basepython = python3 +deps = stdeb + setuptools-version-command +commands = python3 setup.py --command-packages=stdeb.command bdist_deb + diff --git a/RO-VIM-fos/Makefile b/RO-VIM-fos/Makefile new file mode 100644 index 00000000..26934532 --- /dev/null +++ b/RO-VIM-fos/Makefile @@ -0,0 +1,24 @@ +## +# 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. +## + +all: clean package + +clean: + rm -rf dist deb_dist osm_rovim_fos-*.tar.gz osm_rovim_fos.egg-info .eggs + +package: + python3 setup.py --command-packages=stdeb.command sdist_dsc + cp debian/python3-osm-rovim-fos.postinst deb_dist/osm-rovim-fos*/debian/ + cd deb_dist/osm-rovim-fos*/ && dpkg-buildpackage -rfakeroot -uc -us diff --git a/RO-VIM-fos/debian/python3-osm-rovim-fos.postinst b/RO-VIM-fos/debian/python3-osm-rovim-fos.postinst new file mode 100755 index 00000000..744b26fa --- /dev/null +++ b/RO-VIM-fos/debian/python3-osm-rovim-fos.postinst @@ -0,0 +1,24 @@ +#!/bin/bash + +## +# 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. +# +# For those usages not covered by the Apache License, Version 2.0 please +# contact with: OSM_TECH@list.etsi.org +## + +echo "POST INSTALL OSM-ROVIM-FOS" + +#Pip packages required for vmware connector +python3 -m pip install fog05rest>=0.0.4 + diff --git a/osm_ro/vimconn_fos.py b/RO-VIM-fos/osm_rovim_fos/vimconn_fos.py similarity index 99% rename from osm_ro/vimconn_fos.py rename to RO-VIM-fos/osm_rovim_fos/vimconn_fos.py index fd539ccf..90b0e7ec 100644 --- a/osm_ro/vimconn_fos.py +++ b/RO-VIM-fos/osm_rovim_fos/vimconn_fos.py @@ -37,7 +37,7 @@ __date__ ="$13-may-2019 10:35:12$" import uuid import socket import struct -import vimconn +from . import vimconn import random import yaml from functools import partial diff --git a/RO-VIM-fos/requirements.txt b/RO-VIM-fos/requirements.txt new file mode 100644 index 00000000..d75501b9 --- /dev/null +++ b/RO-VIM-fos/requirements.txt @@ -0,0 +1,21 @@ +## +# 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. +## + +PyYAML +requests +netaddr +fog05rest>=0.0.4 +git+https://osm.etsi.org/gerrit/osm/RO.git#egg=osm-ro + diff --git a/RO-VIM-fos/setup.py b/RO-VIM-fos/setup.py new file mode 100644 index 00000000..95d97ca3 --- /dev/null +++ b/RO-VIM-fos/setup.py @@ -0,0 +1,55 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- + +## +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +# implied. +# See the License for the specific language governing permissions and +# limitations under the License. +## + +from setuptools import setup + +_name = "osm_rovim_fos" + +README = """ +=========== +osm-rovim_fos +=========== + +osm-ro pluging for fos VIM +""" + +setup( + name=_name, + description='OSM ro vim plugin for fos', + long_description=README, + version_command=('git describe --match v* --tags --long --dirty', 'pep440-git-full'), + # version=VERSION, + # python_requires='>3.5.0', + author='ETSI OSM', + # TODO py3 author_email='', + maintainer='OSM_TECH@LIST.ETSI.ORG', # TODO py3 + # TODO py3 maintainer_email='', + url='https://osm.etsi.org/gitweb/?p=osm/RO.git;a=summary', + license='Apache 2.0', + + packages=[_name], + include_package_data=True, + dependency_links=["git+https://osm.etsi.org/gerrit/osm/RO.git#egg=osm-ro"], + install_requires=[ + "requests", "netaddr", "PyYAML", "osm-ro", "fog05rest>=0.0.4" + ], + setup_requires=['setuptools-version-command'], + entry_points={ + 'osm_rovim.plugins': ['rovim_fos = osm_rovim_fos.vimconn_fos'], + }, +) diff --git a/RO-VIM-fos/stdeb.cfg b/RO-VIM-fos/stdeb.cfg new file mode 100644 index 00000000..cf4b3539 --- /dev/null +++ b/RO-VIM-fos/stdeb.cfg @@ -0,0 +1,18 @@ +# +# 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. +# + +[DEFAULT] +X-Python3-Version : >= 3.5 +Depends3: python3-pip, python3-requests, python3-netaddr, python3-yaml, python3-osm-ro diff --git a/RO-VIM-fos/tox.ini b/RO-VIM-fos/tox.ini new file mode 100644 index 00000000..297800b0 --- /dev/null +++ b/RO-VIM-fos/tox.ini @@ -0,0 +1,41 @@ +## +# 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. +## + +[tox] +envlist = py3 +toxworkdir={homedir}/.tox + +[testenv] +basepython = python3 +install_command = python3 -m pip install -r requirements.txt -U {opts} {packages} +# deps = -r{toxinidir}/test-requirements.txt +commands=python3 -m unittest discover -v + +[testenv:flake8] +basepython = python3 +deps = flake8 +commands = flake8 osm_rovim_fos --max-line-length 120 \ + --exclude .svn,CVS,.gz,.git,__pycache__,.tox,local,temp --ignore W291,W293,E226,W504 + +[testenv:unittest] +basepython = python3 +commands = python3 -m unittest osm_rovim_fos.tests + +[testenv:build] +basepython = python3 +deps = stdeb + setuptools-version-command +commands = python3 setup.py --command-packages=stdeb.command bdist_deb + diff --git a/RO-VIM-opennebula/Makefile b/RO-VIM-opennebula/Makefile new file mode 100644 index 00000000..2ec6a44d --- /dev/null +++ b/RO-VIM-opennebula/Makefile @@ -0,0 +1,26 @@ +## +# Copyright 2017 Telefonica Digital Spain S.L.U. +# 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. +## + +all: clean package + +clean: + rm -rf dist deb_dist osm_rovim_opennebula-*.tar.gz osm_rovim_opennebula.egg-info .eggs + +package: + python3 setup.py --command-packages=stdeb.command sdist_dsc + cp debian/python3-osm-rovim-opennebula.postinst deb_dist/osm-rovim-opennebula*/debian/ + cd deb_dist/osm-rovim-opennebula*/ && dpkg-buildpackage -rfakeroot -uc -us + diff --git a/RO-VIM-opennebula/debian/python3-osm-rovim-opennebula.postinst b/RO-VIM-opennebula/debian/python3-osm-rovim-opennebula.postinst new file mode 100755 index 00000000..27aacc74 --- /dev/null +++ b/RO-VIM-opennebula/debian/python3-osm-rovim-opennebula.postinst @@ -0,0 +1,26 @@ +#!/bin/bash + +## +# 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. +# +# For those usages not covered by the Apache License, Version 2.0 please +# contact with: OSM_TECH@list.etsi.org +## + +echo "POST INSTALL OSM-ROVIM-OPENNEBULA" + +#Pip packages required for opennebula connector +python3 -m pip install -e git+https://github.com/python-oca/python-oca#egg=oca +python3 -m pip install untangle +python3 -m pip install pyone + diff --git a/osm_ro/vimconn_opennebula.py b/RO-VIM-opennebula/osm_rovim_opennebula/vimconn_opennebula.py similarity index 98% rename from osm_ro/vimconn_opennebula.py rename to RO-VIM-opennebula/osm_rovim_opennebula/vimconn_opennebula.py index cf1a8fbc..440b1cb6 100644 --- a/osm_ro/vimconn_opennebula.py +++ b/RO-VIM-opennebula/osm_rovim_opennebula/vimconn_opennebula.py @@ -28,7 +28,7 @@ vimconnector implements all the methods to interact with OpenNebula using the XM __author__ = "Jose Maria Carmona Perez,Juan Antonio Hernando Labajo, Emilio Abraham Garrido Garcia,Alberto Florez " \ "Pages, Andres Pozo Munoz, Santiago Perez Marin, Onlife Networks Telefonica I+D Product Innovation " __date__ = "$13-dec-2017 11:09:29$" -import vimconn +from osm_ro import vimconn import requests import logging import oca @@ -190,12 +190,12 @@ class vimconnector(vimconn.vimconnector): else: index = ip_profile["subnet_address"].find("/") ip_start = ip_profile["subnet_address"][:index] - if "dhcp_count" in ip_profile.keys() and ip_profile["dhcp_count"] is not None: + if "dhcp_count" in ip_profile and ip_profile["dhcp_count"] is not None: size = str(ip_profile["dhcp_count"]) - elif not ("dhcp_count" in ip_profile.keys()) and ip_profile["ip_version"] == "IPv4": + elif "dhcp_count" not in ip_profile and ip_profile["ip_version"] == "IPv4": prefix = ip_profile["subnet_address"][index + 1:] size = int(math.pow(2, 32 - prefix)) - if "dhcp_start_address" in ip_profile.keys() and ip_profile["dhcp_start_address"] is not None: + if "dhcp_start_address" in ip_profile and ip_profile["dhcp_start_address"] is not None: ip_start = str(ip_profile["dhcp_start_address"]) if ip_profile["ip_version"] == "IPv6": ip_prefix_type = "GLOBAL_PREFIX" @@ -254,11 +254,11 @@ class vimconnector(vimconn.vimconnector): one = self._new_one_connection() net_pool = one.vnpool.info(-2, -1, -1).VNET response = [] - if "name" in filter_dict.keys(): + if "name" in filter_dict: network_name_filter = filter_dict["name"] else: network_name_filter = None - if "id" in filter_dict.keys(): + if "id" in filter_dict: network_id_filter = filter_dict["id"] else: network_id_filter = None @@ -450,11 +450,11 @@ class vimconnector(vimconn.vimconnector): one = self._new_one_connection() image_pool = one.imagepool.info(-2, -1, -1).IMAGE images = [] - if "name" in filter_dict.keys(): + if "name" in filter_dict: image_name_filter = filter_dict["name"] else: image_name_filter = None - if "id" in filter_dict.keys(): + if "id" in filter_dict: image_id_filter = filter_dict["id"] else: image_id_filter = None diff --git a/RO-VIM-opennebula/requirements.txt b/RO-VIM-opennebula/requirements.txt new file mode 100644 index 00000000..cd2f8032 --- /dev/null +++ b/RO-VIM-opennebula/requirements.txt @@ -0,0 +1,24 @@ +## +# Copyright 2017 Telefonica Digital Spain S.L.U. +# 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. +## + +PyYAML +requests +netaddr +untangle +pyone +git+https://github.com/python-oca/python-oca#egg=oca +git+https://osm.etsi.org/gerrit/osm/RO.git#egg=osm-ro + diff --git a/RO-VIM-opennebula/setup.py b/RO-VIM-opennebula/setup.py new file mode 100644 index 00000000..c27bca3d --- /dev/null +++ b/RO-VIM-opennebula/setup.py @@ -0,0 +1,54 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- + +## +# Copyright 2017 Telefonica Digital Spain S.L.U. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +# implied. +# See the License for the specific language governing permissions and +# limitations under the License. +## + +from setuptools import setup + +_name = "osm_rovim_opennebula" + +README = """ +=========== +osm-rovim_opennebula +=========== + +osm-ro pluging for opennebula VIM +""" + +setup( + name=_name, + description='OSM ro vim plugin for opennebula', + long_description=README, + version_command=('git describe --match v* --tags --long --dirty', 'pep440-git-full'), + # version=VERSION, + # python_requires='>3.5.0', + author='ETSI OSM', + # TODO py3 author_email='', + maintainer='OSM_TECH@LIST.ETSI.ORG', # TODO py3 + # TODO py3 maintainer_email='', + url='https://osm.etsi.org/gitweb/?p=osm/RO.git;a=summary', + license='Apache 2.0', + + packages=[_name], + include_package_data=True, + dependency_links=["git+https://osm.etsi.org/gerrit/osm/RO.git#egg=osm-ro"], + install_requires=["requests", "netaddr", "PyYAML", "osm-ro",], + setup_requires=['setuptools-version-command'], + entry_points={ + 'osm_rovim.plugins': ['rovim_opennebula = osm_rovim_opennebula.vimconn_opennebula'], + }, +) diff --git a/RO-VIM-opennebula/stdeb.cfg b/RO-VIM-opennebula/stdeb.cfg new file mode 100644 index 00000000..00071bd6 --- /dev/null +++ b/RO-VIM-opennebula/stdeb.cfg @@ -0,0 +1,20 @@ +# +# Copyright 2017 Telefonica Digital Spain S.L.U. +# 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. +# + +[DEFAULT] +X-Python3-Version : >= 3.5 +Depends3: python3-requests, python3-netaddr, python3-yaml, python3-osm-ro, python3-pip + diff --git a/RO-VIM-opennebula/tox.ini b/RO-VIM-opennebula/tox.ini new file mode 100644 index 00000000..6fb9d372 --- /dev/null +++ b/RO-VIM-opennebula/tox.ini @@ -0,0 +1,42 @@ +## +# Copyright 2017 Telefonica Digital Spain S.L.U. +# 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. +## + +[tox] +envlist = py3 +toxworkdir={homedir}/.tox + +[testenv] +basepython = python3 +install_command = python3 -m pip install -r requirements.txt -U {opts} {packages} +# deps = -r{toxinidir}/test-requirements.txt +commands=python3 -m unittest discover -v + +[testenv:flake8] +basepython = python3 +deps = flake8 +commands = flake8 osm_rovim_opennebula --max-line-length 120 \ + --exclude .svn,CVS,.gz,.git,__pycache__,.tox,local,temp --ignore W291,W293,E226,W504 + +[testenv:unittest] +basepython = python3 +commands = python3 -m unittest osm_rovim_opennebula.tests + +[testenv:build] +basepython = python3 +deps = stdeb + setuptools-version-command +commands = python3 setup.py --command-packages=stdeb.command bdist_deb + diff --git a/RO-VIM-openstack/Makefile b/RO-VIM-openstack/Makefile new file mode 100644 index 00000000..dfafea33 --- /dev/null +++ b/RO-VIM-openstack/Makefile @@ -0,0 +1,25 @@ +## +# 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. +## + +all: clean package + +clean: + rm -rf dist deb_dist osm_rovim_openstack-*.tar.gz osm_rovim_openstack.egg-info .eggs + +package: + python3 setup.py --command-packages=stdeb.command sdist_dsc + cp debian/python3-osm-rovim-openstack.postinst deb_dist/osm-rovim-openstack*/debian/ + cd deb_dist/osm-rovim-openstack*/ && dpkg-buildpackage -rfakeroot -uc -us + diff --git a/RO-VIM-openstack/debian/python3-osm-rovim-openstack.postinst b/RO-VIM-openstack/debian/python3-osm-rovim-openstack.postinst new file mode 100755 index 00000000..055d4a5e --- /dev/null +++ b/RO-VIM-openstack/debian/python3-osm-rovim-openstack.postinst @@ -0,0 +1,23 @@ +#!/bin/bash + +## +# 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. +# +# For those usages not covered by the Apache License, Version 2.0 please +# contact with: OSM_TECH@list.etsi.org +## + +echo "POST INSTALL OSM-ROVIM-OPENSTACK" + +#Pip packages required for openstack connector +python3 -m pip install networking-l2gw diff --git a/osm_ro/tests/test_vimconn_openstack.py b/RO-VIM-openstack/osm_rovim_openstack/tests/test_vimconn_openstack.py similarity index 100% rename from osm_ro/tests/test_vimconn_openstack.py rename to RO-VIM-openstack/osm_rovim_openstack/tests/test_vimconn_openstack.py diff --git a/osm_ro/vimconn_openstack.py b/RO-VIM-openstack/osm_rovim_openstack/vimconn_openstack.py similarity index 98% rename from osm_ro/vimconn_openstack.py rename to RO-VIM-openstack/osm_rovim_openstack/vimconn_openstack.py index 4a897a36..1c2b0728 100644 --- a/osm_ro/vimconn_openstack.py +++ b/RO-VIM-openstack/osm_rovim_openstack/vimconn_openstack.py @@ -16,9 +16,6 @@ # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. -# -# For those usages not covered by the Apache License, Version 2.0 please -# contact with: nfvlabs@tid.es ## ''' @@ -35,7 +32,7 @@ to the VIM connector's SFC resources as follows: __author__ = "Alfonso Tierno, Gerardo Garcia, Pablo Montes, xFlow Research, Igor D.C., Eduardo Sousa" __date__ = "$22-sep-2017 23:59:59$" -import vimconn +from osm_ro import vimconn # import json import logging import netaddr @@ -45,7 +42,6 @@ import random import re import copy from pprint import pformat -from types import StringTypes from novaclient import client as nClient, exceptions as nvExceptions from keystoneauth1.identity import v2, v3 @@ -56,7 +52,7 @@ import keystoneclient.v2_0.client as ksClient_v2 from glanceclient import client as glClient import glanceclient.exc as gl1Exceptions from cinderclient import client as cClient -from httplib import HTTPException +from http.client import HTTPException # TODO py3 check that this base exception matches python2 httplib.HTTPException from neutronclient.neutron import client as neClient from neutronclient.common import exceptions as neExceptions from requests.exceptions import ConnectionError @@ -189,16 +185,15 @@ class vimconnector(vimconn.vimconnector): simple representation of the data that cannot be converted back to python is returned. """ - if isinstance(value, StringTypes): + if isinstance(value, str): return value try: return yaml.dump(value, Dumper=SafeDumper, default_flow_style=True, width=256) except yaml.representer.RepresenterError: - self.logger.debug( - 'The following entity cannot be serialized in YAML:' - '\n\n%s\n\n', pformat(value), exc_info=True) + self.logger.debug('The following entity cannot be serialized in YAML:\n\n%s\n\n', pformat(value), + exc_info=True) return str(value) def _reload_connection(self): @@ -399,11 +394,7 @@ class vimconnector(vimconn.vimconnector): def _format_exception(self, exception): '''Transform a keystone, nova, neutron exception into a vimconn exception''' - # Fixing bug 665 https://osm.etsi.org/bugzilla/show_bug.cgi?id=665 - # There are some openstack versions that message error are unicode with non English message_error = exception.message - if isinstance(message_error, unicode): - message_error = message_error.encode("utf") if isinstance(exception, (neExceptions.NetworkNotFoundClient, nvExceptions.NotFound, ksExceptions.NotFound, gl1Exceptions.HTTPNotFound)): @@ -1382,7 +1373,7 @@ class vimconnector(vimconn.vimconnector): if isinstance(floating_network['floating_ip'], str): if ip.get("floating_network_id") != floating_network['floating_ip']: continue - free_floating_ip = ip.get("floating_ip_address") + free_floating_ip = ip["id"] else: if isinstance(floating_network['floating_ip'], str) and \ floating_network['floating_ip'].lower() != "true": @@ -1408,15 +1399,17 @@ class vimconnector(vimconn.vimconnector): try: # self.logger.debug("Creating floating IP") new_floating_ip = self.neutron.create_floatingip(param) - free_floating_ip = new_floating_ip['floatingip']['floating_ip_address'] + free_floating_ip = new_floating_ip['floatingip']['id'] except Exception as e: raise vimconn.vimconnException(type(e).__name__ + ": Cannot create new floating_ip " + str(e), http_code=vimconn.HTTP_Conflict) - fix_ip = floating_network.get('ip') while not assigned: try: - server.add_floating_ip(free_floating_ip, fix_ip) + # the vim_id key contains the neutron.port_id + self.neutron.update_floatingip(free_floating_ip, + {"floatingip": {"port_id": floating_network["vim_id"]}}) + # Using nove is deprecated on nova client 10.0 assigned = True except Exception as e: # openstack need some time after VM creation to asign an IP. So retry if fails @@ -1431,7 +1424,7 @@ class vimconnector(vimconn.vimconnector): except Exception as e: if not floating_network['exit_on_floating_ip_error']: - self.logger.warn("Cannot create floating_ip. %s", str(e)) + self.logger.warning("Cannot create floating_ip. %s", str(e)) continue raise @@ -1766,7 +1759,7 @@ class vimconnector(vimconn.vimconnector): for vlanID_range in self.config.get('dataplane_net_vlan_range'): try: start_vlanid , end_vlanid = map(int, vlanID_range.replace(" ", "").split("-")) - for vlanID in xrange(start_vlanid, end_vlanid + 1): + for vlanID in range(start_vlanid, end_vlanid + 1): if vlanID not in used_vlanIDs: return vlanID except Exception as exp: @@ -1800,7 +1793,7 @@ class vimconnector(vimconn.vimconnector): for vlanID_range in self.config.get('multisegment_vlan_range'): try: start_vlanid , end_vlanid = map(int, vlanID_range.replace(" ", "").split("-")) - for vlanID in xrange(start_vlanid, end_vlanid + 1): + for vlanID in range(start_vlanid, end_vlanid + 1): if vlanID not in used_vlanIDs: return vlanID except Exception as exp: @@ -1949,8 +1942,7 @@ class vimconnector(vimconn.vimconnector): return error_value, error_text def new_classification(self, name, ctype, definition): - self.logger.debug( - 'Adding a new (Traffic) Classification to VIM, named %s', name) + self.logger.debug('Adding a new (Traffic) Classification to VIM, named %s', name) try: new_class = None self._reload_connection() @@ -2017,8 +2009,7 @@ class vimconnector(vimconn.vimconnector): self._format_exception(e) def new_sfi(self, name, ingress_ports, egress_ports, sfc_encap=True): - self.logger.debug( - "Adding a new Service Function Instance to VIM, named '%s'", name) + self.logger.debug("Adding a new Service Function Instance to VIM, named '%s'", name) try: new_sfi = None self._reload_connection() @@ -2053,13 +2044,11 @@ class vimconnector(vimconn.vimconnector): self._format_exception(e) def get_sfi(self, sfi_id): - self.logger.debug( - 'Getting Service Function Instance %s from VIM', sfi_id) + self.logger.debug('Getting Service Function Instance %s from VIM', sfi_id) filter_dict = {"id": sfi_id} sfi_list = self.get_sfi_list(filter_dict) if len(sfi_list) == 0: - raise vimconn.vimconnNotFoundException( - "Service Function Instance '{}' not found".format(sfi_id)) + raise vimconn.vimconnNotFoundException("Service Function Instance '{}' not found".format(sfi_id)) elif len(sfi_list) > 1: raise vimconn.vimconnConflictException( 'Found more than one Service Function Instance ' @@ -2068,8 +2057,7 @@ class vimconnector(vimconn.vimconnector): return sfi def get_sfi_list(self, filter_dict={}): - self.logger.debug("Getting Service Function Instances from " - "VIM filter: '%s'", str(filter_dict)) + self.logger.debug("Getting Service Function Instances from VIM filter: '%s'", str(filter_dict)) try: self._reload_connection() filter_dict_os = filter_dict.copy() @@ -2096,8 +2084,7 @@ class vimconnector(vimconn.vimconnector): self._format_exception(e) def new_sf(self, name, sfis, sfc_encap=True): - self.logger.debug("Adding a new Service Function to VIM, " - "named '%s'", name) + self.logger.debug("Adding a new Service Function to VIM, named '%s'", name) try: new_sf = None self._reload_connection() @@ -2168,8 +2155,7 @@ class vimconnector(vimconn.vimconnector): self._format_exception(e) def new_sfp(self, name, classifications, sfs, sfc_encap=True, spi=None): - self.logger.debug("Adding a new Service Function Path to VIM, " - "named '%s'", name) + self.logger.debug("Adding a new Service Function Path to VIM, named '%s'", name) try: new_sfp = None self._reload_connection() @@ -2211,8 +2197,7 @@ class vimconnector(vimconn.vimconnector): return sfp def get_sfp_list(self, filter_dict={}): - self.logger.debug("Getting Service Function Paths from VIM filter: " - "'%s'", str(filter_dict)) + self.logger.debug("Getting Service Function Paths from VIM filter: '%s'", str(filter_dict)) try: self._reload_connection() filter_dict_os = filter_dict.copy() @@ -2227,8 +2212,7 @@ class vimconnector(vimconn.vimconnector): self._format_exception(e) def delete_sfp(self, sfp_id): - self.logger.debug( - "Deleting Service Function Path '%s' from VIM", sfp_id) + self.logger.debug("Deleting Service Function Path '%s' from VIM", sfp_id) try: self._reload_connection() self.neutron.delete_sfc_port_chain(sfp_id) diff --git a/RO-VIM-openstack/requirements.txt b/RO-VIM-openstack/requirements.txt new file mode 100644 index 00000000..e0cb62f5 --- /dev/null +++ b/RO-VIM-openstack/requirements.txt @@ -0,0 +1,27 @@ +## +# 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. +## + +PyYAML +python-openstackclient +python-neutronclient +requests +netaddr +#TODO py3 networking-l2gw +#TODO py3 python-novaclient +#TODO py3 python-keystoneclient +#TODO py3 python-glanceclient +#TODO py3 python-cinderclient +git+https://osm.etsi.org/gerrit/osm/RO.git#egg=osm-ro + diff --git a/RO-VIM-openstack/setup.py b/RO-VIM-openstack/setup.py new file mode 100644 index 00000000..1b3deba3 --- /dev/null +++ b/RO-VIM-openstack/setup.py @@ -0,0 +1,58 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- + +## +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +# implied. +# See the License for the specific language governing permissions and +# limitations under the License. +## + +from setuptools import setup + +_name = "osm_rovim_openstack" + +README = """ +=========== +osm-rovim_openstack +=========== + +osm-ro pluging for openstack VIM +""" + +setup( + name=_name, + description='OSM ro vim plugin for openstack', + long_description=README, + version_command=('git describe --match v* --tags --long --dirty', 'pep440-git-full'), + # version=VERSION, + # python_requires='>3.5.0', + author='ETSI OSM', + author_email='alfonso.tiernosepulveda@telefonica.com', + maintainer='Alfonso Tierno', + maintainer_email='alfonso.tiernosepulveda@telefonica.com', + url='https://osm.etsi.org/gitweb/?p=osm/RO.git;a=summary', + license='Apache 2.0', + + packages=[_name], + include_package_data=True, + dependency_links=["git+https://osm.etsi.org/gerrit/osm/RO.git#egg=osm-ro"], + install_requires=[ + "python-openstackclient", "python-neutronclient", + "requests", "netaddr", "PyYAML", + "osm-ro", # TODO py3 "networking-l2gw" + # "python-novaclient", "python-keystoneclient", "python-glanceclient", "python-cinderclient", + ], + setup_requires=['setuptools-version-command'], + entry_points={ + 'osm_rovim.plugins': ['rovim_openstack = osm_rovim_openstack.vimconn_openstack'], + }, +) diff --git a/RO-VIM-openstack/stdeb.cfg b/RO-VIM-openstack/stdeb.cfg new file mode 100644 index 00000000..ef5f94d1 --- /dev/null +++ b/RO-VIM-openstack/stdeb.cfg @@ -0,0 +1,20 @@ +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +# implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +[DEFAULT] +X-Python3-Version : >= 3.5 +Depends3: python3-openstackclient, python3-neutronclient, python3-requests, python3-netaddr, python3-yaml, + python3-osm-ro, python3-pip + # TODO py3 python3-networking-l2gw diff --git a/RO-VIM-openstack/tox.ini b/RO-VIM-openstack/tox.ini new file mode 100644 index 00000000..2a677566 --- /dev/null +++ b/RO-VIM-openstack/tox.ini @@ -0,0 +1,41 @@ +## +# 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. +## + +[tox] +envlist = py3 +toxworkdir={homedir}/.tox + +[testenv] +basepython = python3 +install_command = python3 -m pip install -r requirements.txt -U {opts} {packages} +# deps = -r{toxinidir}/test-requirements.txt +commands=python3 -m unittest discover -v + +[testenv:flake8] +basepython = python3 +deps = flake8 +commands = flake8 osm_rovim_openstack --max-line-length 120 \ + --exclude .svn,CVS,.gz,.git,__pycache__,.tox,local,temp --ignore W291,W293,E226,W504 + +[testenv:unittest] +basepython = python3 +commands = python3 -m unittest osm_rovim_openstack.tests + +[testenv:build] +basepython = python3 +deps = stdeb + setuptools-version-command +commands = python3 setup.py --command-packages=stdeb.command bdist_deb + diff --git a/RO-VIM-openvim/Makefile b/RO-VIM-openvim/Makefile new file mode 100644 index 00000000..8c688321 --- /dev/null +++ b/RO-VIM-openvim/Makefile @@ -0,0 +1,24 @@ +## +# 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. +## + +all: clean package + +clean: + rm -rf dist deb_dist osm_rovim_openvim-*.tar.gz osm_rovim_openvim.egg-info .eggs + +package: + python3 setup.py --command-packages=stdeb.command sdist_dsc + cd deb_dist/osm-rovim-openvim*/ && dpkg-buildpackage -rfakeroot -uc -us + diff --git a/osm_ro/vimconn_openvim.py b/RO-VIM-openvim/osm_rovim_openvim/vimconn_openvim.py similarity index 92% rename from osm_ro/vimconn_openvim.py rename to RO-VIM-openvim/osm_rovim_openvim/vimconn_openvim.py index 6f584c5e..c89a3037 100644 --- a/osm_ro/vimconn_openvim.py +++ b/RO-VIM-openvim/osm_rovim_openvim/vimconn_openvim.py @@ -27,16 +27,16 @@ vimconnector implements all the methods to interact with openvim using the openv __author__="Alfonso Tierno, Gerardo Garcia" __date__ ="$26-aug-2014 11:09:29$" -import vimconn +from osm_ro import vimconn import requests import json import yaml import logging import math -from openmano_schemas import id_schema, name_schema, nameshort_schema, description_schema, \ +from osm_ro.openmano_schemas import id_schema, name_schema, nameshort_schema, description_schema, \ vlan1000_schema, integer0_schema from jsonschema import validate as js_v, exceptions as js_e -from urllib import quote +from urllib.parse import quote '''contain the openvim virtual machine status to openmano status''' vmStatus2manoFormat={'ACTIVE':'ACTIVE', @@ -357,9 +357,9 @@ class vimconnector(vimconn.vimconnector): try: tenant_list = vim_response.json()["tenants"] if len(tenant_list) == 0: - raise vimconn.vimconnNotFoundException("No tenant found for name '%s'" % str(self.tenant_name)) + raise vimconn.vimconnNotFoundException("No tenant found for name '{}'".format(self.tenant_name)) elif len(tenant_list) > 1: - raise vimconn.vimconnConflictException ("More that one tenant found for name '%s'" % str(self.tenant_name)) + raise vimconn.vimconnConflictException ("More that one tenant found for name '{}'".format(self.tenant_name)) self.tenant = tenant_list[0]["id"] return self.tenant except Exception as e: @@ -381,7 +381,7 @@ class vimconnector(vimconn.vimconnector): #print "Input data: ", str(client_data) return True, client_data except js_e.ValidationError as exc: - print "validate_in error, jsonschema exception ", exc.message, "at", exc.path + print("validate_in error, jsonschema exception ", exc.message, "at", exc.path) return False, ("validate_in error, jsonschema exception ", exc.message, "at", exc.path) def _remove_extra_items(self, data, schema): @@ -469,7 +469,7 @@ class vimconnector(vimconn.vimconnector): ''' filterquery=[] filterquery_text='' - for k,v in filter_dict.iteritems(): + for k,v in filter_dict.items(): filterquery.append(str(k)+'='+str(v)) if len(filterquery)>0: filterquery_text='?'+ '&'.join(filterquery) @@ -551,7 +551,7 @@ class vimconnector(vimconn.vimconnector): del filter_dict["tenant_id"] filterquery=[] filterquery_text='' - for k,v in filter_dict.iteritems(): + for k,v in filter_dict.items(): filterquery.append(str(k)+'='+str(v)) if len(filterquery)>0: filterquery_text='?'+ '&'.join(filterquery) @@ -635,7 +635,7 @@ class vimconnector(vimconn.vimconnector): if "cores" not in numa and "threads" not in numa and "paired-threads" not in numa: numa["paired-threads"] = new_flavor_dict["vcpus"] if "memory" not in numa: - numa["memory"] = int(math.ceil(new_flavor_dict["ram"]/1024.0)) + numa["memory"] = int(math.ceil(new_flavor_dict["ram"] / 1024.0)) for iface in numa.get("interfaces", ()): if not iface.get("bandwidth"): iface["bandwidth"] = "1 Mbps" @@ -701,7 +701,7 @@ class vimconnector(vimconn.vimconnector): if image_dict.get('description'): new_image_dict['description'] = image_dict['description'] if image_dict.get('metadata'): - new_image_dict['metadata'] = yaml.load(image_dict['metadata']) + new_image_dict['metadata'] = yaml.load(image_dict['metadata'], Loader=yaml.SafeLoader) if image_dict.get('location'): new_image_dict['path'] = image_dict['location'] payload_req = json.dumps({"image":new_image_dict}) @@ -752,9 +752,9 @@ class vimconnector(vimconn.vimconnector): #if r is not None: # self.logger.warn("Warning: remove extra items %s", str(r)) if len(response['images'])==0: - raise vimconn.vimconnNotFoundException("Image not found at VIM with path '%s'", path) + raise vimconn.vimconnNotFoundException("Image not found at VIM with path '{}'".format(path)) elif len(response['images'])>1: - raise vimconn.vimconnConflictException("More than one image found at VIM with path '%s'", path) + raise vimconn.vimconnConflictException("More than one image found at VIM with path '{}'".format(path)) return response['images'][0]['id'] except (requests.exceptions.RequestException, js_e.ValidationError) as e: self._format_request_exception(e) @@ -774,7 +774,7 @@ class vimconnector(vimconn.vimconnector): self._get_my_tenant() filterquery=[] filterquery_text='' - for k,v in filter_dict.iteritems(): + for k,v in filter_dict.items(): filterquery.append(str(k)+'='+str(v)) if len(filterquery)>0: filterquery_text='?'+ '&'.join(filterquery) @@ -796,14 +796,14 @@ class vimconnector(vimconn.vimconnector): self._get_my_tenant() except Exception as e: return -vimconn.HTTP_Not_Found, str(e) - print "VIMConnector: Adding a new VM instance from JSON to VIM" + print("VIMConnector: Adding a new VM instance from JSON to VIM") payload_req = vm_data try: vim_response = requests.post(self.url+'/'+self.tenant+'/servers', headers = self.headers_req, data=payload_req) except requests.exceptions.RequestException as e: - print "new_vminstancefromJSON Exception: ", e.args + print( "new_vminstancefromJSON Exception: ", e.args) return -vimconn.HTTP_Not_Found, str(e.args[0]) - print vim_response + # print vim_response #print vim_response.status_code if vim_response.status_code == 200: #print vim_response.json() @@ -812,16 +812,17 @@ class vimconnector(vimconn.vimconnector): #print http_content if res: r = self._remove_extra_items(http_content, new_image_response_schema) - if r is not None: print "Warning: remove extra items ", r + if r is not None: print("Warning: remove extra items ", r) #print http_content vminstance_id = http_content['server']['id'] - print "Tenant image id: ",vminstance_id + print( "Tenant image id: ",vminstance_id) return vim_response.status_code,vminstance_id else: return -vimconn.HTTP_Bad_Request,http_content else: #print vim_response.text jsonerror = self._format_jsonerror(vim_response) - text = 'Error in VIM "%s": not possible to add new vm instance. HTTP Response: %d. Error: %s' % (self.url, vim_response.status_code, jsonerror) + text = 'Error in VIM "{}": not possible to add new vm instance. HTTP Response: {}. Error: {}'.format( + self.url, vim_response.status_code, jsonerror) #print text return -vim_response.status_code,text @@ -1108,7 +1109,7 @@ class vimconnector(vimconn.vimconnector): and append to the server_dict ''' if type(server_dict) is not dict: - print 'vimconnector.host_vim2gui() ERROR, param server_dict must be a dictionary' + print( 'vimconnector.host_vim2gui() ERROR, param server_dict must be a dictionary') return RAD={} occupation={} @@ -1123,7 +1124,7 @@ class vimconnector(vimconn.vimconnector): RAD_item['cpus']['cores'] = [] RAD_item['cpus']['eligible_cores'] = [] occupation_item['cores']=[] - for _ in range(0, len(numa['cores']) / 2): + for _ in range(0, len(numa['cores']) // 2): RAD_item['cpus']['cores'].append( [] ) for core in numa['cores']: RAD_item['cpus']['cores'][core['core_id']].append(core['thread_id']) @@ -1134,7 +1135,7 @@ class vimconnector(vimconn.vimconnector): occupation_item['ports']={} for iface in numa['interfaces']: RAD_item['ports'][ iface['pci'] ] = 'speed:'+str(iface['Mbps'])+'M' - occupation_item['ports'][ iface['pci'] ] = { 'occupied': str(100*iface['Mbps_consumed'] / iface['Mbps']) + "%" } + occupation_item['ports'][ iface['pci'] ] = { 'occupied': str(100*iface['Mbps_consumed'] // iface['Mbps']) + "%" } RAD[ numa['numa_socket'] ] = RAD_item occupation[ numa['numa_socket'] ] = occupation_item @@ -1148,20 +1149,20 @@ class vimconnector(vimconn.vimconnector): try: vim_response = requests.get(url) except requests.exceptions.RequestException as e: - print "get_hosts_info Exception: ", e.args + print( "get_hosts_info Exception: ", e.args) return -vimconn.HTTP_Not_Found, str(e.args[0]) - print "vim get", url, "response:", vim_response.status_code, vim_response.json() + print("vim get", url, "response:", vim_response.status_code, vim_response.json()) #print vim_response.status_code #print json.dumps(vim_response.json(), indent=4) if vim_response.status_code != 200: - #TODO: get error - print 'vimconnector.get_hosts_info error getting host list %d %s' %(vim_response.status_code, vim_response.json()) + # TODO: get error + print('vimconnector.get_hosts_info error getting host list {} {}'.format(vim_response.status_code, vim_response.json())) return -vim_response.status_code, "Error getting host list" res,hosts = self._format_in(vim_response, get_hosts_response_schema) if res==False: - print "vimconnector.get_hosts_info error parsing GET HOSTS vim response", hosts + print("vimconnector.get_hosts_info error parsing GET HOSTS vim response", hosts) return vimconn.HTTP_Internal_Server_Error, hosts #obtain hosts details hosts_dict={} @@ -1170,15 +1171,15 @@ class vimconnector(vimconn.vimconnector): try: vim_response = requests.get(url) except requests.exceptions.RequestException as e: - print "get_hosts_info Exception: ", e.args + print( "get_hosts_info Exception: ", e.args) return -vimconn.HTTP_Not_Found, str(e.args[0]) - print "vim get", url, "response:", vim_response.status_code, vim_response.json() + print("vim get", url, "response:", vim_response.status_code, vim_response.json()) if vim_response.status_code != 200: - print 'vimconnector.get_hosts_info error getting detailed host %d %s' %(vim_response.status_code, vim_response.json()) + print('vimconnector.get_hosts_info error getting detailed host {} {}'.format(vim_response.status_code, vim_response.json())) continue res,host_detail = self._format_in(vim_response, get_host_detail_response_schema) if res==False: - print "vimconnector.get_hosts_info error parsing GET HOSTS/%s vim response" % host['id'], host_detail + print ("vimconnector.get_hosts_info error parsing GET HOSTS/{} vim response {}".format(host['id']), host_detail) continue #print 'host id '+host['id'], json.dumps(host_detail, indent=4) self.host_vim2gui(host_detail, hosts_dict) @@ -1192,20 +1193,20 @@ class vimconnector(vimconn.vimconnector): try: vim_response = requests.get(url) except requests.exceptions.RequestException as e: - print "get_hosts Exception: ", e.args + print("get_hosts Exception: ", e.args) return -vimconn.HTTP_Not_Found, str(e.args[0]) - print "vim get", url, "response:", vim_response.status_code, vim_response.json() + print("vim get", url, "response:", vim_response.status_code, vim_response.json()) #print vim_response.status_code #print json.dumps(vim_response.json(), indent=4) if vim_response.status_code != 200: #TODO: get error - print 'vimconnector.get_hosts error getting host list %d %s' %(vim_response.status_code, vim_response.json()) + print('vimconnector.get_hosts error getting host list {} {}'.format(vim_response.status_code, vim_response.json())) return -vim_response.status_code, "Error getting host list" res,hosts = self._format_in(vim_response, get_hosts_response_schema) if res==False: - print "vimconnector.get_host error parsing GET HOSTS vim response", hosts + print("vimconnector.get_host error parsing GET HOSTS vim response", hosts) return vimconn.HTTP_Internal_Server_Error, hosts #obtain instances from hosts for host in hosts['hosts']: @@ -1213,15 +1214,15 @@ class vimconnector(vimconn.vimconnector): try: vim_response = requests.get(url) except requests.exceptions.RequestException as e: - print "get_hosts Exception: ", e.args + print("get_hosts Exception: ", e.args) return -vimconn.HTTP_Not_Found, str(e.args[0]) - print "vim get", url, "response:", vim_response.status_code, vim_response.json() + print("vim get", url, "response:", vim_response.status_code, vim_response.json()) if vim_response.status_code != 200: - print 'vimconnector.get_hosts error getting instances at host %d %s' %(vim_response.status_code, vim_response.json()) + print('vimconnector.get_hosts error getting instances at host {} {}'.format(vim_response.status_code, vim_response.json())) continue res,servers = self._format_in(vim_response, get_server_response_schema) if res==False: - print "vimconnector.get_host error parsing GET SERVERS/%s vim response" % host['id'], servers + print("vimconnector.get_host error parsing GET SERVERS/{} vim response {}".format(host['id']), servers) continue #print 'host id '+host['id'], json.dumps(host_detail, indent=4) host['instances'] = servers['servers'] @@ -1233,14 +1234,14 @@ class vimconnector(vimconn.vimconnector): try: vim_response = requests.get(url) except requests.exceptions.RequestException as e: - print "get_processor_rankings Exception: ", e.args + print("get_processor_rankings Exception: ", e.args) return -vimconn.HTTP_Not_Found, str(e.args[0]) - print "vim get", url, "response:", vim_response.status_code, vim_response.json() + print("vim get", url, "response:", vim_response.status_code, vim_response.json()) #print vim_response.status_code #print json.dumps(vim_response.json(), indent=4) if vim_response.status_code != 200: #TODO: get error - print 'vimconnector.get_processor_rankings error getting processor rankings %d %s' %(vim_response.status_code, vim_response.json()) + print('vimconnector.get_processor_rankings error getting processor rankings {} {}'.format(vim_response.status_code, vim_response.json())) return -vim_response.status_code, "Error getting processor rankings" res,rankings = self._format_in(vim_response, get_processor_rankings_response_schema) @@ -1271,14 +1272,14 @@ class vimconnector(vimconn.vimconnector): '''Adds a external port to VIM''' '''Returns the port identifier''' #TODO change to logging exception code policies - print "VIMConnector: Adding a new external port" + print( "VIMConnector: Adding a new external port") payload_req = port_data try: vim_response = requests.post(self.url_admin+'/ports', headers = self.headers_req, data=payload_req) except requests.exceptions.RequestException as e: self.logger.error("new_external_port Exception: ", str(e)) return -vimconn.HTTP_Not_Found, str(e.args[0]) - print vim_response + print( vim_response) #print vim_response.status_code if vim_response.status_code == 200: #print vim_response.json() @@ -1287,16 +1288,17 @@ class vimconnector(vimconn.vimconnector): #print http_content if res: r = self._remove_extra_items(http_content, new_port_response_schema) - if r is not None: print "Warning: remove extra items ", r + if r is not None: print("Warning: remove extra items ", r) #print http_content port_id = http_content['port']['id'] - print "Port id: ",port_id + print("Port id: ",port_id) return vim_response.status_code,port_id else: return -vimconn.HTTP_Bad_Request,http_content else: #print vim_response.text jsonerror = self._format_jsonerror(vim_response) - text = 'Error in VIM "%s": not possible to add new external port. HTTP Response: %d. Error: %s' % (self.url_admin, vim_response.status_code, jsonerror) + text = 'Error in VIM "{}": not possible to add new external port. HTTP Response: {}. Error: {}'.format( + self.url_admin, vim_response.status_code, jsonerror) #print text return -vim_response.status_code,text @@ -1304,7 +1306,7 @@ class vimconnector(vimconn.vimconnector): '''Adds a external network to VIM (shared)''' '''Returns the network identifier''' #TODO change to logging exception code policies - print "VIMConnector: Adding external shared network to VIM (type " + net_type + "): "+ net_name + print("VIMConnector: Adding external shared network to VIM (type " + net_type + "): "+ net_name) payload_req = '{"network":{"name": "' + net_name + '","shared":true,"type": "' + net_type + '"}}' try: @@ -1312,7 +1314,7 @@ class vimconnector(vimconn.vimconnector): except requests.exceptions.RequestException as e: self.logger.error( "new_external_network Exception: ", e.args) return -vimconn.HTTP_Not_Found, str(e.args[0]) - print vim_response + print(vim_response) #print vim_response.status_code if vim_response.status_code == 200: #print vim_response.json() @@ -1321,16 +1323,17 @@ class vimconnector(vimconn.vimconnector): #print http_content if res: r = self._remove_extra_items(http_content, new_network_response_schema) - if r is not None: print "Warning: remove extra items ", r + if r is not None: print("Warning: remove extra items ", r) #print http_content network_id = http_content['network']['id'] - print "Network id: ",network_id + print( "Network id: ",network_id) return vim_response.status_code,network_id else: return -vimconn.HTTP_Bad_Request,http_content else: #print vim_response.text jsonerror = self._format_jsonerror(vim_response) - text = 'Error in VIM "%s": not possible to add new external network. HTTP Response: %d. Error: %s' % (self.url, vim_response.status_code, jsonerror) + text = 'Error in VIM "{}": not possible to add new external network. HTTP Response: {}. Error: {}'.format( + self.url, vim_response.status_code, jsonerror) #print text return -vim_response.status_code,text @@ -1338,7 +1341,7 @@ class vimconnector(vimconn.vimconnector): '''Connects a external port to a network''' '''Returns status code of the VIM response''' #TODO change to logging exception code policies - print "VIMConnector: Connecting external port to network" + print("VIMConnector: Connecting external port to network") payload_req = '{"port":{"network_id":"' + network_id + '"}}' if admin: @@ -1350,9 +1353,9 @@ class vimconnector(vimconn.vimconnector): try: vim_response = requests.put(url +'/ports/'+port_id, headers = self.headers_req, data=payload_req) except requests.exceptions.RequestException as e: - print "connect_port_network Exception: ", e.args + print("connect_port_network Exception: ", e.args) return -vimconn.HTTP_Not_Found, str(e.args[0]) - print vim_response + print(vim_response) #print vim_response.status_code if vim_response.status_code == 200: #print vim_response.json() @@ -1361,17 +1364,18 @@ class vimconnector(vimconn.vimconnector): #print http_content if res: r = self._remove_extra_items(http_content, new_port_response_schema) - if r is not None: print "Warning: remove extra items ", r + if r is not None: print("Warning: remove extra items ", r) #print http_content port_id = http_content['port']['id'] - print "Port id: ",port_id + print("Port id: ",port_id) return vim_response.status_code,port_id else: return -vimconn.HTTP_Bad_Request,http_content else: - print vim_response.text + print(vim_response.text) jsonerror = self._format_jsonerror(vim_response) - text = 'Error in VIM "%s": not possible to connect external port to network. HTTP Response: %d. Error: %s' % (self.url_admin, vim_response.status_code, jsonerror) - print text + text = 'Error in VIM "{}": not possible to connect external port to network. HTTP Response: {}.' \ + ' Error: {}'.format(self.url_admin, vim_response.status_code, jsonerror) + print(text) return -vim_response.status_code,text diff --git a/RO-VIM-openvim/requirements.txt b/RO-VIM-openvim/requirements.txt new file mode 100644 index 00000000..f9797f89 --- /dev/null +++ b/RO-VIM-openvim/requirements.txt @@ -0,0 +1,20 @@ +## +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +# implied. +# See the License for the specific language governing permissions and +# limitations under the License. +## + +PyYAML +requests +netaddr +git+https://osm.etsi.org/gerrit/osm/RO.git#egg=osm-ro + diff --git a/RO-VIM-openvim/setup.py b/RO-VIM-openvim/setup.py new file mode 100644 index 00000000..19ac0ba3 --- /dev/null +++ b/RO-VIM-openvim/setup.py @@ -0,0 +1,55 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- + +## +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +# implied. +# See the License for the specific language governing permissions and +# limitations under the License. +## + +from setuptools import setup + +_name = "osm_rovim_openvim" + +README = """ +=========== +osm-rovim_openvim +=========== + +osm-ro pluging for openvim VIM +""" + +setup( + name=_name, + description='OSM ro vim plugin for openvim', + long_description=README, + version_command=('git describe --match v* --tags --long --dirty', 'pep440-git-full'), + # version=VERSION, + # python_requires='>3.5.0', + author='ETSI OSM', + author_email='alfonso.tiernosepulveda@telefonica.com', + maintainer='Alfonso Tierno', + maintainer_email='alfonso.tiernosepulveda@telefonica.com', + url='https://osm.etsi.org/gitweb/?p=osm/RO.git;a=summary', + license='Apache 2.0', + + packages=[_name], + include_package_data=True, + dependency_links=["git+https://osm.etsi.org/gerrit/osm/RO.git#egg=osm-ro"], + install_requires=[ + "requests", "netaddr", "PyYAML", + ], + setup_requires=['setuptools-version-command'], + entry_points={ + 'osm_rovim.plugins': ['rovim_openvim = osm_rovim_openvim.vimconn_openvim'], + }, +) diff --git a/RO-VIM-openvim/stdeb.cfg b/RO-VIM-openvim/stdeb.cfg new file mode 100644 index 00000000..50f98219 --- /dev/null +++ b/RO-VIM-openvim/stdeb.cfg @@ -0,0 +1,18 @@ +# +# 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. +# + +[DEFAULT] +X-Python3-Version : >= 3.5 +Depends3: python3-requests, python3-netaddr, python3-yaml, python3-osm-ro diff --git a/RO-VIM-openvim/tox.ini b/RO-VIM-openvim/tox.ini new file mode 100644 index 00000000..f17bf9ac --- /dev/null +++ b/RO-VIM-openvim/tox.ini @@ -0,0 +1,41 @@ +## +# 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. +## + +[tox] +envlist = py3 +toxworkdir={homedir}/.tox + +[testenv] +basepython = python3 +install_command = python3 -m pip install -r requirements.txt -U {opts} {packages} +# deps = -r{toxinidir}/test-requirements.txt +commands=python3 -m unittest discover -v + +[testenv:flake8] +basepython = python3 +deps = flake8 +commands = flake8 osm_rovim_openvim --max-line-length 120 \ + --exclude .svn,CVS,.gz,.git,__pycache__,.tox,local,temp --ignore W291,W293,E226,W504 + +[testenv:unittest] +basepython = python3 +commands = python3 -m unittest osm_rovim_openvim.tests + +[testenv:build] +basepython = python3 +deps = stdeb + setuptools-version-command +commands = python3 setup.py --command-packages=stdeb.command bdist_deb + diff --git a/RO-VIM-vmware/Makefile b/RO-VIM-vmware/Makefile new file mode 100644 index 00000000..283afdfb --- /dev/null +++ b/RO-VIM-vmware/Makefile @@ -0,0 +1,26 @@ +## +# Copyright VMware Inc. +# 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. +## + +all: clean package + +clean: + rm -rf dist deb_dist osm_rovim_vmware-*.tar.gz osm_rovim_vmware.egg-info .eggs + +package: + python3 setup.py --command-packages=stdeb.command sdist_dsc + cp debian/python3-osm-rovim-vmware.postinst deb_dist/osm-rovim-vmware*/debian/ + cd deb_dist/osm-rovim-vmware*/ && dpkg-buildpackage -rfakeroot -uc -us + diff --git a/RO-VIM-vmware/debian/python3-osm-rovim-vmware.postinst b/RO-VIM-vmware/debian/python3-osm-rovim-vmware.postinst new file mode 100755 index 00000000..e7ce877e --- /dev/null +++ b/RO-VIM-vmware/debian/python3-osm-rovim-vmware.postinst @@ -0,0 +1,29 @@ +#!/bin/bash + +## +# Copyright VMware Inc. +# 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. +# +# For those usages not covered by the Apache License, Version 2.0 please +# contact with: OSM_TECH@list.etsi.org +## + +echo "POST INSTALL OSM-ROVIM-VMWARE" + +#Pip packages required for vmware connector +python3 -m pip install --upgrade pip +python3 -m pip install --upgrade pyvcloud==19.1.1 +python3 -m pip install --upgrade progressbar +python3 -m pip install --upgrade pyvmomi +# python3 -m pip install --upgrade prettytable +# python3 -m pip install --upgrade pyang pyangbind diff --git a/osm_ro/tests/test_vimconn_vmware.py b/RO-VIM-vmware/osm_rovim_vmware/tests/test_vimconn_vmware.py similarity index 99% rename from osm_ro/tests/test_vimconn_vmware.py rename to RO-VIM-vmware/osm_rovim_vmware/tests/test_vimconn_vmware.py index 89ca36c4..f2ab68c9 100755 --- a/osm_ro/tests/test_vimconn_vmware.py +++ b/RO-VIM-vmware/osm_rovim_vmware/tests/test_vimconn_vmware.py @@ -22,7 +22,7 @@ ## -from osm_ro.vimconn_vmware import vimconnector +from vimconn_vmware import vimconnector from osm_ro.vimconn import vimconnUnexpectedResponse,vimconnNotFoundException,vimconnException from pyvcloud.vcd.client import Client from lxml import etree as lxmlElementTree diff --git a/osm_ro/tests/test_vimconn_vmware_xml_response.py b/RO-VIM-vmware/osm_rovim_vmware/tests/test_vimconn_vmware_xml_response.py similarity index 100% rename from osm_ro/tests/test_vimconn_vmware_xml_response.py rename to RO-VIM-vmware/osm_rovim_vmware/tests/test_vimconn_vmware_xml_response.py diff --git a/osm_ro/vimconn_vmware.py b/RO-VIM-vmware/osm_rovim_vmware/vimconn_vmware.py similarity index 99% rename from osm_ro/vimconn_vmware.py rename to RO-VIM-vmware/osm_rovim_vmware/vimconn_vmware.py index f343eeac..e37c4196 100644 --- a/osm_ro/vimconn_vmware.py +++ b/RO-VIM-vmware/osm_rovim_vmware/vimconn_vmware.py @@ -27,7 +27,7 @@ mbayramov@vmware.com """ from progressbar import Percentage, Bar, ETA, FileTransferSpeed, ProgressBar -import vimconn +from osm_ro import vimconn import os import shutil import subprocess @@ -55,7 +55,7 @@ import logging import json import time import uuid -import httplib +# import httplib #For python3 #import http.client import hashlib @@ -266,7 +266,7 @@ class vimconnector(vimconn.vimconnector): elif index == "config": return self.config else: - raise KeyError("Invalid key '%s'" % str(index)) + raise KeyError("Invalid key '{}'".format(index)) def __setitem__(self, index, value): if index == 'name': @@ -290,7 +290,7 @@ class vimconnector(vimconn.vimconnector): elif index == 'url_admin': self.url_admin = value else: - raise KeyError("Invalid key '%s'" % str(index)) + raise KeyError("Invalid key '{}'".format(index)) def connect_as_admin(self): """ Method connect as pvdc admin user to vCloud director. @@ -446,7 +446,7 @@ class vimconnector(vimconn.vimconnector): raise vimconn.vimconnNotFoundException("Fail to get tenant {}".format(tenant_id)) lxmlroot_respond = lxmlElementTree.fromstring(response.content) - namespaces = {prefix:uri for prefix,uri in lxmlroot_respond.nsmap.iteritems() if prefix} + namespaces = {prefix:uri for prefix,uri in lxmlroot_respond.nsmap.items() if prefix} #For python3 #namespaces = {prefix:uri for prefix,uri in lxmlroot_respond.nsmap.items() if prefix} namespaces["xmlns"]= "http://www.vmware.com/vcloud/v1.5" @@ -976,7 +976,7 @@ class vimconnector(vimconn.vimconnector): raise vimconn.vimconnNotFoundException("Fail to get image {}".format(image_id)) lxmlroot_respond = lxmlElementTree.fromstring(response.content) - namespaces = {prefix:uri for prefix,uri in lxmlroot_respond.nsmap.iteritems() if prefix} + namespaces = {prefix:uri for prefix,uri in lxmlroot_respond.nsmap.items() if prefix} #For python3 #namespaces = {prefix:uri for prefix,uri in lxmlroot_respond.nsmap.items() if prefix} namespaces["xmlns"]= "http://www.vmware.com/vcloud/v1.5" @@ -999,7 +999,7 @@ class vimconnector(vimconn.vimconnector): image_id)) lxmlroot_respond = lxmlElementTree.fromstring(response.content) - namespaces = {prefix:uri for prefix,uri in lxmlroot_respond.nsmap.iteritems() if prefix} + namespaces = {prefix:uri for prefix,uri in lxmlroot_respond.nsmap.items() if prefix} #For python3 #namespaces = {prefix:uri for prefix,uri in lxmlroot_respond.nsmap.items() if prefix} namespaces["xmlns"]= "http://www.vmware.com/vcloud/v1.5" @@ -1168,7 +1168,7 @@ class vimconnector(vimconn.vimconnector): while bytes_transferred < statinfo.st_size: my_bytes = f.read(chunk_bytes) if len(my_bytes) <= chunk_bytes: - headers['Content-Range'] = 'bytes %s-%s/%s' % ( + headers['Content-Range'] = 'bytes {}-{}/{}'.format( bytes_transferred, len(my_bytes) - 1, statinfo.st_size) headers['Content-Length'] = str(len(my_bytes)) response = requests.put(url=hrefvmdk, @@ -1181,7 +1181,7 @@ class vimconnector(vimconn.vimconnector): progress_bar.update(bytes_transferred) else: self.logger.debug( - 'file upload failed with error: [%s] %s' % (response.status_code, + 'file upload failed with error: [{}] {}'.format(response.status_code, response.content)) f.close() @@ -3294,7 +3294,7 @@ class vimconnector(vimconn.vimconnector): org_dict = self.get_org(self.org_uuid) if org_dict and 'networks' in org_dict: org_network_dict = org_dict['networks'] - for net_uuid,net_name in org_network_dict.iteritems(): + for net_uuid,net_name in org_network_dict.items(): #For python3 #for net_uuid,net_name in org_network_dict.items(): if net_name == network_name: @@ -4399,7 +4399,7 @@ class vimconnector(vimconn.vimconnector): return None try: lxmlroot_respond = lxmlElementTree.fromstring(response.content) - namespaces = {prefix:uri for prefix,uri in lxmlroot_respond.nsmap.iteritems() if prefix} + namespaces = {prefix:uri for prefix,uri in lxmlroot_respond.nsmap.items() if prefix} #For python3 #namespaces = {prefix:uri for prefix,uri in lxmlroot_respond.nsmap.items() if prefix} namespaces["xmlns"]= "http://www.vmware.com/vcloud/v1.5" @@ -4843,7 +4843,7 @@ class vimconnector(vimconn.vimconnector): bytexml = bytes(bytearray(response.content, encoding='utf-8')) contentelem = lxmlElementTree.XML(bytexml) - namespaces = {prefix:uri for prefix,uri in contentelem.nsmap.iteritems() if prefix} + namespaces = {prefix:uri for prefix,uri in contentelem.nsmap.items() if prefix} namespaces["xmlns"]= "http://www.vmware.com/vcloud/v1.5" # Find the reservation element in the response @@ -4919,7 +4919,7 @@ class vimconnector(vimconn.vimconnector): bytexml = bytes(bytearray(data, encoding='utf-8')) newelem = lxmlElementTree.XML(bytexml) - namespaces = {prefix: uri for prefix, uri in newelem.nsmap.iteritems() if prefix} + namespaces = {prefix: uri for prefix, uri in newelem.nsmap.items() if prefix} namespaces["xmlns"] = "http://www.vmware.com/vcloud/v1.5" nwcfglist = newelem.findall(".//xmlns:NetworkConfig", namespaces) @@ -5538,7 +5538,7 @@ class vimconnector(vimconn.vimconnector): try: #Find but type & max of instance IDs assigned to disks lxmlroot_respond = lxmlElementTree.fromstring(response.content) - namespaces = {prefix:uri for prefix,uri in lxmlroot_respond.nsmap.iteritems() if prefix} + namespaces = {prefix:uri for prefix,uri in lxmlroot_respond.nsmap.items() if prefix} #For python3 #namespaces = {prefix:uri for prefix,uri in lxmlroot_respond.nsmap.items() if prefix} namespaces["xmlns"]= "http://www.vmware.com/vcloud/v1.5" @@ -6275,9 +6275,7 @@ class vimconnector(vimconn.vimconnector): if "used_vlanIDs" not in self.persistent_info: self.persistent_info["used_vlanIDs"] = {} else: - used_ids = self.persistent_info["used_vlanIDs"].values() - #For python3 - #used_ids = list(self.persistent_info["used_vlanIDs"].values()) + used_ids = list(self.persistent_info["used_vlanIDs"].values()) for vlanID_range in self.config.get('vlanID_range'): start_vlanid , end_vlanid = vlanID_range.split("-") diff --git a/RO-VIM-vmware/requirements.txt b/RO-VIM-vmware/requirements.txt new file mode 100644 index 00000000..af74bad1 --- /dev/null +++ b/RO-VIM-vmware/requirements.txt @@ -0,0 +1,25 @@ +## +# Copyright VMware Inc. +# 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. +## + +PyYAML +requests +netaddr +pyvcloud==19.1.1 +pyvmomi +progressbar +prettytable +# TODO py3 genisoimage +git+https://osm.etsi.org/gerrit/osm/RO.git#egg=osm-ro diff --git a/RO-VIM-vmware/setup.py b/RO-VIM-vmware/setup.py new file mode 100644 index 00000000..193102ec --- /dev/null +++ b/RO-VIM-vmware/setup.py @@ -0,0 +1,58 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- + +## +# Copyright VMware Inc. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +# implied. +# See the License for the specific language governing permissions and +# limitations under the License. +## + +from setuptools import setup + +_name = "osm_rovim_vmware" + +README = """ +=========== +osm-rovim_vmware +=========== + +osm-ro pluging for vmware VIM +""" + +setup( + name=_name, + description='OSM ro vim plugin for vmware', + long_description=README, + version_command=('git describe --match v* --tags --long --dirty', 'pep440-git-full'), + # version=VERSION, + # python_requires='>3.5.0', + author='ETSI OSM', + # TODO py3 author_email='', + maintainer='OSM_TECH@LIST.ETSI.ORG', # TODO py3 + # TODO py3 maintainer_email='', + url='https://osm.etsi.org/gitweb/?p=osm/RO.git;a=summary', + license='Apache 2.0', + + packages=[_name], + include_package_data=True, + dependency_links=["git+https://osm.etsi.org/gerrit/osm/RO.git#egg=osm-ro"], + install_requires=[ + "pyvcloud==19.1.1", "progressbar", "prettytable", "pyvmomi", + "requests", "netaddr", "PyYAML", + "osm-ro", + ], + setup_requires=['setuptools-version-command'], + entry_points={ + 'osm_rovim.plugins': ['rovim_vmware = osm_rovim_vmware.vimconn_vmware'], + }, +) diff --git a/RO-VIM-vmware/stdeb.cfg b/RO-VIM-vmware/stdeb.cfg new file mode 100644 index 00000000..ff50a2f7 --- /dev/null +++ b/RO-VIM-vmware/stdeb.cfg @@ -0,0 +1,20 @@ +## +# Copyright VMware Inc. +# 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. +## + +[DEFAULT] +X-Python3-Version : >= 3.5 +Depends3: python3-requests, python3-netaddr, python3-yaml, python3-osm-ro, python3-pip, + genisoimage, python3-progressbar, python3-prettytable, python3-pyvmomi diff --git a/RO-VIM-vmware/tox.ini b/RO-VIM-vmware/tox.ini new file mode 100644 index 00000000..448b263e --- /dev/null +++ b/RO-VIM-vmware/tox.ini @@ -0,0 +1,42 @@ +## +# Copyright VMware Inc. +# 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. +## + +[tox] +envlist = py3 +toxworkdir={homedir}/.tox + +[testenv] +basepython = python3 +install_command = python3 -m pip install -r requirements.txt -U {opts} {packages} +# deps = -r{toxinidir}/test-requirements.txt +commands=python3 -m unittest discover -v + +[testenv:flake8] +basepython = python3 +deps = flake8 +commands = flake8 osm_rovim_vmware --max-line-length 120 \ + --exclude .svn,CVS,.gz,.git,__pycache__,.tox,local,temp --ignore W291,W293,E226,W504 + +[testenv:unittest] +basepython = python3 +commands = python3 -m unittest osm_rovim_vmware.tests + +[testenv:build] +basepython = python3 +deps = stdeb + setuptools-version-command +commands = python3 setup.py --command-packages=stdeb.command bdist_deb + diff --git a/RO-client/Makefile b/RO-client/Makefile new file mode 100644 index 00000000..e689ad6f --- /dev/null +++ b/RO-client/Makefile @@ -0,0 +1,25 @@ +# Copyright 2018 Telefonica S.A. +# +# 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. + +all: clean package + +clean: + rm -rf dist deb_dist osm_roclient-*.tar.gz osm_roclient.egg-info .eggs + +package: + python3 setup.py --command-packages=stdeb.command sdist_dsc + cp debian/python3-osm-roclient.postinst deb_dist/osm-roclient*/debian/ + cd deb_dist/osm-roclient*/ && dpkg-buildpackage -rfakeroot -uc -us + diff --git a/RO-client/README.rst b/RO-client/README.rst new file mode 100644 index 00000000..0e9c887f --- /dev/null +++ b/RO-client/README.rst @@ -0,0 +1,6 @@ +=========== +osm-roclient +=========== + +osm-roclient is a client for interact with osm-ro server + diff --git a/RO-client/debian/python3-osm-roclient.postinst b/RO-client/debian/python3-osm-roclient.postinst new file mode 100755 index 00000000..27c90440 --- /dev/null +++ b/RO-client/debian/python3-osm-roclient.postinst @@ -0,0 +1,25 @@ +#!/bin/bash + +## +# 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. +## + + +#configure arg-autocomplete for RO-client +su $SUDO_USER -c 'activate-global-python-argcomplete --user' +if ! su $SUDO_USER -c 'grep -q bash_completion.d/python-argcomplete.sh ${HOME}/.bashrc' +then + echo " inserting .bash_completion.d/python-argcomplete.sh execution at .bashrc" + su $SUDO_USER -c 'echo ". ${HOME}/.bash_completion.d/python-argcomplete.sh" >> ~/.bashrc' +fi + diff --git a/openmano b/RO-client/osm_roclient/roclient.py similarity index 83% rename from openmano rename to RO-client/osm_roclient/roclient.py index 13a93da4..0e6d32ce 100755 --- a/openmano +++ b/RO-client/osm_roclient/roclient.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python +#!/usr/bin/env python3 # -*- coding: utf-8 -*- # PYTHON_ARGCOMPLETE_OK @@ -28,8 +28,8 @@ openmano client used to interact with openmano-server (openmanod) """ __author__ = "Alfonso Tierno, Gerardo Garcia, Pablo Montes" __date__ = "$09-oct-2014 09:09:48$" -__version__ = "0.4.24-r534" -version_date = "Nov 2018" +__version__ = "0.5.0" +version_date = "2019-010-04" from argcomplete.completers import FilesCompleter import os @@ -41,24 +41,29 @@ import yaml import logging #from jsonschema import validate as js_v, exceptions as js_e -class ArgumentParserError(Exception): pass -class OpenmanoCLIError(Exception): pass +class ArgumentParserError(Exception): + pass + + +class OpenmanoCLIError(Exception): + pass + class ThrowingArgumentParser(argparse.ArgumentParser): def error(self, message): - print "Error: %s" %message - print + print("Error: {}".format(message)) + print() self.print_usage() #self.print_help() - print - print "Type 'openmano -h' for help" + print() + print("Type 'openmano -h' for help") raise ArgumentParserError def config(args): - print "OPENMANO_HOST: %s" %mano_host - print "OPENMANO_PORT: %s" %mano_port + print("OPENMANO_HOST: {}".format(mano_host)) + print("OPENMANO_PORT: {}".format(mano_port)) if args.n: logger.debug("resolving tenant and datacenter names") mano_tenant_id = "None" @@ -71,21 +76,22 @@ def config(args): mano_wim_name = "None" try: mano_tenant_id = _get_item_uuid("tenants", mano_tenant) - URLrequest = "http://%s:%s/openmano/tenants/%s" %(mano_host, mano_port, mano_tenant_id) + URLrequest = "http://{}:{}/openmano/tenants/{}".format(mano_host, mano_port, mano_tenant_id) mano_response = requests.get(URLrequest) logger.debug("openmano response: %s", mano_response.text ) content = mano_response.json() mano_tenant_name = content["tenant"]["name"] - URLrequest = "http://%s:%s/openmano/%s/datacenters/%s" %(mano_host, mano_port, mano_tenant_id, mano_datacenter) + URLrequest = "http://{}:{}/openmano/{}/datacenters/{}".format(mano_host, mano_port, mano_tenant_id, + mano_datacenter) mano_response = requests.get(URLrequest) - logger.debug("openmano response: %s", mano_response.text ) + logger.debug("openmano response: %s", mano_response.text) content = mano_response.json() if "error" not in content: mano_datacenter_id = content["datacenter"]["uuid"] mano_datacenter_name = content["datacenter"]["name"] # WIM - URLrequest = "http://%s:%s/openmano/%s/wims/%s" % ( + URLrequest = "http://{}:{}/openmano/{}/wims/{}".format( mano_host, mano_port, mano_tenant_id, mano_wim) mano_response = requests.get(URLrequest) logger.debug("openmano response: %s", mano_response.text) @@ -96,49 +102,49 @@ def config(args): except OpenmanoCLIError: pass - print "OPENMANO_TENANT: %s" %mano_tenant - print " Id: %s" %mano_tenant_id - print " Name: %s" %mano_tenant_name - print "OPENMANO_DATACENTER: %s" %str (mano_datacenter) - print " Id: %s" %mano_datacenter_id - print " Name: %s" %mano_datacenter_name + print( "OPENMANO_TENANT: {}".format(mano_tenant)) + print( " Id: {}".format(mano_tenant_id)) + print( " Name: {}".format(mano_tenant_name)) + print( "OPENMANO_DATACENTER: {}".format(mano_datacenter)) + print( " Id: {}".format(mano_datacenter_id)) + print( " Name: {}".format(mano_datacenter_name)) # WIM - print "OPENMANO_WIM: %s" %str (mano_wim) - print " Id: %s" %mano_wim_id - print " Name: %s" %mano_wim_name + print( "OPENMANO_WIM: {}".format( (mano_wim))) + print( " Id: {}".format(mano_wim_id)) + print( " Name: {}".format(mano_wim_name)) else: - print "OPENMANO_TENANT: %s" %mano_tenant - print "OPENMANO_DATACENTER: %s" %str (mano_datacenter) + print("OPENMANO_TENANT: {}".format(mano_tenant)) + print("OPENMANO_DATACENTER: {}".format(mano_datacenter)) # WIM - print "OPENMANO_WIM: %s" %str (mano_wim) + print("OPENMANO_WIM: {}".format(mano_wim)) def _print_verbose(mano_response, verbose_level=0): content = mano_response.json() result = 0 if mano_response.status_code==200 else mano_response.status_code if type(content)!=dict or len(content)!=1: - #print "Non expected format output" - print str(content) + # print("Non expected format output") + print(str(content)) return result - val=content.values()[0] + val = next(iter(content.values())) if type(val)==str: - print val + print(val) return result elif type(val) == list: content_list = val elif type(val)==dict: content_list = [val] else: - #print "Non expected dict/list format output" - print str(content) + # print("Non expected dict/list format output" + print(str(content)) return result - #print content_list + # print(content_list if verbose_level==None: verbose_level=0 if verbose_level >= 3: - print yaml.safe_dump(content, indent=4, default_flow_style=False) + print(yaml.safe_dump(content, indent=4, default_flow_style=False)) return result if mano_response.status_code == 200: @@ -173,35 +179,33 @@ def _print_verbose(mano_response, verbose_level=0): new_line='' if content.get('description'): myoutput += new_line + " Description: {:20}".format(content['description']) - print myoutput + print(myoutput) else: - print content['error']['description'] + print(content['error']['description']) return result def parser_json_yaml(file_name): try: - f = file(file_name, "r") - text = f.read() - f.close() + with open(file_name, "r") as f: + text = f.read() except Exception as e: return (False, str(e)) #Read and parse file if file_name[-5:]=='.yaml' or file_name[-4:]=='.yml' or (file_name[-5:]!='.json' and '\t' not in text): try: - config = yaml.load(text) + config = yaml.load(text, Loader=yaml.SafeLoader) except yaml.YAMLError as exc: error_pos = "" if hasattr(exc, 'problem_mark'): mark = exc.problem_mark - error_pos = " at line:%s column:%s" % (mark.line+1, mark.column+1) + error_pos = " at line:{} column:{}".format(mark.line+1, mark.column+1) return (False, "Error loading file '"+file_name+"' yaml format error" + error_pos) else: #json try: config = json.loads(text) except Exception as e: return (False, "Error loading file '"+file_name+"' json format error " + str(e) ) - return True, config def _load_file_or_yaml(content): @@ -215,7 +219,7 @@ def _load_file_or_yaml(content): if os.path.isfile(content): r,payload = parser_json_yaml(content) if not r: - print payload + print(payload) exit(-1) elif "{" in content or ":" in content: try: @@ -224,23 +228,23 @@ def _load_file_or_yaml(content): error_pos = "" if hasattr(exc, 'problem_mark'): mark = exc.problem_mark - error_pos = " at position: (%s:%s)" % (mark.line+1, mark.column+1) - print "Error loading yaml/json text"+error_pos + error_pos = " at position: ({}:{})".format(mark.line+1, mark.column+1) + print("Error loading yaml/json text"+error_pos) exit (-1) else: - print "'%s' is neither a valid file nor a yaml/json content" % content + print("'{}' is neither a valid file nor a yaml/json content".format(content)) exit(-1) return payload def _get_item_uuid(item, item_name_id, tenant=None): if tenant: - URLrequest = "http://%s:%s/openmano/%s/%s" %(mano_host, mano_port, tenant, item) + URLrequest = "http://{}:{}/openmano/{}/{}".format(mano_host, mano_port, tenant, item) else: - URLrequest = "http://%s:%s/openmano/%s" %(mano_host, mano_port, item) + URLrequest = "http://{}:{}/openmano/{}".format(mano_host, mano_port, item) mano_response = requests.get(URLrequest) logger.debug("openmano response: %s", mano_response.text ) content = mano_response.json() - #print content + # print(content found = 0 for i in content[item]: if i["uuid"] == item_name_id: @@ -252,9 +256,9 @@ def _get_item_uuid(item, item_name_id, tenant=None): uuid = i["uuid"] found += 1 if found == 0: - raise OpenmanoCLIError("No %s found with name/uuid '%s'" %(item[:-1], item_name_id)) + raise OpenmanoCLIError("No {} found with name/uuid '{}'".format(item[:-1], item_name_id)) elif found > 1: - raise OpenmanoCLIError("%d %s found with name '%s'. uuid must be used" %(found, item, item_name_id)) + raise OpenmanoCLIError("{} {} found with name '{}'. uuid must be used".format(found, item, item_name_id)) return uuid # # def check_valid_uuid(uuid): @@ -288,10 +292,11 @@ def _get_wim(wim_name_id = None, tenant = "any"): return _get_item_uuid("wims", wim_name_id, tenant) def vnf_create(args): - #print "vnf-create",args + # print("vnf-create", args) headers_req = {'Accept': 'application/json', 'content-type': 'application/json'} tenant = _get_tenant() myvnf = _load_file_or_yaml(args.file) + api_version = "" if "vnfd:vnfd-catalog" in myvnf or "vnfd-catalog" in myvnf: api_version = "/v3" @@ -313,7 +318,7 @@ def vnf_create(args): if args.name or args.description or args.image_path or args.image_name or args.image_checksum: # TODO, change this for API v3 - # print args.name + # print(args.name try: if args.name: vnfd['name'] = args.name @@ -323,7 +328,7 @@ def vnf_create(args): if args.image_path: index = 0 for image_path_ in args.image_path.split(","): - # print "image-path", image_path_ + # print("image-path", image_path_) if api_version == "/v3": if vdu_list[index].get("image"): vdu_list[index]['image'] = image_path_ @@ -376,7 +381,7 @@ def vnf_create(args): else: vdu_list[index]['image checksum'] = image_checksum_ index += 1 - except (KeyError, TypeError), e: + except (KeyError, TypeError) as e: if str(e) == 'vnf': error_pos= "missing field 'vnf'" elif str(e) == 'name': error_pos= "missing field 'vnf':'name'" elif str(e) == 'description': error_pos= "missing field 'vnf':'description'" @@ -386,44 +391,44 @@ def vnf_create(args): elif str(e) == 'image name': error_pos= "missing field 'vnf':'VNFC'['image name']" elif str(e) == 'image checksum': error_pos= "missing field 'vnf':'VNFC'['image checksum']" else: error_pos="wrong format" - print "Wrong VNF descriptor: " + error_pos + print("Wrong VNF descriptor: " + error_pos) return -1 payload_req = json.dumps(myvnf) - #print payload_req + # print(payload_req URLrequest = "http://{}:{}/openmano{}/{}/{token}".format(mano_host, mano_port, api_version, tenant, token=token) logger.debug("openmano request: %s", payload_req) - mano_response = requests.post(URLrequest, headers = headers_req, data=payload_req) + mano_response = requests.post(URLrequest, headers=headers_req, data=payload_req) logger.debug("openmano response: %s", mano_response.text ) return _print_verbose(mano_response, args.verbose) def vnf_list(args): - #print "vnf-list",args + # print("vnf-list",args if args.all: tenant = "any" else: tenant = _get_tenant() if args.name: toshow = _get_item_uuid("vnfs", args.name, tenant) - URLrequest = "http://%s:%s/openmano/%s/vnfs/%s" %(mano_host, mano_port, tenant, toshow) + URLrequest = "http://{}:{}/openmano/{}/vnfs/{}".format(mano_host, mano_port, tenant, toshow) else: - URLrequest = "http://%s:%s/openmano/%s/vnfs" %(mano_host, mano_port, tenant) + URLrequest = "http://{}:{}/openmano/{}/vnfs".format(mano_host, mano_port, tenant) mano_response = requests.get(URLrequest) logger.debug("openmano response: %s", mano_response.text ) content = mano_response.json() - # print json.dumps(content, indent=4) + # print(json.dumps(content, indent=4) if args.verbose==None: args.verbose=0 result = 0 if mano_response.status_code==200 else mano_response.status_code if mano_response.status_code == 200: if not args.name: if args.verbose >= 3: - print yaml.safe_dump(content, indent=4, default_flow_style=False) + print(yaml.safe_dump(content, indent=4, default_flow_style=False)) return result if len(content['vnfs']) == 0: - print "No VNFs were found." + print("No VNFs were found.") return 404 # HTTP_Not_Found for vnf in content['vnfs']: myoutput = "{:38} {:20}".format(vnf['uuid'], vnf['name']) @@ -431,64 +436,64 @@ def vnf_list(args): myoutput += " osm_id={:20}".format(vnf.get('osm_id')) if args.verbose >= 1: myoutput += " {}".format(vnf['created_at']) - print (myoutput) + print(myoutput) if args.verbose >= 2: - print (" Description: {}".format(vnf['description'])) - # print (" VNF descriptor file: {}".format(vnf['path'])) + print(" Description: {}".format(vnf['description'])) + # print(" VNF descriptor file: {}".format(vnf['path'])) else: if args.verbose: - print yaml.safe_dump(content, indent=4, default_flow_style=False) + print(yaml.safe_dump(content, indent=4, default_flow_style=False)) return result vnf = content['vnf'] - print ("{:38} {:20} osm_id={:20} {:20}".format(vnf['uuid'], vnf['name'], vnf.get('osm_id'), - vnf['created_at'])) - print (" Description: {}".format(vnf['description'])) - # print " VNF descriptor file: %s" %vnf['path'] - print (" VMs:") + print("{:38} {:20} osm_id={:20} {:20}".format(vnf['uuid'], vnf['name'], vnf.get('osm_id'), + vnf['created_at']), end=" ") + print(" Description: {}".format(vnf['description'])) + # print(" VNF descriptor file: {}".format(vnf['path'])) + print(" VMs:") for vm in vnf['VNFC']: - print (" {:20} osm_id={:20} {}".format(vm['name'], vm.get('osm_id'), vm['description'])) + print(" {:20} osm_id={:20} {}".format(vm['name'], vm.get('osm_id'), vm['description'])) if len(vnf['nets']) > 0: - print (" Internal nets:") + print(" Internal nets:") for net in vnf['nets']: - print (" {:20} {}".format(net['name'], net['description'])) + print(" {:20} {}".format(net['name'], net['description'])) if len(vnf['external-connections']) > 0: - print (" External interfaces:") + print(" External interfaces:") for interface in vnf['external-connections']: - print (" {:20} {:20} {:20} {:14}".format( + print(" {:20} {:20} {:20} {:14}".format( interface['external_name'], interface['vm_name'], interface['internal_name'], interface.get('vpci') if interface.get('vpci') else "")) else: - print content['error']['description'] + print(content['error']['description']) if args.verbose: - print yaml.safe_dump(content, indent=4, default_flow_style=False) + print(yaml.safe_dump(content, indent=4, default_flow_style=False)) return result def vnf_delete(args): - #print "vnf-delete",args + # print("vnf-delete",args if args.all: tenant = "any" else: tenant = _get_tenant() todelete = _get_item_uuid("vnfs", args.name, tenant=tenant) if not args.force: - r = raw_input("Delete VNF %s (y/N)? " %(todelete)) + r = input("Delete VNF {} (y/N)? ".format(todelete)) if not (len(r)>0 and r[0].lower()=="y"): return 0 - URLrequest = "http://%s:%s/openmano/%s/vnfs/%s" %(mano_host, mano_port, tenant, todelete) + URLrequest = "http://{}:{}/openmano/{}/vnfs/{}".format(mano_host, mano_port, tenant, todelete) mano_response = requests.delete(URLrequest) logger.debug("openmano response: %s", mano_response.text ) result = 0 if mano_response.status_code==200 else mano_response.status_code content = mano_response.json() - #print json.dumps(content, indent=4) + # print(json.dumps(content, indent=4)) if mano_response.status_code == 200: - print content['result'] + print(content['result']) else: - print content['error']['description'] + print(content['error']['description']) return result def scenario_create(args): - # print "scenario-create",args + # print("scenario-create",args tenant = _get_tenant() headers_req = {'content-type': 'application/yaml'} myscenario = _load_file_or_yaml(args.file) @@ -515,9 +520,9 @@ def scenario_create(args): if args.description: nsd['description'] = args.description payload_req = yaml.safe_dump(myscenario, explicit_start=True, indent=4, default_flow_style=False, tags=False, - encoding='utf-8', allow_unicode=True) + allow_unicode=True) - # print payload_req + # print(payload_req URLrequest = "http://{host}:{port}/openmano{api}/{tenant}/{token}".format( host=mano_host, port=mano_port, api=api_version, tenant=tenant, token=token) logger.debug("openmano request: %s", payload_req) @@ -526,20 +531,20 @@ def scenario_create(args): return _print_verbose(mano_response, args.verbose) def scenario_list(args): - #print "scenario-list",args + # print("scenario-list",args if args.all: tenant = "any" else: tenant = _get_tenant() if args.name: toshow = _get_item_uuid("scenarios", args.name, tenant) - URLrequest = "http://%s:%s/openmano/%s/scenarios/%s" %(mano_host, mano_port, tenant, toshow) + URLrequest = "http://{}:{}/openmano/{}/scenarios/{}".format(mano_host, mano_port, tenant, toshow) else: - URLrequest = "http://%s:%s/openmano/%s/scenarios" %(mano_host, mano_port, tenant) + URLrequest = "http://{}:{}/openmano/{}/scenarios".format(mano_host, mano_port, tenant) mano_response = requests.get(URLrequest) logger.debug("openmano response: %s", mano_response.text ) content = mano_response.json() - #print json.dumps(content, indent=4) + # print(json.dumps(content, indent=4) if args.verbose==None: args.verbose=0 @@ -547,10 +552,10 @@ def scenario_list(args): if mano_response.status_code == 200: if not args.name: if args.verbose >= 3: - print yaml.safe_dump(content, indent=4, default_flow_style=False) + print( yaml.safe_dump(content, indent=4, default_flow_style=False)) return result if len(content['scenarios']) == 0: - print "No scenarios were found." + print( "No scenarios were found.") return 404 #HTTP_Not_Found for scenario in content['scenarios']: myoutput = "{:38} {:20}".format(scenario['uuid'], scenario['name']) @@ -558,23 +563,23 @@ def scenario_list(args): myoutput += " osm_id={:20}".format(scenario.get('osm_id')) if args.verbose >= 1: myoutput += " {}".format(scenario['created_at']) - print (myoutput) + print(myoutput) if args.verbose >=2: - print (" Description: {}".format(scenario['description'])) + print(" Description: {}".format(scenario['description'])) else: if args.verbose: - print yaml.safe_dump(content, indent=4, default_flow_style=False) + print(yaml.safe_dump(content, indent=4, default_flow_style=False)) return result scenario = content['scenario'] - print ("{:38} {:20} osm_id={:20} {:20}".format(scenario['uuid'], scenario['name'], scenario.get('osm_id'), - scenario['created_at'])) - print (" Description: {}".format(scenario['description'])) - print (" VNFs:") + print("{:38} {:20} osm_id={:20} {:20}".format(scenario['uuid'], scenario['name'], scenario.get('osm_id'), + scenario['created_at']), end=" ") + print(" Description: {}".format(scenario['description'])) + print(" VNFs:") for vnf in scenario['vnfs']: - print (" {:38} {:20} vnf_index={} {}".format(vnf['vnf_id'], vnf['name'], vnf.get("member_vnf_index"), + print(" {:38} {:20} vnf_index={} {}".format(vnf['vnf_id'], vnf['name'], vnf.get("member_vnf_index"), vnf['description'])) if len(scenario['nets']) > 0: - print (" nets:") + print(" nets:") for net in scenario['nets']: description = net['description'] if not description: # if description does not exist, description is "-". Valid for external and internal nets. @@ -585,39 +590,39 @@ def scenario_list(args): external = "" if net["external"]: external = " external" - print (" {:20} {:38} {:30}{}{}".format(net['name'], net['uuid'], description, vim_id, external)) + print(" {:20} {:38} {:30}{}{}".format(net['name'], net['uuid'], description, vim_id, external)) else: - print (content['error']['description']) + print(content['error']['description']) if args.verbose: - print yaml.safe_dump(content, indent=4, default_flow_style=False) + print(yaml.safe_dump(content, indent=4, default_flow_style=False)) return result def scenario_delete(args): - #print "scenario-delete",args + # print("scenario-delete",args if args.all: tenant = "any" else: tenant = _get_tenant() todelete = _get_item_uuid("scenarios", args.name, tenant=tenant) if not args.force: - r = raw_input("Delete scenario %s (y/N)? " %(args.name)) + r = input("Delete scenario {} (y/N)? ".format(args.name)) if not (len(r)>0 and r[0].lower()=="y"): return 0 - URLrequest = "http://%s:%s/openmano/%s/scenarios/%s" %(mano_host, mano_port, tenant, todelete) + URLrequest = "http://{}:{}/openmano/{}/scenarios/{}".format(mano_host, mano_port, tenant, todelete) mano_response = requests.delete(URLrequest) logger.debug("openmano response: %s", mano_response.text ) result = 0 if mano_response.status_code==200 else mano_response.status_code content = mano_response.json() - #print json.dumps(content, indent=4) + # print(json.dumps(content, indent=4) if mano_response.status_code == 200: - print content['result'] + print( content['result']) else: - print content['error']['description'] + print( content['error']['description']) return result def scenario_deploy(args): - print "This command is deprecated, use 'openmano instance-scenario-create --scenario %s --name %s' instead!!!" % (args.scenario, args.name) - print + print("This command is deprecated, use 'openmano instance-scenario-create --scenario {} --name {}' instead!!!".format(args.scenario, args.name)) + print() args.file = None args.netmap_use = None args.netmap_create = None @@ -625,7 +630,7 @@ def scenario_deploy(args): args.keypair_auto = None return instance_create(args) -# #print "scenario-deploy",args +# # print("scenario-deploy",args # headers_req = {'content-type': 'application/json'} # action = {} # actionCmd="start" @@ -641,9 +646,9 @@ def scenario_deploy(args): # if args.description: # action[actionCmd]["description"] = args.description # payload_req = json.dumps(action, indent=4) -# #print payload_req +# # print(payload_req # -# URLrequest = "http://%s:%s/openmano/%s/scenarios/%s/action" %(mano_host, mano_port, mano_tenant, args.scenario) +# URLrequest = "http://{}:{}/openmano/{}/scenarios/{}/action".format(mano_host, mano_port, mano_tenant, args.scenario) # logger.debug("openmano request: %s", payload_req) # mano_response = requests.post(URLrequest, headers = headers_req, data=payload_req) # logger.debug("openmano response: %s", mano_response.text ) @@ -652,47 +657,47 @@ def scenario_deploy(args): # # result = 0 if mano_response.status_code==200 else mano_response.status_code # content = mano_response.json() -# #print json.dumps(content, indent=4) +# # print(json.dumps(content, indent=4)) # if args.verbose >= 3: -# print yaml.safe_dump(content, indent=4, default_flow_style=False) +# print(yaml.safe_dump(content, indent=4, default_flow_style=False)) # return result # # if mano_response.status_code == 200: -# myoutput = "%s %s" %(content['uuid'].ljust(38),content['name'].ljust(20)) +# myoutput = "{} {}".format(content['uuid'].ljust(38),content['name'].ljust(20)) # if args.verbose >=1: -# myoutput = "%s %s" %(myoutput, content['created_at'].ljust(20)) +# myoutput = "{} {}".format(myoutput, content['created_at'].ljust(20)) # if args.verbose >=2: -# myoutput = "%s %s %s" %(myoutput, content['description'].ljust(30)) -# print myoutput -# print "" -# print "To check the status, run the following command:" -# print "openmano instance-scenario-list " +# myoutput = "{} {} {}".format(myoutput, content['description'].ljust(30)) +# print(myoutput) +# print("") +# print("To check the status, run the following command:") +# print("openmano instance-scenario-list " # else: -# print content['error']['description'] +# print(content['error']['description']) # return result def scenario_verify(args): - #print "scenario-verify",args + # print("scenario-verify",args) tenant = _get_tenant() headers_req = {'content-type': 'application/json'} action = {} action["verify"] = {} action["verify"]["instance_name"] = "scen-verify-return5" payload_req = json.dumps(action, indent=4) - #print payload_req + # print(payload_req) - URLrequest = "http://%s:%s/openmano/%s/scenarios/%s/action" %(mano_host, mano_port, tenant, args.scenario) + URLrequest = "http://{}:{}/openmano/{}/scenarios/{}/action".format(mano_host, mano_port, tenant, args.scenario) logger.debug("openmano request: %s", payload_req) mano_response = requests.post(URLrequest, headers = headers_req, data=payload_req) logger.debug("openmano response: %s", mano_response.text ) result = 0 if mano_response.status_code==200 else mano_response.status_code content = mano_response.json() - #print json.dumps(content, indent=4) + # print(json.dumps(content, indent=4)) if mano_response.status_code == 200: - print content['result'] + print(content['result']) else: - print content['error']['description'] + print(content['error']['description']) return result def instance_create(args): @@ -721,7 +726,7 @@ def instance_create(args): if args.scenario != None: scenario = args.scenario if not scenario: - print "you must provide a scenario in the file descriptor or with --scenario" + print("you must provide a scenario in the file descriptor or with --scenario") return -1 if isinstance(scenario, str): myInstance["instance"]["scenario"] = _get_item_uuid("scenarios", scenario, tenant) @@ -733,7 +738,7 @@ def instance_create(args): for net_comma in net_comma_list: net_tuple = net_comma.split("=") if len(net_tuple) != 2: - print "error at netmap-use. Expected net-scenario=net-datacenter. (%s)?" % net_comma + print("error at netmap-use. Expected net-scenario=net-datacenter. ({})?".format(net_comma)) return net_scenario = net_tuple[0].strip() net_datacenter = net_tuple[1].strip() @@ -756,7 +761,8 @@ def instance_create(args): net_scenario = net_tuple[0].strip() net_datacenter = net_tuple[1].strip() else: - print "error at netmap-create. Expected net-scenario=net-datacenter or net-scenario. (%s)?" % net_comma + print("error at netmap-create. Expected net-scenario=net-datacenter or net-scenario. ({})?".format( + net_comma)) return if net_scenario not in myInstance["instance"]["networks"]: myInstance["instance"]["networks"][net_scenario] = {} @@ -791,10 +797,10 @@ def instance_create(args): with open(home+'/.ssh/'+file, 'r') as f: keys.append(f.read()) if not keys: - print "Cannot obtain any public ssh key from '{}'. Try not using --keymap-auto".format(home+'/.ssh') + print("Cannot obtain any public ssh key from '{}'. Try not using --keymap-auto".format(home+'/.ssh')) return 1 except Exception as e: - print "Cannot obtain any public ssh key. Error '{}'. Try not using --keymap-auto".format(str(e)) + print("Cannot obtain any public ssh key. Error '{}'. Try not using --keymap-auto".format(str(e))) return 1 if "cloud-config" not in myInstance["instance"]: @@ -807,9 +813,10 @@ def instance_create(args): cloud_config["users"] = [] cloud_config["users"].append({"name": user, "key-pairs": keys }) - payload_req = yaml.safe_dump(myInstance, explicit_start=True, indent=4, default_flow_style=False, tags=False, encoding='utf-8', allow_unicode=True) + payload_req = yaml.safe_dump(myInstance, explicit_start=True, indent=4, default_flow_style=False, tags=False, + allow_unicode=True) logger.debug("openmano request: %s", payload_req) - URLrequest = "http://%s:%s/openmano/%s/instances" %(mano_host, mano_port, tenant) + URLrequest = "http://{}:{}/openmano/{}/instances".format(mano_host, mano_port, tenant) mano_response = requests.post(URLrequest, headers = headers_req, data=payload_req) logger.debug("openmano response: %s", mano_response.text ) if args.verbose==None: @@ -817,9 +824,9 @@ def instance_create(args): result = 0 if mano_response.status_code==200 else mano_response.status_code content = mano_response.json() - #print json.dumps(content, indent=4) + # print(json.dumps(content, indent=4)) if args.verbose >= 3: - print yaml.safe_dump(content, indent=4, default_flow_style=False) + print(yaml.safe_dump(content, indent=4, default_flow_style=False)) return result if mano_response.status_code == 200: @@ -828,26 +835,26 @@ def instance_create(args): myoutput = "{} {:20}".format(myoutput, content['created_at']) if args.verbose >=2: myoutput = "{} {:30}".format(myoutput, content['description']) - print myoutput + print(myoutput) else: - print content['error']['description'] + print(content['error']['description']) return result def instance_scenario_list(args): - #print "instance-scenario-list",args + # print("instance-scenario-list",args) if args.all: tenant = "any" else: tenant = _get_tenant() if args.name: toshow = _get_item_uuid("instances", args.name, tenant) - URLrequest = "http://%s:%s/openmano/%s/instances/%s" %(mano_host, mano_port, tenant, toshow) + URLrequest = "http://{}:{}/openmano/{}/instances/{}".format(mano_host, mano_port, tenant, toshow) else: - URLrequest = "http://%s:%s/openmano/%s/instances" %(mano_host, mano_port, tenant) + URLrequest = "http://{}:{}/openmano/{}/instances".format(mano_host, mano_port, tenant) mano_response = requests.get(URLrequest) logger.debug("openmano response: %s", mano_response.text ) content = mano_response.json() - #print json.dumps(content, indent=4) + # print(json.dumps(content, indent=4) if args.verbose==None: args.verbose=0 @@ -855,57 +862,57 @@ def instance_scenario_list(args): if mano_response.status_code == 200: if not args.name: if args.verbose >= 3: - print yaml.safe_dump(content, indent=4, default_flow_style=False) + print(yaml.safe_dump(content, indent=4, default_flow_style=False)) return result if len(content['instances']) == 0: - print "No scenario instances were found." + print("No scenario instances were found.") return result for instance in content['instances']: myoutput = "{:38} {:20}".format(instance['uuid'], instance['name']) if args.verbose >=1: myoutput = "{} {:20}".format(myoutput, instance['created_at']) - print myoutput + print(myoutput) if args.verbose >=2: - print "Description: %s" %instance['description'] + print("Description: {}".format(instance['description'])) else: if args.verbose: - print yaml.safe_dump(content, indent=4, default_flow_style=False) + print(yaml.safe_dump(content, indent=4, default_flow_style=False)) return result instance = content - print ("{:38} {:20} {:20}".format(instance['uuid'],instance['name'],instance['created_at'])) - print ("Description: %s" %instance['description']) - print ("Template scenario id: {}".format(instance['scenario_id'])) - print ("Template scenario name: {}".format(instance['scenario_name'])) - print ("---------------------------------------") - print ("VNF instances: {}".format(len(instance['vnfs']))) + print("{:38} {:20} {:20}".format(instance['uuid'],instance['name'],instance['created_at'])) + print("Description: {}".format(instance['description'])) + print("Template scenario id: {}".format(instance['scenario_id'])) + print("Template scenario name: {}".format(instance['scenario_name'])) + print("---------------------------------------") + print("VNF instances: {}".format(len(instance['vnfs']))) for vnf in instance['vnfs']: - #print " %s %s Template vnf name: %s Template vnf id: %s" %(vnf['uuid'].ljust(38), vnf['name'].ljust(20), vnf['vnf_name'].ljust(20), vnf['vnf_id'].ljust(38)) - print (" {:38} {:20} Template vnf id: {:38}".format(vnf['uuid'], vnf['vnf_name'], vnf['vnf_id'])) + # print(" {} {} Template vnf name: {} Template vnf id: {}".format(vnf['uuid'].ljust(38), vnf['name'].ljust(20), vnf['vnf_name'].ljust(20), vnf['vnf_id'].ljust(38)) + print(" {:38} {:20} Template vnf id: {:38}".format(vnf['uuid'], vnf['vnf_name'], vnf['vnf_id'])) if len(instance['nets'])>0: - print "---------------------------------------" - print "Internal nets:" + print("---------------------------------------") + print("Internal nets:") for net in instance['nets']: if net['created']: - print (" {:38} {:12} VIM ID: {}".format(net['uuid'], net['status'], net['vim_net_id'])) - print "---------------------------------------" - print "External nets:" + print(" {:38} {:12} VIM ID: {}".format(net['uuid'], net['status'], net['vim_net_id'])) + print("---------------------------------------") + print("External nets:") for net in instance['nets']: if not net['created']: - print (" {:38} {:12} VIM ID: {}".format(net['uuid'], net['status'], net['vim_net_id'])) - print ("---------------------------------------") - print ("VM instances:") + print(" {:38} {:12} VIM ID: {}".format(net['uuid'], net['status'], net['vim_net_id'])) + print("---------------------------------------") + print("VM instances:") for vnf in instance['vnfs']: for vm in vnf['vms']: - print (" {:38} {:20} {:20} {:12} VIM ID: {}".format(vm['uuid'], vnf['vnf_name'], vm['name'], - vm['status'], vm['vim_vm_id'])) + print(" {:38} {:20} {:20} {:12} VIM ID: {}".format(vm['uuid'], vnf['vnf_name'], vm['name'], + vm['status'], vm['vim_vm_id'])) else: - print content['error']['description'] + print(content['error']['description']) if args.verbose: - print yaml.safe_dump(content, indent=4, default_flow_style=False) + print(yaml.safe_dump(content, indent=4, default_flow_style=False)) return result def instance_scenario_status(args): - print "instance-scenario-status" + print("instance-scenario-status") return 0 def instance_scenario_delete(args): @@ -914,21 +921,21 @@ def instance_scenario_delete(args): else: tenant = _get_tenant() todelete = _get_item_uuid("instances", args.name, tenant=tenant) - #print "instance-scenario-delete",args + # print("instance-scenario-delete",args) if not args.force: - r = raw_input("Delete scenario instance %s (y/N)? " %(args.name)) + r = input("Delete scenario instance {} (y/N)? ".format(args.name)) if not (len(r)>0 and r[0].lower()=="y"): return - URLrequest = "http://%s:%s/openmano/%s/instances/%s" %(mano_host, mano_port, tenant, todelete) + URLrequest = "http://{}:{}/openmano/{}/instances/{}".format(mano_host, mano_port, tenant, todelete) mano_response = requests.delete(URLrequest) logger.debug("openmano response: %s", mano_response.text ) result = 0 if mano_response.status_code==200 else mano_response.status_code content = mano_response.json() - #print json.dumps(content, indent=4) + # print(json.dumps(content, indent=4)) if mano_response.status_code == 200: - print content['result'] + print(content['result']) else: - print content['error']['description'] + print(content['error']['description']) return result def get_action(args): @@ -954,7 +961,7 @@ def get_action(args): return _print_verbose(mano_response, args.verbose) def instance_scenario_action(args): - #print "instance-scenario-action", args + # print("instance-scenario-action", args) tenant = _get_tenant() toact = _get_item_uuid("instances", args.name, tenant=tenant) action={} @@ -966,33 +973,33 @@ def instance_scenario_action(args): headers_req = {'content-type': 'application/json'} payload_req = json.dumps(action, indent=4) - URLrequest = "http://%s:%s/openmano/%s/instances/%s/action" %(mano_host, mano_port, tenant, toact) + URLrequest = "http://{}:{}/openmano/{}/instances/{}/action".format(mano_host, mano_port, tenant, toact) logger.debug("openmano request: %s", payload_req) mano_response = requests.post(URLrequest, headers = headers_req, data=payload_req) logger.debug("openmano response: %s", mano_response.text ) result = 0 if mano_response.status_code==200 else mano_response.status_code content = mano_response.json() - # print json.dumps(content, indent=4) + # print(json.dumps(content, indent=4)) if mano_response.status_code == 200: if args.verbose: - print yaml.safe_dump(content, indent=4, default_flow_style=False) + print(yaml.safe_dump(content, indent=4, default_flow_style=False)) return result if "instance_action_id" in content: print("instance_action_id={}".format(content["instance_action_id"])) else: - for uuid,c in content.iteritems(): - print ("{:38} {:20} {:20}".format(uuid, c.get('name'), c.get('description'))) + for uuid,c in content.items(): + print("{:38} {:20} {:20}".format(uuid, c.get('name'), c.get('description'))) else: - print content['error']['description'] + print(content['error']['description']) return result def instance_vnf_list(args): - print "instance-vnf-list" + print("instance-vnf-list") return 0 def instance_vnf_status(args): - print "instance-vnf-status" + print("instance-vnf-status") return 0 def tenant_create(args): @@ -1002,21 +1009,21 @@ def tenant_create(args): tenant_dict["description"] = args.description payload_req = json.dumps( {"tenant": tenant_dict }) - #print payload_req + # print(payload_req) - URLrequest = "http://%s:%s/openmano/tenants" %(mano_host, mano_port) + URLrequest = "http://{}:{}/openmano/tenants".format(mano_host, mano_port) logger.debug("openmano request: %s", payload_req) mano_response = requests.post(URLrequest, headers=headers_req, data=payload_req) logger.debug("openmano response: %s", mano_response.text ) return _print_verbose(mano_response, args.verbose) def tenant_list(args): - #print "tenant-list",args + # print("tenant-list",args) if args.name: toshow = _get_item_uuid("tenants", args.name) - URLrequest = "http://%s:%s/openmano/tenants/%s" %(mano_host, mano_port, toshow) + URLrequest = "http://{}:{}/openmano/tenants/{}".format(mano_host, mano_port, toshow) else: - URLrequest = "http://%s:%s/openmano/tenants" %(mano_host, mano_port) + URLrequest = "http://{}:{}/openmano/tenants".format(mano_host, mano_port) mano_response = requests.get(URLrequest) logger.debug("openmano response: %s", mano_response.text ) if args.verbose==None: @@ -1026,22 +1033,22 @@ def tenant_list(args): return _print_verbose(mano_response, args.verbose) def tenant_delete(args): - #print "tenant-delete",args + # print("tenant-delete",args) todelete = _get_item_uuid("tenants", args.name) if not args.force: - r = raw_input("Delete tenant %s (y/N)? " %(args.name)) + r = input("Delete tenant {} (y/N)? ".format(args.name)) if not (len(r)>0 and r[0].lower()=="y"): return 0 - URLrequest = "http://%s:%s/openmano/tenants/%s" %(mano_host, mano_port, todelete) + URLrequest = "http://{}:{}/openmano/tenants/{}".format(mano_host, mano_port, todelete) mano_response = requests.delete(URLrequest) logger.debug("openmano response: %s", mano_response.text ) result = 0 if mano_response.status_code==200 else mano_response.status_code content = mano_response.json() - #print json.dumps(content, indent=4) + # print(json.dumps(content, indent=4)) if mano_response.status_code == 200: - print content['result'] + print(content['result']) else: - print content['error']['description'] + print(content['error']['description']) return result def datacenter_attach(args): @@ -1063,9 +1070,9 @@ def datacenter_attach(args): payload_req = json.dumps( {"datacenter": datacenter_dict }) - #print payload_req + # print(payload_req) - URLrequest = "http://%s:%s/openmano/%s/datacenters/%s" %(mano_host, mano_port, tenant, datacenter) + URLrequest = "http://{}:{}/openmano/{}/datacenters/{}".format(mano_host, mano_port, tenant, datacenter) logger.debug("openmano request: %s", payload_req) mano_response = requests.post(URLrequest, headers=headers_req, data=payload_req) logger.debug("openmano response: %s", mano_response.text ) @@ -1075,7 +1082,7 @@ def datacenter_attach(args): content = mano_response.json() if "already in use for 'name'" in content['error']['description'] and \ "to database vim_tenants table" in content['error']['description']: - print "Try to specify a different name with --vim-tenant-name" + print("Try to specify a different name with --vim-tenant-name") return result @@ -1100,9 +1107,9 @@ def datacenter_edit_vim_tenant(args): datacenter_dict["config"] = _load_file_or_yaml(args.config) payload_req = json.dumps({"datacenter": datacenter_dict}) - # print payload_req + # print(payload_req) - URLrequest = "http://%s:%s/openmano/%s/datacenters/%s" % (mano_host, mano_port, tenant, datacenter) + URLrequest = "http://{}:{}/openmano/{}/datacenters/{}".format(mano_host, mano_port, tenant, datacenter) logger.debug("openmano request: %s", payload_req) mano_response = requests.put(URLrequest, headers=headers_req, data=payload_req) logger.debug("openmano response: %s", mano_response.text) @@ -1117,16 +1124,16 @@ def datacenter_detach(args): tenant = _get_tenant() datacenter = _get_datacenter(args.name, tenant) headers_req = {'Accept': 'application/json', 'content-type': 'application/json'} - URLrequest = "http://%s:%s/openmano/%s/datacenters/%s" %(mano_host, mano_port, tenant, datacenter) + URLrequest = "http://{}:{}/openmano/{}/datacenters/{}".format(mano_host, mano_port, tenant, datacenter) mano_response = requests.delete(URLrequest, headers=headers_req) logger.debug("openmano response: %s", mano_response.text ) content = mano_response.json() - #print json.dumps(content, indent=4) + # print(json.dumps(content, indent=4)) result = 0 if mano_response.status_code==200 else mano_response.status_code if mano_response.status_code == 200: - print content['result'] + print(content['result']) else: - print content['error']['description'] + print(content['error']['description']) return result def datacenter_create(args): @@ -1148,43 +1155,43 @@ def datacenter_create(args): datacenter_dict['config']['sdn-controller'] = sdn_controller payload_req = json.dumps( {"datacenter": datacenter_dict }) - #print payload_req + # print(payload_req) - URLrequest = "http://%s:%s/openmano/datacenters" %(mano_host, mano_port) + URLrequest = "http://{}:{}/openmano/datacenters".format(mano_host, mano_port) logger.debug("openmano request: %s", payload_req) mano_response = requests.post(URLrequest, headers=headers_req, data=payload_req) logger.debug("openmano response: %s", mano_response.text ) return _print_verbose(mano_response, args.verbose) def datacenter_delete(args): - #print "datacenter-delete",args + # print("datacenter-delete",args) todelete = _get_item_uuid("datacenters", args.name, "any") if not args.force: - r = raw_input("Delete datacenter %s (y/N)? " %(args.name)) + r = input("Delete datacenter {} (y/N)? ".format(args.name)) if not (len(r)>0 and r[0].lower()=="y"): return 0 - URLrequest = "http://%s:%s/openmano/datacenters/%s" %(mano_host, mano_port, todelete) + URLrequest = "http://{}:{}/openmano/datacenters/{}".format(mano_host, mano_port, todelete) mano_response = requests.delete(URLrequest) logger.debug("openmano response: %s", mano_response.text ) result = 0 if mano_response.status_code==200 else mano_response.status_code content = mano_response.json() - #print json.dumps(content, indent=4) + # print(json.dumps(content, indent=4)) if mano_response.status_code == 200: - print content['result'] + print(content['result']) else: - print content['error']['description'] + print(content['error']['description']) return result def datacenter_list(args): - #print "datacenter-list",args + # print("datacenter-list",args) tenant='any' if args.all else _get_tenant() if args.name: toshow = _get_item_uuid("datacenters", args.name, tenant) - URLrequest = "http://%s:%s/openmano/%s/datacenters/%s" %(mano_host, mano_port, tenant, toshow) + URLrequest = "http://{}:{}/openmano/{}/datacenters/{}".format(mano_host, mano_port, tenant, toshow) else: - URLrequest = "http://%s:%s/openmano/%s/datacenters" %(mano_host, mano_port, tenant) + URLrequest = "http://{}:{}/openmano/{}/datacenters".format(mano_host, mano_port, tenant) mano_response = requests.get(URLrequest) logger.debug("openmano response: %s", mano_response.text ) if args.verbose==None: @@ -1206,7 +1213,7 @@ def datacenter_sdn_port_mapping_set(args): payload_req = json.dumps({"sdn_port_mapping": sdn_port_mapping}) # read - URLrequest = "http://%s:%s/openmano/%s/datacenters/%s/sdn_mapping" % (mano_host, mano_port, tenant, datacenter) + URLrequest = "http://{}:{}/openmano/{}/datacenters/{}/sdn_mapping".format(mano_host, mano_port, tenant, datacenter) mano_response = requests.get(URLrequest) logger.debug("openmano response: %s", mano_response.text) port_mapping = mano_response.json() @@ -1215,19 +1222,19 @@ def datacenter_sdn_port_mapping_set(args): raise OpenmanoCLIError("openmano client error: {}".format(port_mapping['error']['description'])) if len(port_mapping["sdn_port_mapping"]["ports_mapping"]) > 0: if not args.force: - r = raw_input("Datacenter %s already contains a port mapping. Overwrite? (y/N)? " % (datacenter)) + r = input("Datacenter {} already contains a port mapping. Overwrite? (y/N)? ".format(datacenter)) if not (len(r) > 0 and r[0].lower() == "y"): return 0 # clear - URLrequest = "http://%s:%s/openmano/%s/datacenters/%s/sdn_mapping" % (mano_host, mano_port, tenant, datacenter) + URLrequest = "http://{}:{}/openmano/{}/datacenters/{}/sdn_mapping".format(mano_host, mano_port, tenant, datacenter) mano_response = requests.delete(URLrequest) logger.debug("openmano response: %s", mano_response.text) if mano_response.status_code != 200: return _print_verbose(mano_response, args.verbose) # set - URLrequest = "http://%s:%s/openmano/%s/datacenters/%s/sdn_mapping" % (mano_host, mano_port, tenant, datacenter) + URLrequest = "http://{}:{}/openmano/{}/datacenters/{}/sdn_mapping".format(mano_host, mano_port, tenant, datacenter) logger.debug("openmano request: %s", payload_req) mano_response = requests.post(URLrequest, headers=headers_req, data=payload_req) logger.debug("openmano response: %s", mano_response.text) @@ -1238,7 +1245,7 @@ def datacenter_sdn_port_mapping_list(args): tenant = _get_tenant() datacenter = _get_datacenter(args.name, tenant) - URLrequest = "http://%s:%s/openmano/%s/datacenters/%s/sdn_mapping" % (mano_host, mano_port, tenant, datacenter) + URLrequest = "http://{}:{}/openmano/{}/datacenters/{}/sdn_mapping".format(mano_host, mano_port, tenant, datacenter) mano_response = requests.get(URLrequest) logger.debug("openmano response: %s", mano_response.text) @@ -1250,11 +1257,11 @@ def datacenter_sdn_port_mapping_clear(args): datacenter = _get_datacenter(args.name, tenant) if not args.force: - r = raw_input("Clean SDN port mapping for datacenter %s (y/N)? " %(datacenter)) + r = input("Clean SDN port mapping for datacenter {} (y/N)? ".format(datacenter)) if not (len(r) > 0 and r[0].lower() == "y"): return 0 - URLrequest = "http://%s:%s/openmano/%s/datacenters/%s/sdn_mapping" % (mano_host, mano_port, tenant, datacenter) + URLrequest = "http://{}:{}/openmano/{}/datacenters/{}/sdn_mapping".format(mano_host, mano_port, tenant, datacenter) mano_response = requests.delete(URLrequest) logger.debug("openmano response: %s", mano_response.text) @@ -1288,9 +1295,9 @@ def sdn_controller_create(args): payload_req = json.dumps({"sdn_controller": controller_dict}) - # print payload_req + # print(payload_req) - URLrequest = "http://%s:%s/openmano/%s/sdn_controllers" % (mano_host, mano_port, tenant) + URLrequest = "http://{}:{}/openmano/{}/sdn_controllers".format(mano_host, mano_port, tenant) logger.debug("openmano request: %s", payload_req) mano_response = requests.post(URLrequest, headers=headers_req, data=payload_req) logger.debug("openmano response: %s", mano_response.text) @@ -1325,14 +1332,14 @@ def sdn_controller_edit(args): raise OpenmanoCLIError("At least one parameter must be edited") if not args.force: - r = raw_input("Update SDN controller {} (y/N)? ".format(args.name)) + r = input("Update SDN controller {} (y/N)? ".format(args.name)) if not (len(r) > 0 and r[0].lower() == "y"): return 0 payload_req = json.dumps({"sdn_controller": controller_dict}) - # print payload_req + # print(payload_req) - URLrequest = "http://%s:%s/openmano/%s/sdn_controllers/%s" % (mano_host, mano_port, tenant, controller_uuid) + URLrequest = "http://{}:{}/openmano/{}/sdn_controllers/{}".format(mano_host, mano_port, tenant, controller_uuid) logger.debug("openmano request: %s", payload_req) mano_response = requests.put(URLrequest, headers=headers_req, data=payload_req) logger.debug("openmano response: %s", mano_response.text) @@ -1346,10 +1353,10 @@ def sdn_controller_list(args): if args.name: toshow = _get_item_uuid("sdn_controllers", args.name, tenant) - URLrequest = "http://%s:%s/openmano/%s/sdn_controllers/%s" %(mano_host, mano_port, tenant, toshow) + URLrequest = "http://{}:{}/openmano/{}/sdn_controllers/{}".format(mano_host, mano_port, tenant, toshow) else: - URLrequest = "http://%s:%s/openmano/%s/sdn_controllers" %(mano_host, mano_port, tenant) - #print URLrequest + URLrequest = "http://{}:{}/openmano/{}/sdn_controllers".format(mano_host, mano_port, tenant) + # print(URLrequest) mano_response = requests.get(URLrequest) logger.debug("openmano response: %s", mano_response.text ) if args.verbose==None: @@ -1366,23 +1373,23 @@ def sdn_controller_delete(args): controller_uuid = _get_item_uuid("sdn_controllers", args.name, tenant) if not args.force: - r = raw_input("Delete SDN controller %s (y/N)? " % (args.name)) + r = input("Delete SDN controller {} (y/N)? ".format(args.name)) if not (len(r) > 0 and r[0].lower() == "y"): return 0 - URLrequest = "http://%s:%s/openmano/%s/sdn_controllers/%s" % (mano_host, mano_port, tenant, controller_uuid) + URLrequest = "http://{}:{}/openmano/{}/sdn_controllers/{}".format(mano_host, mano_port, tenant, controller_uuid) mano_response = requests.delete(URLrequest) logger.debug("openmano response: %s", mano_response.text) return _print_verbose(mano_response, args.verbose) def vim_action(args): - #print "datacenter-net-action",args + # print("datacenter-net-action",args) tenant = _get_tenant() datacenter = _get_datacenter(args.datacenter, tenant) if args.verbose==None: args.verbose=0 if args.action=="list": - URLrequest = "http://%s:%s/openmano/%s/vim/%s/%ss" %(mano_host, mano_port, tenant, datacenter, args.item) + URLrequest = "http://{}:{}/openmano/{}/vim/{}/{}s".format(mano_host, mano_port, tenant, datacenter, args.item) if args.name!=None: args.verbose += 1 URLrequest += "/" + args.name @@ -1390,16 +1397,16 @@ def vim_action(args): logger.debug("openmano response: %s", mano_response.text ) return _print_verbose(mano_response, args.verbose) elif args.action=="delete": - URLrequest = "http://%s:%s/openmano/%s/vim/%s/%ss/%s" %(mano_host, mano_port, tenant, datacenter, args.item, args.name) + URLrequest = "http://{}:{}/openmano/{}/vim/{}/{}s/{}".format(mano_host, mano_port, tenant, datacenter, args.item, args.name) mano_response = requests.delete(URLrequest) logger.debug("openmano response: %s", mano_response.text ) result = 0 if mano_response.status_code==200 else mano_response.status_code content = mano_response.json() - #print json.dumps(content, indent=4) + # print(json.dumps(content, indent=4)) if mano_response.status_code == 200: - print content['result'] + print(content['result']) else: - print content['error']['description'] + print(content['error']['description']) return result elif args.action=="create": headers_req = {'content-type': 'application/yaml'} @@ -1421,11 +1428,12 @@ def vim_action(args): if args.shared: create_dict[args.item]['shared'] = args.shared if "name" not in create_dict[args.item]: - print "You must provide a name in the descriptor file or with the --name option" + print("You must provide a name in the descriptor file or with the --name option") return - payload_req = yaml.safe_dump(create_dict, explicit_start=True, indent=4, default_flow_style=False, tags=False, encoding='utf-8', allow_unicode=True) + payload_req = yaml.safe_dump(create_dict, explicit_start=True, indent=4, default_flow_style=False, tags=False, + allow_unicode=True) logger.debug("openmano request: %s", payload_req) - URLrequest = "http://%s:%s/openmano/%s/vim/%s/%ss" %(mano_host, mano_port, tenant, datacenter, args.item) + URLrequest = "http://{}:{}/openmano/{}/vim/{}/{}s".format(mano_host, mano_port, tenant, datacenter, args.item) mano_response = requests.post(URLrequest, headers = headers_req, data=payload_req) logger.debug("openmano response: %s", mano_response.text ) if args.verbose==None: @@ -1434,7 +1442,7 @@ def vim_action(args): def _get_items(item, item_name_id=None, datacenter=None, tenant=None): - URLrequest = "http://%s:%s/openmano" %(mano_host, mano_port) + URLrequest = "http://{}:{}/openmano".format(mano_host, mano_port) if tenant: URLrequest += "/" + tenant if datacenter: @@ -1469,7 +1477,7 @@ def vim_net_sdn_attach(args): if args.mac: payload_req['mac'] = args.mac - URLrequest = "http://%s:%s/openmano/%s/vim/%s/network/%s/attach" % (mano_host, mano_port, tenant, datacenter, network_uuid) + URLrequest = "http://{}:{}/openmano/{}/vim/{}/network/{}/attach".format(mano_host, mano_port, tenant, datacenter, network_uuid) logger.debug("openmano request: %s", payload_req) mano_response = requests.post(URLrequest, headers=headers_req, data=json.dumps(payload_req)) logger.debug("openmano response: %s", mano_response.text) @@ -1479,7 +1487,7 @@ def vim_net_sdn_attach(args): def vim_net_sdn_detach(args): if not args.all and not args.id: - print "--all or --id must be used" + print("--all or --id must be used") return 1 # Verify the network exists in the vim @@ -1494,15 +1502,15 @@ def vim_net_sdn_detach(args): network_uuid = content['network']['id'] if not args.force: - r = raw_input("Confirm action' (y/N)? ") + r = input("Confirm action' (y/N)? ") if len(r) == 0 or r[0].lower() != "y": return 0 if args.id: - URLrequest = "http://%s:%s/openmano/%s/vim/%s/network/%s/detach/%s" % ( + URLrequest = "http://{}:{}/openmano/{}/vim/{}/network/{}/detach/{}".format( mano_host, mano_port, tenant, datacenter, network_uuid, args.id) else: - URLrequest = "http://%s:%s/openmano/%s/vim/%s/network/%s/detach" % ( + URLrequest = "http://{}:{}/openmano/{}/vim/{}/network/{}/detach".format( mano_host, mano_port, tenant, datacenter, network_uuid) mano_response = requests.delete(URLrequest) logger.debug("openmano response: %s", mano_response.text) @@ -1512,8 +1520,9 @@ def vim_net_sdn_detach(args): def datacenter_net_action(args): if args.action == "net-update": - print "This command is deprecated, use 'openmano datacenter-netmap-delete --all' and 'openmano datacenter-netmap-import' instead!!!" - print + print("This command is deprecated, use 'openmano datacenter-netmap-delete --all' and 'openmano" + " datacenter-netmap-import' instead!!!") + print() args.action = "netmap-delete" args.netmap = None args.all = True @@ -1536,19 +1545,19 @@ def datacenter_net_action(args): args.action = "netmap" + args.action[3:] args.vim_name=None args.vim_id=None - print "This command is deprecated, use 'openmano datacenter-%s' instead!!!" % args.action - print + print("This command is deprecated, use 'openmano datacenter-{}' instead!!!".format(args.action)) + print() return datacenter_netmap_action(args) def datacenter_netmap_action(args): tenant = _get_tenant() datacenter = _get_datacenter(args.datacenter, tenant) - #print "datacenter_netmap_action",args + # print("datacenter_netmap_action",args) payload_req = None if args.verbose==None: args.verbose=0 headers_req = {'Accept': 'application/json', 'content-type': 'application/json'} - URLrequest = "http://%s:%s/openmano/%s/datacenters/%s/netmaps" %(mano_host, mano_port, tenant, datacenter) + URLrequest = "http://{}:{}/openmano/{}/datacenters/{}/netmaps".format(mano_host, mano_port, tenant, datacenter) if args.action=="netmap-list": if args.netmap: @@ -1558,18 +1567,18 @@ def datacenter_netmap_action(args): elif args.action=="netmap-delete": if args.netmap and args.all: - print "you can not use a netmap name and the option --all at the same time" + print("you can not use a netmap name and the option --all at the same time") return 1 if args.netmap: - force_text= "Delete default netmap '%s' from datacenter '%s' (y/N)? " % (args.netmap, datacenter) + force_text= "Delete default netmap '{}' from datacenter '{}' (y/N)? ".format(args.netmap, datacenter) URLrequest += "/" + args.netmap elif args.all: - force_text="Delete all default netmaps from datacenter '%s' (y/N)? " % (datacenter) + force_text="Delete all default netmaps from datacenter '{}' (y/N)? ".format(datacenter) else: - print "you must specify a netmap name or the option --all" + print("you must specify a netmap name or the option --all") return 1 if not args.force: - r = raw_input(force_text) + r = input(force_text) if len(r)>0 and r[0].lower()=="y": pass else: @@ -1577,7 +1586,7 @@ def datacenter_netmap_action(args): mano_response = requests.delete(URLrequest, headers=headers_req) elif args.action=="netmap-import": if not args.force: - r = raw_input("Create all the available networks from datacenter '%s' as default netmaps (y/N)? " % (datacenter)) + r = input("Create all the available networks from datacenter '{}' as default netmaps (y/N)? ".format(datacenter)) if len(r)>0 and r[0].lower()=="y": pass else: @@ -1602,9 +1611,9 @@ def datacenter_netmap_action(args): if args.action=="netmap-edit" and not args.force: if len(payload["netmap"]) == 0: - print "You must supply some parameter to edit" + print("You must supply some parameter to edit") return 1 - r = raw_input("Edit default netmap '%s' from datacenter '%s' (y/N)? " % (args.netmap, datacenter)) + r = input("Edit default netmap '{}' from datacenter '{}' (y/N)? ".format(args.netmap, datacenter)) if len(r)>0 and r[0].lower()=="y": pass else: @@ -1613,7 +1622,8 @@ def datacenter_netmap_action(args): mano_response = requests.put(URLrequest, headers=headers_req, data=payload_req) else: #netmap-create if "vim_name" not in payload["netmap"] and "vim_id" not in payload["netmap"]: - print "You must supply either --vim-id or --vim-name option; or include one of them in the file descriptor" + print("You must supply either --vim-id or --vim-name option; or include one of them in the file" + " descriptor") return 1 mano_response = requests.post(URLrequest, headers=headers_req, data=payload_req) @@ -1624,15 +1634,15 @@ def datacenter_netmap_action(args): def element_edit(args): element = _get_item_uuid(args.element, args.name) headers_req = {'Accept': 'application/json', 'content-type': 'application/json'} - URLrequest = "http://%s:%s/openmano/%s/%s" %(mano_host, mano_port, args.element, element) + URLrequest = "http://{}:{}/openmano/{}/{}".format(mano_host, mano_port, args.element, element) payload=_load_file_or_yaml(args.file) if args.element[:-1] not in payload: payload = {args.element[:-1]: payload } payload_req = json.dumps(payload) - #print payload_req + # print(payload_req) if not args.force or (args.name==None and args.filer==None): - r = raw_input(" Edit " + args.element[:-1] + " " + args.name + " (y/N)? ") + r = input(" Edit " + args.element[:-1] + " " + args.name + " (y/N)? ") if len(r)>0 and r[0].lower()=="y": pass else: @@ -1651,7 +1661,7 @@ def datacenter_edit(args): tenant = _get_tenant() element = _get_item_uuid('datacenters', args.name, tenant) headers_req = {'Accept': 'application/json', 'content-type': 'application/json'} - URLrequest = "http://%s:%s/openmano/datacenters/%s" % (mano_host, mano_port, element) + URLrequest = "http://{}:{}/openmano/datacenters/{}".format(mano_host, mano_port, element) has_arguments = False if args.file != None: @@ -1678,9 +1688,9 @@ def datacenter_edit(args): payload = {'datacenter': payload} payload_req = json.dumps(payload) - # print payload_req + # print(payload_req) if not args.force or (args.name == None and args.filer == None): - r = raw_input(" Edit datacenter " + args.name + " (y/N)? ") + r = input(" Edit datacenter " + args.name + " (y/N)? ") if len(r) > 0 and r[0].lower() == "y": pass else: @@ -1713,7 +1723,7 @@ def wim_account_create(args): payload_req = json.dumps({"wim_account": wim_dict}) - URLrequest = "http://%s:%s/openmano/%s/wims/%s" % (mano_host, mano_port, tenant, wim) + URLrequest = "http://{}:{}/openmano/{}/wims/{}".format(mano_host, mano_port, tenant, wim) logger.debug("openmano request: %s", payload_req) mano_response = requests.post(URLrequest, headers=headers_req, data=payload_req) logger.debug("openmano response: %s", mano_response.text) @@ -1723,7 +1733,7 @@ def wim_account_create(args): content = mano_response.json() if "already in use for 'name'" in content['error']['description'] and \ "to database wim_tenants table" in content['error']['description']: - print "Try to specify a different name with --wim-tenant-name" + print("Try to specify a different name with --wim-tenant-name") return result @@ -1734,16 +1744,16 @@ def wim_account_delete(args): tenant = _get_tenant() wim = _get_wim(args.name, tenant) headers_req = {'Accept': 'application/json', 'content-type': 'application/json'} - URLrequest = "http://%s:%s/openmano/%s/wims/%s" % (mano_host, mano_port, tenant, wim) + URLrequest = "http://{}:{}/openmano/{}/wims/{}".format(mano_host, mano_port, tenant, wim) mano_response = requests.delete(URLrequest, headers=headers_req) logger.debug("openmano response: %s", mano_response.text) content = mano_response.json() - # print json.dumps(content, indent=4) + # print(json.dumps(content, indent=4)) result = 0 if mano_response.status_code == 200 else mano_response.status_code if mano_response.status_code == 200: - print content['result'] + print(content['result']) else: - print content['error']['description'] + print(content['error']['description']) return result @@ -1764,9 +1774,9 @@ def wim_account_edit(args): payload_req = json.dumps({"wim_account": wim_dict}) - # print payload_req + # print(payload_req) - URLrequest = "http://%s:%s/openmano/%s/wims/%s" % (mano_host, mano_port, tenant, wim) + URLrequest = "http://{}:{}/openmano/{}/wims/{}".format(mano_host, mano_port, tenant, wim) logger.debug("openmano request: %s", payload_req) mano_response = requests.post(URLrequest, headers=headers_req, data=payload_req) logger.debug("openmano response: %s", mano_response.text) @@ -1776,7 +1786,7 @@ def wim_account_edit(args): content = mano_response.json() if "already in use for 'name'" in content['error']['description'] and \ "to database wim_tenants table" in content['error']['description']: - print "Try to specify a different name with --wim-tenant-name" + print("Try to specify a different name with --wim-tenant-name") return result def wim_create(args): @@ -1791,7 +1801,7 @@ def wim_create(args): payload_req = json.dumps({"wim": wim_dict}) - URLrequest = "http://%s:%s/openmano/wims" % (mano_host, mano_port) + URLrequest = "http://{}:{}/openmano/wims".format(mano_host, mano_port) logger.debug("openmano request: %s", payload_req) mano_response = requests.post(URLrequest, headers=headers_req, data=payload_req) logger.debug("openmano response: %s", mano_response.text) @@ -1802,7 +1812,7 @@ def wim_edit(args): tenant = _get_tenant() element = _get_item_uuid('wims', args.name, tenant) headers_req = {'Accept': 'application/json', 'content-type': 'application/json'} - URLrequest = "http://%s:%s/openmano/wims/%s" % (mano_host, mano_port, element) + URLrequest = "http://{}:{}/openmano/wims/{}".format(mano_host, mano_port, element) has_arguments = False if args.file != None: @@ -1818,9 +1828,9 @@ def wim_edit(args): payload = {'wim': payload} payload_req = json.dumps(payload) - # print payload_req + # print(payload_req) if not args.force or (args.name == None and args.filer == None): - r = raw_input(" Edit wim " + args.name + " (y/N)? ") + r = input(" Edit wim " + args.name + " (y/N)? ") if len(r) > 0 and r[0].lower() == "y": pass else: @@ -1836,34 +1846,34 @@ def wim_edit(args): def wim_delete(args): - # print "wim-delete",args + # print("wim-delete",args) todelete = _get_item_uuid("wims", args.name, "any") if not args.force: - r = raw_input("Delete wim %s (y/N)? " % (args.name)) + r = input("Delete wim {} (y/N)? ".format(args.name)) if not (len(r) > 0 and r[0].lower() == "y"): return 0 - URLrequest = "http://%s:%s/openmano/wims/%s" % (mano_host, mano_port, todelete) + URLrequest = "http://{}:{}/openmano/wims/{}".format(mano_host, mano_port, todelete) mano_response = requests.delete(URLrequest) logger.debug("openmano response: %s", mano_response.text) result = 0 if mano_response.status_code == 200 else mano_response.status_code content = mano_response.json() - # print json.dumps(content, indent=4) + # print(json.dumps(content, indent=4) if mano_response.status_code == 200: - print content['result'] + print(content['result']) else: - print content['error']['description'] + print(content['error']['description']) return result def wim_list(args): - # print "wim-list",args + # print("wim-list",args) tenant = 'any' if args.all else _get_tenant() if args.name: toshow = _get_item_uuid("wims", args.name, tenant) - URLrequest = "http://%s:%s/openmano/%s/wims/%s" % (mano_host, mano_port, tenant, toshow) + URLrequest = "http://{}:{}/openmano/{}/wims/{}".format(mano_host, mano_port, tenant, toshow) else: - URLrequest = "http://%s:%s/openmano/%s/wims" % (mano_host, mano_port, tenant) + URLrequest = "http://{}:{}/openmano/{}/wims".format(mano_host, mano_port, tenant) mano_response = requests.get(URLrequest) logger.debug("openmano response: %s", mano_response.text) if args.verbose == None: @@ -1886,7 +1896,7 @@ def wim_port_mapping_set(args): payload_req = json.dumps({"wim_port_mapping": wim_port_mapping}) # read - URLrequest = "http://%s:%s/openmano/%s/wims/%s/port_mapping" % (mano_host, mano_port, tenant, wim) + URLrequest = "http://{}:{}/openmano/{}/wims/{}/port_mapping".format(mano_host, mano_port, tenant, wim) mano_response = requests.get(URLrequest) logger.debug("openmano response: %s", mano_response.text) port_mapping = mano_response.json() @@ -1897,19 +1907,19 @@ def wim_port_mapping_set(args): # TODO: check this if statement if len(port_mapping["wim_port_mapping"]) > 0: if not args.force: - r = raw_input("WIM %s already contains a port mapping. Overwrite? (y/N)? " % (wim)) + r = input("WIM {} already contains a port mapping. Overwrite? (y/N)? ".format(wim)) if not (len(r) > 0 and r[0].lower() == "y"): return 0 # clear - URLrequest = "http://%s:%s/openmano/%s/wims/%s/port_mapping" % (mano_host, mano_port, tenant, wim) + URLrequest = "http://{}:{}/openmano/{}/wims/{}/port_mapping".format(mano_host, mano_port, tenant, wim) mano_response = requests.delete(URLrequest) logger.debug("openmano response: %s", mano_response.text) if mano_response.status_code != 200: return _print_verbose(mano_response, args.verbose) # set - URLrequest = "http://%s:%s/openmano/%s/wims/%s/port_mapping" % (mano_host, mano_port, tenant, wim) + URLrequest = "http://{}:{}/openmano/{}/wims/{}/port_mapping".format(mano_host, mano_port, tenant, wim) logger.debug("openmano request: %s", payload_req) mano_response = requests.post(URLrequest, headers=headers_req, data=payload_req) logger.debug("openmano response: %s", mano_response.text) @@ -1920,7 +1930,7 @@ def wim_port_mapping_list(args): tenant = _get_tenant() wim = _get_wim(args.name, tenant) - URLrequest = "http://%s:%s/openmano/%s/wims/%s/port_mapping" % (mano_host, mano_port, tenant, wim) + URLrequest = "http://{}:{}/openmano/{}/wims/{}/port_mapping".format(mano_host, mano_port, tenant, wim) mano_response = requests.get(URLrequest) logger.debug("openmano response: %s", mano_response.text) @@ -1932,38 +1942,37 @@ def wim_port_mapping_clear(args): wim = _get_wim(args.name, tenant) if not args.force: - r = raw_input("Clear WIM port mapping for wim %s (y/N)? " % (wim)) + r = input("Clear WIM port mapping for wim {} (y/N)? ".format(wim)) if not (len(r) > 0 and r[0].lower() == "y"): return 0 - URLrequest = "http://%s:%s/openmano/%s/wims/%s/port_mapping" % (mano_host, mano_port, tenant, wim) + URLrequest = "http://{}:{}/openmano/{}/wims/{}/port_mapping".format(mano_host, mano_port, tenant, wim) mano_response = requests.delete(URLrequest) logger.debug("openmano response: %s", mano_response.text) content = mano_response.json() - # print json.dumps(content, indent=4) + # print(json.dumps(content, indent=4)) result = 0 if mano_response.status_code == 200 else mano_response.status_code if mano_response.status_code == 200: - print content['result'] + print(content['result']) else: - print content['error']['description'] + print(content['error']['description']) return result def version(args): headers_req = {'Accept': 'application/json', 'content-type': 'application/json'} - URLrequest = "http://%s:%s/openmano/version" % (mano_host, mano_port) + URLrequest = "http://{}:{}/openmano/version".format(mano_host, mano_port) mano_response = requests.get(URLrequest, headers=headers_req) logger.debug("openmano response: %s", mano_response.text) - print mano_response.text - - -global mano_host -global mano_port -global mano_tenant + print(mano_response.text) -if __name__=="__main__": +def main(): + global mano_host + global mano_port + global mano_tenant + global logger mano_tenant = os.getenv('OPENMANO_TENANT', None) mano_host = os.getenv('OPENMANO_HOST',"localhost") mano_port = os.getenv('OPENMANO_PORT',"9090") @@ -2458,15 +2467,15 @@ if __name__=="__main__": if item == "network" or item == "tenant": vim_item_create_parser = subparsers.add_parser(command_name + '-create', parents=[parent_parser], help="create a "+item+" at vim") - vim_item_create_parser.add_argument("file", nargs='?', help="descriptor of the %s. Must be a file or yaml/json text" % item).completer = FilesCompleter - vim_item_create_parser.add_argument("--name", action="store", help="name of the %s" % item ) + vim_item_create_parser.add_argument("file", nargs='?', help="descriptor of the {}. Must be a file or yaml/json text".format(item)).completer = FilesCompleter + vim_item_create_parser.add_argument("--name", action="store", help="name of the {}".format(item)) vim_item_create_parser.add_argument("--datacenter", action="store", help="specifies the datacenter") if item=="network": vim_item_create_parser.add_argument("--type", action="store", help="type of network, data, ptp, bridge") vim_item_create_parser.add_argument("--shared", action="store_true", help="Private or shared") vim_item_create_parser.add_argument("--bind-net", action="store", help="For openvim datacenter type, net to be bind to, for vlan type, use sufix ':'") else: - vim_item_create_parser.add_argument("--description", action="store", help="description of the %s" % item) + vim_item_create_parser.add_argument("--description", action="store", help="description of the {}".format(item)) vim_item_create_parser.set_defaults(func=vim_action, item=item, action="create") argcomplete.autocomplete(main_parser) @@ -2481,22 +2490,31 @@ if __name__=="__main__": logging.basicConfig(format=streamformat, level= level) logger = logging.getLogger('mano') logger.setLevel(level) + # print("#TODO py3", args) result = args.func(args) if result == None: result = 0 #for some reason it fails if call exit inside try instance. Need to call exit at the end !? except (requests.exceptions.ConnectionError): - print "Connection error: not possible to contact OPENMANO-SERVER (openmanod)" + print("Connection error: not possible to contact OPENMANO-SERVER (openmanod)") result = -2 except (KeyboardInterrupt): - print 'Exiting openmano' + print('Exiting openmano') result = -3 except (SystemExit, ArgumentParserError): result = -4 + except (AttributeError): + print("Type '--help' for more information") + result = -4 except OpenmanoCLIError as e: - print str(e) + # print("#TODO py3", e) + print(e) result = -5 - #print result + # print(result) exit(result) + +if __name__ == '__main__': + main() + diff --git a/RO-client/requirements.txt b/RO-client/requirements.txt new file mode 100644 index 00000000..cd8e0484 --- /dev/null +++ b/RO-client/requirements.txt @@ -0,0 +1,18 @@ +## +# 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. +## + +argcomplete +requests==2.* +PyYAML + diff --git a/RO-client/setup.py b/RO-client/setup.py new file mode 100644 index 00000000..d1748cd5 --- /dev/null +++ b/RO-client/setup.py @@ -0,0 +1,58 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- + +# Copyright 2018 Telefonica S.A. +# +# 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. + +import os +from setuptools import setup + +_name = "osm_roclient" +# version is at first line of osm_roclient/html_public/version +here = os.path.abspath(os.path.dirname(__file__)) +with open(os.path.join(here, 'README.rst')) as readme_file: + README = readme_file.read() + +setup( + name=_name, + description='OSM ro client', + long_description=README, + version_command=('git describe --match v* --tags --long --dirty', 'pep440-git-full'), + # version=VERSION, + # python_requires='>3.5.0', + author='ETSI OSM', + author_email='alfonso.tiernosepulveda@telefonica.com', + maintainer='Alfonso Tierno', + maintainer_email='alfonso.tiernosepulveda@telefonica.com', + url='https://osm.etsi.org/gitweb/?p=osm/LCM.git;a=summary', + license='Apache 2.0', + + packages=[_name], + include_package_data=True, + # data_files=[('/etc/osm/', ['osm_roclient/lcm.cfg']), + # ('/etc/systemd/system/', ['osm_roclient/osm-lcm.service']), + # ], + install_requires=[ + 'PyYAML', + 'requests==2.*', + 'argcomplete', + ], + setup_requires=['setuptools-version-command'], + entry_points={ + "console_scripts": [ + "openmano=osm_roclient.roclient:main" + ] + }, +) diff --git a/RO-client/stdeb.cfg b/RO-client/stdeb.cfg new file mode 100644 index 00000000..844e87e8 --- /dev/null +++ b/RO-client/stdeb.cfg @@ -0,0 +1,18 @@ +# +# 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. +# + +[DEFAULT] +X-Python3-Version : >= 3.5 +Depends3: python3-argcomplete, python3-requests, python3-yaml diff --git a/RO-client/tox.ini b/RO-client/tox.ini new file mode 100644 index 00000000..a8e7c3a6 --- /dev/null +++ b/RO-client/tox.ini @@ -0,0 +1,41 @@ +# Copyright 2018 Telefonica S.A. +# +# 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. + +[tox] +envlist = py3 +toxworkdir={homedir}/.tox + +[testenv] +basepython = python3 +install_command = python3 -m pip install -r requirements.txt -U {opts} {packages} +deps = -r{toxinidir}/test-requirements.txt +commands=python3 -m unittest discover -v + +[testenv:flake8] +basepython = python3 +deps = flake8 +commands = flake8 osm_roclient --max-line-length 120 \ + --exclude .svn,CVS,.gz,.git,__pycache__,.tox,local,temp --ignore W291,W293,E226,W504 + +[testenv:unittest] +basepython = python3 +commands = python3 -m unittest osm_roclient.tests + +[testenv:build] +basepython = python3 +deps = stdeb + setuptools-version-command +commands = python3 setup.py --command-packages=stdeb.command bdist_deb + diff --git a/RO/MANIFEST.in b/RO/MANIFEST.in new file mode 100644 index 00000000..7251d312 --- /dev/null +++ b/RO/MANIFEST.in @@ -0,0 +1,21 @@ +## +# 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. +## + +#include MANIFEST.in +#include requirements.txt +include README.rst +include requirements.txt +include README.rst +recursive-include osm_ro * + diff --git a/RO/Makefile b/RO/Makefile new file mode 100644 index 00000000..b41748d3 --- /dev/null +++ b/RO/Makefile @@ -0,0 +1,120 @@ +# Copyright 2018 Telefonica S.A. +# +# 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. + +.PHONY: all test clean + +SHELL := /bin/bash + +BRANCH ?= master + +all: clean package + +clean: + rm -rf dist deb_dist osm_ro-*.tar.gz osm_ro.egg-info .eggs + +package: +# apt-get install -y python-stdeb + python3 setup.py --command-packages=stdeb.command sdist_dsc + cp debian/python3-osm-ro.postinst deb_dist/osm-ro*/debian/ + cd deb_dist/osm-ro*/ && dpkg-buildpackage -rfakeroot -uc -us + # mkdir -p .build + # cp build/deb_dist/python-*.deb .build/ + +clean_build: + rm -rf build + find osm_ro -name '*.pyc' -delete + find osm_ro -name '*.pyo' -delete + +prepare: +# ip install --user --upgrade setuptools + mkdir -p build/ +# VER1=$(shell git describe | sed -e 's/^v//' |cut -d- -f1); \ +# VER2=$(shell git describe | cut -d- -f2); \ +# VER3=$(shell git describe | cut -d- -f3); \ +# echo "$$VER1.dev$$VER2+$$VER3" > build/RO_VERSION + cp tox.ini build/ + cp MANIFEST.in build/ + cp requirements.txt build/ + cp README.rst build/ + cp setup.py build/ + cp stdeb.cfg build/ + cp -r osm_ro build/ + cp openmano build/ + cp openmanod build/ + cp -r vnfs build/osm_ro + cp -r scenarios build/osm_ro + cp -r instance-scenarios build/osm_ro + cp -r scripts build/osm_ro + cp -r database_utils build/osm_ro + cp LICENSE build/osm_ro + +connectors: prepare + # python-novaclient is required for that + rm -f build/osm_ro/openmanolinkervimconn.py + cd build/osm_ro; for i in `ls vimconn_*.py |sed "s/\.py//"` ; do echo "import $$i" >> openmanolinkervimconn.py; done + python build/osm_ro/openmanolinkervimconn.py 2>&1 + rm -f build/osm_ro/openmanolinkervimconn.py + +build: connectors prepare + python -m py_compile build/osm_ro/*.py +# cd build && tox -e flake8 + +lib-openvim: + $(shell git clone https://osm.etsi.org/gerrit/osm/openvim) + LIB_BRANCH=$(shell git -C openvim branch -a|grep -oP 'remotes/origin/\K$(BRANCH)'); \ + [ -z "$$LIB_BRANCH" ] && LIB_BRANCH='master'; \ + echo "BRANCH: $(BRANCH)"; \ + echo "LIB_OPENVIM_BRANCH: $$LIB_BRANCH"; \ + git -C openvim checkout $$LIB_BRANCH + make -C openvim clean lite + +osm-im: + $(shell git clone https://osm.etsi.org/gerrit/osm/IM) + make -C IM clean all + +snap: + echo "Nothing to be done yet" + +install: lib-openvim osm-im + dpkg -i IM/deb_dist/python-osm-im*.deb + dpkg -i openvim/.build/python-lib-osm-openvim*.deb + dpkg -i .build/python-osm-ro*.deb + cd .. && \ + OSMLIBOVIM_PATH=`python -c 'import lib_osm_openvim; print lib_osm_openvim.__path__[0]'` || FATAL "lib-osm-openvim was not properly installed" && \ + OSMRO_PATH=`python -c 'import osm_ro; print osm_ro.__path__[0]'` || FATAL "osm-ro was not properly installed" && \ + USER=root DEBIAN_FRONTEND=noninteractive $$OSMRO_PATH/database_utils/install-db-server.sh --updatedb || FATAL "osm-ro db installation failed" && \ + USER=root DEBIAN_FRONTEND=noninteractive $$OSMLIBOVIM_PATH/database_utils/install-db-server.sh -u mano -p manopw -d mano_vim_db --updatedb || FATAL "lib-osm-openvim db installation failed" + service osm-ro restart + +develop: prepare +# pip install -r requirements.txt + cd build && ./setup.py develop + +test: + . ./test/basictest.sh -f --insert-bashrc --install-openvim --init-openvim + . ./test/basictest.sh -f reset add-openvim + ./test/test_RO.py deploy -n mgmt -t osm -i cirros034 -d local-openvim --timeout=30 --failfast + ./test/test_RO.py vim -t osm -d local-openvim --timeout=30 --failfast + +build-docker-from-source: + docker build -t osm/openmano -f docker/Dockerfile-local . + +run-docker: + docker-compose -f docker/openmano-compose.yml up + +stop-docker: + docker-compose -f docker/openmano-compose.yml down + + diff --git a/README.rst b/RO/README.rst similarity index 100% rename from README.rst rename to RO/README.rst diff --git a/RO/debian/python3-osm-ro.postinst b/RO/debian/python3-osm-ro.postinst new file mode 100755 index 00000000..02f356b7 --- /dev/null +++ b/RO/debian/python3-osm-ro.postinst @@ -0,0 +1,21 @@ +#!/bin/bash + +## +# 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. +# +# For those usages not covered by the Apache License, Version 2.0 please +# contact with: OSM_TECH@list.etsi.org +## + +echo "POST INSTALL OSM-RO" +# nothing to do diff --git a/osm_ro/__init__.py b/RO/osm_ro/__init__.py similarity index 100% rename from osm_ro/__init__.py rename to RO/osm_ro/__init__.py diff --git a/osm_ro/console_proxy_thread.py b/RO/osm_ro/console_proxy_thread.py similarity index 89% rename from osm_ro/console_proxy_thread.py rename to RO/osm_ro/console_proxy_thread.py index 032c774a..0c448991 100644 --- a/osm_ro/console_proxy_thread.py +++ b/RO/osm_ro/console_proxy_thread.py @@ -80,7 +80,7 @@ class ConsoleProxyThread(threading.Thread): raise ConsoleProxyException(type(e).__name__ + ": "+ (str(e) if len(e.args)==0 else str(e.args[0])) ) def run(self): - while 1: + while True: try: inputready, _, _ = select.select(self.input_list, [], [], self.check_finish) except select.error as e: @@ -119,9 +119,9 @@ class ConsoleProxyThread(threading.Thread): try: forward = socket.socket(socket.AF_INET, socket.SOCK_STREAM) forward.connect((self.console_host, self.console_port)) - name = "%s:%d => (%s:%d => %s:%d) => %s:%d" %\ - (clientsock.getpeername() + clientsock.getsockname() + forward.getsockname() + forward.getpeername() ) - self.logger.warn("new connection " + name) + name = "{}:{} => ({}:{} => {}:{}) => {}:{}".format( + *clientsock.getpeername(), *clientsock.getsockname(), *forward.getsockname(), *forward.getpeername() ) + self.logger.warning("new connection " + name) self.input_list.append(clientsock) self.input_list.append(forward) @@ -142,22 +142,22 @@ class ConsoleProxyThread(threading.Thread): if sock not in self.channel: return #can happen if there is data ready to received at both sides and the channel has been deleted. QUITE IMPROBABLE but just in case info = self.channel[sock] - #debug info + # debug info sockname = "client" if sock is info["clientsock"] else "server" - self.logger.warn("del connection %s %s at %s side", info["name"], str(cause), str(sockname) ) - #close sockets + self.logger.warning("del connection %s %s at %s side", info["name"], str(cause), str(sockname)) + # close sockets try: # close the connection with client info["clientsock"].close() # equivalent to do self.s.close() except (socket.error, socket.herror, socket.gaierror, socket.timeout) as e: - self.logger.error("Exception on_close client socket %s: %s", type(e).__name__, str(e) ) + self.logger.error("Exception on_close client socket %s: %s", type(e).__name__, str(e)) try: # close the connection with remote server info["serversock"].close() except (socket.error, socket.herror, socket.gaierror, socket.timeout) as e: self.logger.error("Exception on_close server socket %s: %s", type(e).__name__, str(e) ) - #remove objects from input_list + # remove objects from input_list self.input_list.remove(info["clientsock"]) self.input_list.remove(info["serversock"]) # delete both objects from channel dict @@ -166,7 +166,7 @@ class ConsoleProxyThread(threading.Thread): def on_recv(self, sock): if sock not in self.channel: - return #can happen if there is data ready to received at both sides and the channel has been deleted. QUITE IMPROBABLE but just in case + return # can happen if there is data ready to received at both sides and the channel has been deleted. QUITE IMPROBABLE but just in case info = self.channel[sock] peersock = info["serversock"] if sock is info["clientsock"] else info["clientsock"] try: @@ -174,12 +174,12 @@ class ConsoleProxyThread(threading.Thread): if len(data) == 0: self.on_close(sock, "peer closed") else: - #print self.data + # print self.data sock = peersock peersock.send(data) except (socket.error, socket.herror, socket.gaierror, socket.timeout) as e: - #print self.name, ": Exception %s: %s" % (type(e).__name__, str(e) ) - self.on_close(sock, "Exception %s: %s" % (type(e).__name__, str(e) )) + # print(self.name, ": Exception {}: {}".format(type(e).__name__, e)) + self.on_close(sock, "Exception {}: {}".format(type(e).__name__, e)) diff --git a/database_utils/dump_db.sh b/RO/osm_ro/database_utils/dump_db.sh similarity index 100% rename from database_utils/dump_db.sh rename to RO/osm_ro/database_utils/dump_db.sh diff --git a/database_utils/init_mano_db.sh b/RO/osm_ro/database_utils/init_mano_db.sh similarity index 100% rename from database_utils/init_mano_db.sh rename to RO/osm_ro/database_utils/init_mano_db.sh diff --git a/database_utils/install-db-server.sh b/RO/osm_ro/database_utils/install-db-server.sh similarity index 100% rename from database_utils/install-db-server.sh rename to RO/osm_ro/database_utils/install-db-server.sh diff --git a/database_utils/mano_db_structure.sql b/RO/osm_ro/database_utils/mano_db_structure.sql similarity index 100% rename from database_utils/mano_db_structure.sql rename to RO/osm_ro/database_utils/mano_db_structure.sql diff --git a/database_utils/migrate_mano_db.sh b/RO/osm_ro/database_utils/migrate_mano_db.sh similarity index 100% rename from database_utils/migrate_mano_db.sh rename to RO/osm_ro/database_utils/migrate_mano_db.sh diff --git a/database_utils/migrations/down/34_remove_wim_tables.sql b/RO/osm_ro/database_utils/migrations/down/34_remove_wim_tables.sql similarity index 100% rename from database_utils/migrations/down/34_remove_wim_tables.sql rename to RO/osm_ro/database_utils/migrations/down/34_remove_wim_tables.sql diff --git a/database_utils/migrations/down/35_remove_sfc_ingress_and_egress.sql b/RO/osm_ro/database_utils/migrations/down/35_remove_sfc_ingress_and_egress.sql similarity index 100% rename from database_utils/migrations/down/35_remove_sfc_ingress_and_egress.sql rename to RO/osm_ro/database_utils/migrations/down/35_remove_sfc_ingress_and_egress.sql diff --git a/database_utils/migrations/up/34_add_wim_tables.sql b/RO/osm_ro/database_utils/migrations/up/34_add_wim_tables.sql similarity index 100% rename from database_utils/migrations/up/34_add_wim_tables.sql rename to RO/osm_ro/database_utils/migrations/up/34_add_wim_tables.sql diff --git a/database_utils/migrations/up/35_add_sfc_ingress_and_egress.sql b/RO/osm_ro/database_utils/migrations/up/35_add_sfc_ingress_and_egress.sql similarity index 100% rename from database_utils/migrations/up/35_add_sfc_ingress_and_egress.sql rename to RO/osm_ro/database_utils/migrations/up/35_add_sfc_ingress_and_egress.sql diff --git a/osm_ro/db_base.py b/RO/osm_ro/db_base.py similarity index 97% rename from osm_ro/db_base.py rename to RO/osm_ro/db_base.py index e6e1134d..9c131334 100644 --- a/osm_ro/db_base.py +++ b/RO/osm_ro/db_base.py @@ -29,7 +29,7 @@ __date__ ="$4-Apr-2016 10:05:01$" import MySQLdb as mdb import uuid as myUuid -import utils as af +from osm_ro import utils as af import json #import yaml import time @@ -164,12 +164,14 @@ def _convert_bandwidth(data, reverse=False, logger=None): pos = value.find("bps") if pos>0: if value[pos-1]=="G": data["bandwidth"] = int(data["bandwidth"][:pos-1]) * 1000 - elif value[pos-1]=="k": data["bandwidth"]= int(data["bandwidth"][:pos-1]) / 1000 + elif value[pos-1]=="k": data["bandwidth"]= int(data["bandwidth"][:pos-1]) // 1000 else: data["bandwidth"]= int(data["bandwidth"][:pos-1]) else: value = int(data["bandwidth"]) - if value % 1000 == 0: data["bandwidth"]=str(value/1000) + " Gbps" - else: data["bandwidth"]=str(value) + " Mbps" + if value % 1000 == 0: + data["bandwidth"] = str(value // 1000) + " Gbps" + else: + data["bandwidth"] = str(value) + " Mbps" except: if logger: logger.error("convert_bandwidth exception for type '%s' data '%s'", type(data["bandwidth"]), data["bandwidth"]) @@ -248,8 +250,6 @@ class db_base(): return self.con.escape(value) def escape_string(self, value): - if isinstance(value, unicode): - value = value.encode("utf8") return self.con.escape_string(value) @retry @@ -280,7 +280,7 @@ class db_base(): return except AttributeError as e: #self.con not defined if e[0][-5:] == "'con'": - self.logger.warn("while disconnecting from DB: Error %d: %s",e.args[0], e.args[1]) + self.logger.warning("while disconnecting from DB: Error %d: %s",e.args[0], e.args[1]) return else: raise @@ -364,8 +364,7 @@ class db_base(): ''' # the **_ ignores extra kwargs table_info = ' (table `{}`)'.format(table) if table else '' if cmd: - self.logger.debug("Exception '%s' with command '%s'%s", - e, cmd, table_info) + self.logger.debug("Exception '%s' with command '%s'%s", e, cmd, table_info) if isinstance(e,AttributeError ): self.logger.debug(str(e), exc_info=True) @@ -376,7 +375,7 @@ class db_base(): self.reconnect() if tries > 1: - self.logger.warn("DB Exception '%s'. Retry", str(e)) + self.logger.warning("DB Exception '%s'. Retry", str(e)) return else: raise db_base_Exception("Database connection timeout Try Again", httperrors.Request_Timeout) @@ -422,7 +421,7 @@ class db_base(): """ if data is None: return 'Null' - elif isinstance(data[1], (str, unicode)): + elif isinstance(data[1], str): return json.dumps(data) else: return json.dumps(str(data)) @@ -438,7 +437,7 @@ class db_base(): """ if data[1] is None: return str(data[0]) + "=Null" - elif isinstance(data[1], (str, unicode)): + elif isinstance(data[1], str): return str(data[0]) + '=' + json.dumps(data[1]) elif isinstance(data[1], dict): if "INCREMENT" in data[1]: @@ -483,12 +482,12 @@ class db_base(): for v2 in v: if v2 is None: cmd2.append(k.replace("=", " is").replace("<>", " is not") + " Null") - elif isinstance(v2, (str, unicode)): + elif isinstance(v2, str): cmd2.append(k + json.dumps(v2)) else: cmd2.append(k + json.dumps(str(v2))) cmd.append("(" + " OR ".join(cmd2) + ")") - elif isinstance(v, (str, unicode)): + elif isinstance(v, str): cmd.append(k + json.dumps(v)) else: cmd.append(k + json.dumps(str(v))) @@ -524,7 +523,7 @@ class db_base(): :return: the number of updated rows, raises exception upon error """ # gettting uuid - values = ",".join(map(self.__tuple2db_format_set, UPDATE.iteritems() )) + values = ",".join(map(self.__tuple2db_format_set, UPDATE.items() )) if modified_time: values += ",modified_at={:f}".format(modified_time) cmd= "UPDATE " + table + " SET " + values + " WHERE " + self.__create_where(WHERE) @@ -589,7 +588,7 @@ class db_base(): self.cur.execute(cmd) #insertion cmd= "INSERT INTO " + table +" SET " + \ - ",".join(map(self.__tuple2db_format_set, INSERT.iteritems() )) + ",".join(map(self.__tuple2db_format_set, INSERT.items() )) if created_time: cmd += ",created_at={time:.9f},modified_at={time:.9f}".format(time=created_time) if confidential_data: @@ -810,7 +809,7 @@ class db_base(): self.cur.execute("SELECT * FROM " + table + " WHERE "+ where_text) rows = self.cur.fetchall() if self.cur.rowcount==0: - return 0, "Name %s not found in table %s" %(name, table) + return 0, "Name {} not found in table {}".format(name, table) elif self.cur.rowcount>1: - return self.cur.rowcount, "More than one VNF with name %s found in table %s" %(name, table) + return self.cur.rowcount, "More than one VNF with name {} found in table {}".format(name, table) return self.cur.rowcount, rows[0]["uuid"] diff --git a/osm_ro/http_tools/__init__.py b/RO/osm_ro/http_tools/__init__.py similarity index 100% rename from osm_ro/http_tools/__init__.py rename to RO/osm_ro/http_tools/__init__.py diff --git a/osm_ro/http_tools/errors.py b/RO/osm_ro/http_tools/errors.py similarity index 100% rename from osm_ro/http_tools/errors.py rename to RO/osm_ro/http_tools/errors.py diff --git a/osm_ro/http_tools/handler.py b/RO/osm_ro/http_tools/handler.py similarity index 100% rename from osm_ro/http_tools/handler.py rename to RO/osm_ro/http_tools/handler.py diff --git a/osm_ro/http_tools/request_processing.py b/RO/osm_ro/http_tools/request_processing.py similarity index 94% rename from osm_ro/http_tools/request_processing.py rename to RO/osm_ro/http_tools/request_processing.py index f2dabc8a..13e19ed5 100644 --- a/osm_ro/http_tools/request_processing.py +++ b/RO/osm_ro/http_tools/request_processing.py @@ -15,6 +15,7 @@ from jsonschema import exceptions as js_e from jsonschema import validate as js_v from . import errors as httperrors +from io import TextIOWrapper logger = logging.getLogger('openmano.http') @@ -64,13 +65,13 @@ def format_out(data): '''Return string of dictionary data according to requested json, yaml, xml. By default json ''' - logger.debug("OUT: " + yaml.safe_dump(data, explicit_start=True, indent=4, default_flow_style=False, tags=False, encoding='utf-8', allow_unicode=True) ) + logger.debug("OUT: " + yaml.safe_dump(data, explicit_start=True, indent=4, default_flow_style=False, tags=False, allow_unicode=True) ) accept = bottle.request.headers.get('Accept') if accept and 'application/yaml' in accept: bottle.response.content_type='application/yaml' return yaml.safe_dump( data, explicit_start=True, indent=4, default_flow_style=False, - tags=False, encoding='utf-8', allow_unicode=True) #, canonical=True, default_style='"' + tags=False, allow_unicode=True) #, canonical=True, default_style='"' else: #by default json bottle.response.content_type='application/json' #return data #json no style @@ -102,11 +103,11 @@ def format_in(default_schema, version_fields=None, version_dict_schema=None, con if 'application/json' in format_type: error_text = "Invalid json format " #Use the json decoder instead of bottle decoder because it informs about the location of error formats with a ValueError exception - client_data = json.load(bottle.request.body) + client_data = json.load(TextIOWrapper(bottle.request.body, encoding="utf-8")) # TODO py3 #client_data = bottle.request.json() elif 'application/yaml' in format_type: error_text = "Invalid yaml format " - client_data = yaml.load(bottle.request.body) + client_data = yaml.load(bottle.request.body, Loader=yaml.Loader) elif 'application/xml' in format_type: bottle.abort(501, "Content-Type: application/xml not supported yet.") else: @@ -118,10 +119,10 @@ def format_in(default_schema, version_fields=None, version_dict_schema=None, con # return if confidential_data: logger.debug('IN: %s', remove_clear_passwd (yaml.safe_dump(client_data, explicit_start=True, indent=4, default_flow_style=False, - tags=False, encoding='utf-8', allow_unicode=True))) + tags=False, allow_unicode=True))) else: logger.debug('IN: %s', yaml.safe_dump(client_data, explicit_start=True, indent=4, default_flow_style=False, - tags=False, encoding='utf-8', allow_unicode=True) ) + tags=False, allow_unicode=True) ) # look for the client provider version error_text = "Invalid content " if not default_schema and not version_fields: diff --git a/osm_ro/http_tools/tests/__init__.py b/RO/osm_ro/http_tools/tests/__init__.py similarity index 100% rename from osm_ro/http_tools/tests/__init__.py rename to RO/osm_ro/http_tools/tests/__init__.py diff --git a/osm_ro/http_tools/tests/test_errors.py b/RO/osm_ro/http_tools/tests/test_errors.py similarity index 100% rename from osm_ro/http_tools/tests/test_errors.py rename to RO/osm_ro/http_tools/tests/test_errors.py diff --git a/osm_ro/http_tools/tests/test_handler.py b/RO/osm_ro/http_tools/tests/test_handler.py similarity index 100% rename from osm_ro/http_tools/tests/test_handler.py rename to RO/osm_ro/http_tools/tests/test_handler.py diff --git a/osm_ro/http_tools/tox.ini b/RO/osm_ro/http_tools/tox.ini similarity index 100% rename from osm_ro/http_tools/tox.ini rename to RO/osm_ro/http_tools/tox.ini diff --git a/osm_ro/httpserver.py b/RO/osm_ro/httpserver.py similarity index 99% rename from osm_ro/httpserver.py rename to RO/osm_ro/httpserver.py index 613fb084..d86271cb 100644 --- a/osm_ro/httpserver.py +++ b/RO/osm_ro/httpserver.py @@ -34,7 +34,7 @@ import yaml import threading import logging -from openmano_schemas import vnfd_schema_v01, vnfd_schema_v02, \ +from osm_ro.openmano_schemas import vnfd_schema_v01, vnfd_schema_v02, \ nsd_schema_v01, nsd_schema_v02, nsd_schema_v03, scenario_edit_schema, \ scenario_action_schema, instance_scenario_action_schema, instance_scenario_create_schema_v01, \ tenant_schema, tenant_edit_schema,\ @@ -50,9 +50,9 @@ from .http_tools.request_processing import ( ) from .wim.http_handler import WimHandler -import nfvo -import utils -from db_base import db_base_Exception +from . import nfvo +from . import utils +from .db_base import db_base_Exception from functools import wraps global mydb @@ -314,7 +314,7 @@ def http_get_vim_account(tenant_id, vim_account_id=None): vim_account["passwd"] = "******" if vim_account['config'] != None: try: - config_dict = yaml.load(vim_account['config']) + config_dict = yaml.load(vim_account['config'], Loader=yaml.Loader) vim_account['config'] = config_dict if vim_account['config'].get('admin_password'): vim_account['config']['admin_password'] = "******" @@ -383,7 +383,7 @@ def http_get_datacenter_id(tenant_id, datacenter_id): vim_tenant["passwd"] = "******" if vim_tenant['config'] != None: try: - config_dict = yaml.load(vim_tenant['config']) + config_dict = yaml.load(vim_tenant['config'], Loader=yaml.Loader) vim_tenant['config'] = config_dict if vim_tenant['config'].get('admin_password'): vim_tenant['config']['admin_password'] = "******" @@ -396,7 +396,7 @@ def http_get_datacenter_id(tenant_id, datacenter_id): if datacenter['config'] != None: try: - config_dict = yaml.load(datacenter['config']) + config_dict = yaml.load(datacenter['config'], Loader=yaml.Loader) datacenter['config'] = config_dict if datacenter['config'].get('admin_password'): datacenter['config']['admin_password'] = "******" @@ -636,7 +636,7 @@ def http_getnetmap_datacenter_id(tenant_id, datacenter_id, netmap_id=None): if netmap_id and len(netmaps)==1: data={'netmap' : netmaps[0]} elif netmap_id and len(netmaps)==0: - bottle.abort(httperrors.Not_Found, "No netmap found with " + " and ".join(map(lambda x: str(x[0])+": "+str(x[1]), where_.iteritems())) ) + bottle.abort(httperrors.Not_Found, "No netmap found with " + " and ".join(map(lambda x: str(x[0])+": "+str(x[1]), where_.items())) ) return else: data={'netmaps' : netmaps} @@ -668,11 +668,11 @@ def http_delnetmap_datacenter_id(tenant_id, datacenter_id, netmap_id=None): #change_keys_http2db(content, http2db_tenant, reverse=True) deleted = mydb.delete_row(FROM='datacenter_nets', WHERE= where_) if deleted == 0 and netmap_id: - bottle.abort(httperrors.Not_Found, "No netmap found with " + " and ".join(map(lambda x: str(x[0])+": "+str(x[1]), where_.iteritems())) ) + bottle.abort(httperrors.Not_Found, "No netmap found with " + " and ".join(map(lambda x: str(x[0])+": "+str(x[1]), where_.items())) ) if netmap_id: - return format_out({"result": "netmap %s deleted" % netmap_id}) + return format_out({"result": "netmap {} deleted".format(netmap_id)}) else: - return format_out({"result": "%d netmap deleted" % deleted}) + return format_out({"result": "{} netmap deleted".format(deleted)}) except bottle.HTTPError: raise except (nfvo.NfvoException, db_base_Exception) as e: @@ -1081,7 +1081,7 @@ def http_get_hosts(tenant_id, datacenter): result, data = nfvo.get_hosts_info(mydb, tenant_id) #, datacenter) if result < 0: - #print "http_get_hosts error %d %s" % (-result, data) + #print("http_get_hosts error {} {}".format((-result, data)) bottle.abort(-result, data) else: utils.convert_float_timestamp2str(data) diff --git a/osm_ro/nfvo.py b/RO/osm_ro/nfvo.py similarity index 97% rename from osm_ro/nfvo.py rename to RO/osm_ro/nfvo.py index 49705004..a28f57f6 100644 --- a/osm_ro/nfvo.py +++ b/RO/osm_ro/nfvo.py @@ -30,42 +30,50 @@ __date__ ="$16-sep-2014 22:05:01$" # import imp import json import yaml -import utils -from utils import deprecated -import vim_thread -import console_proxy_thread as cli -import vimconn +from osm_ro import utils +from osm_ro.utils import deprecated +from osm_ro.vim_thread import vim_thread +import osm_ro.console_proxy_thread as cli +from osm_ro import vimconn import logging import collections import math from uuid import uuid4 -from db_base import db_base_Exception +from osm_ro.db_base import db_base_Exception -import nfvo_db +from osm_ro import nfvo_db from threading import Lock import time as t -from lib_osm_openvim import ovim as ovim_module -from lib_osm_openvim.ovim import ovimException +# TODO py3 BEGIN +# from lib_osm_openvim import ovim as ovim_module +# from lib_osm_openvim.ovim import ovimException +from unittest.mock import MagicMock +ovim_module = MagicMock() +class ovimException(Exception): + pass +ovim_module.ovimException = ovimException +# TODO py3 END + from Crypto.PublicKey import RSA import osm_im.vnfd as vnfd_catalog import osm_im.nsd as nsd_catalog from pyangbind.lib.serialise import pybindJSONDecoder from copy import deepcopy +from pkg_resources import iter_entry_points # WIM -import wim.wimconn as wimconn -import wim.wim_thread as wim_thread -from .http_tools import errors as httperrors -from .wim.engine import WimEngine -from .wim.persistence import WimPersistence +import osm_ro.wim.wimconn as wimconn +import osm_ro.wim.wim_thread as wim_thread +from osm_ro.http_tools import errors as httperrors +from osm_ro.wim.engine import WimEngine +from osm_ro.wim.persistence import WimPersistence from copy import deepcopy from pprint import pformat # global global_config -global vimconn_imported # WIM global wim_engine wim_engine = None @@ -78,7 +86,7 @@ global ovim ovim = None global_config = None -vimconn_imported = {} # dictionary with VIM type as key, loaded module as value +plugins = {} # dictionary with VIM type as key, loaded module as value vim_threads = {"running":{}, "deleting": {}, "names": []} # threads running for attached-VIMs vim_persistent_info = {} # WIM @@ -97,6 +105,13 @@ db_lock = Lock() class NfvoException(httperrors.HttpMappedError): """Common Class for NFVO errors""" +def _load_vim_plugin(name): + global plugins + for v in iter_entry_points('osm_rovim.plugins', name): + plugins[name] = v.load() + if name and name not in plugins: + raise NfvoException("Unknown vim type '{}'. This plugin has not been registered".format(name), + httperrors.Bad_Request) def get_task_id(): global last_task_id @@ -151,7 +166,7 @@ def get_non_used_wim_name(wim_name, wim_id, tenant_name, tenant_id): def start_service(mydb, persistence=None, wim=None): - global db, global_config + global db, global_config, plugins db = nfvo_db.nfvo_db(lock=db_lock) mydb.lock = db_lock db.connect(global_config['db_host'], global_config['db_user'], global_config['db_passwd'], global_config['db_name']) @@ -201,30 +216,19 @@ def start_service(mydb, persistence=None, wim=None): extra={'datacenter_tenant_id': vim.get('datacenter_tenant_id'), 'datacenter_id': vim.get('datacenter_id')} if vim["config"]: - extra.update(yaml.load(vim["config"])) + extra.update(yaml.load(vim["config"], Loader=yaml.Loader)) if vim.get('dt_config'): - extra.update(yaml.load(vim["dt_config"])) - if vim["type"] not in vimconn_imported: - module_info=None - try: - module = "vimconn_" + vim["type"] - pkg = __import__("osm_ro." + module) - vim_conn = getattr(pkg, module) - # module_info = imp.find_module(module, [__file__[:__file__.rfind("/")]]) - # vim_conn = imp.load_module(vim["type"], *module_info) - vimconn_imported[vim["type"]] = vim_conn - except (IOError, ImportError) as e: - # if module_info and module_info[0]: - # file.close(module_info[0]) - raise NfvoException("Unknown vim type '{}'. Cannot open file '{}.py'; {}: {}".format( - vim["type"], module, type(e).__name__, str(e)), httperrors.Bad_Request) + extra.update(yaml.load(vim["dt_config"], Loader=yaml.Loader)) + plugin_name = "rovim_" + vim["type"] + if plugin_name not in plugins: + _load_vim_plugin(plugin_name) thread_id = vim['datacenter_tenant_id'] vim_persistent_info[thread_id] = {} try: #if not tenant: # return -httperrors.Bad_Request, "You must provide a valid tenant name or uuid for VIM %s" % ( vim["type"]) - myvim = vimconn_imported[ vim["type"] ].vimconnector( + myvim = plugins[plugin_name].vimconnector( uuid=vim['datacenter_id'], name=vim['datacenter_name'], tenant_id=vim['vim_tenant_id'], tenant_name=vim['vim_tenant_name'], url=vim['vim_url'], url_admin=vim['vim_url_admin'], @@ -240,8 +244,8 @@ def start_service(mydb, persistence=None, wim=None): httperrors.Internal_Server_Error) thread_name = get_non_used_vim_name(vim['datacenter_name'], vim['datacenter_id'], vim['vim_tenant_name'], vim['vim_tenant_id']) - new_thread = vim_thread.vim_thread(task_lock, thread_name, vim['datacenter_name'], - vim['datacenter_tenant_id'], db=db, db_lock=db_lock, ovim=ovim) + new_thread = vim_thread(task_lock, plugins, thread_name, vim['datacenter_name'], + vim['datacenter_tenant_id'], db=db, db_lock=db_lock, ovim=ovim) new_thread.start() vim_threads["running"][thread_id] = new_thread @@ -349,7 +353,7 @@ def get_imagelist(mydb, vnf_id, nfvo_tenant=None): if vm["image_id"] and vm["image_id"] not in image_list: image_list.append(vm["image_id"]) if vm["image_list"]: - vm_image_list = yaml.load(vm["image_list"]) + vm_image_list = yaml.load(vm["image_list"], Loader=yaml.Loader) for image_dict in vm_image_list: if image_dict["image_id"] not in image_list: image_list.append(image_dict["image_id"]) @@ -363,6 +367,7 @@ def get_vim(mydb, nfvo_tenant=None, datacenter_id=None, datacenter_name=None, da 'nfvo_tenant_id','datacenter_id','vim_tenant_id','vim_url','vim_url_admin','datacenter_name','type','user','passwd' raise exception upon error ''' + global plugins WHERE_dict={} if nfvo_tenant is not None: WHERE_dict['nfvo_tenant_id'] = nfvo_tenant if datacenter_id is not None: WHERE_dict['d.uuid'] = datacenter_id @@ -386,28 +391,19 @@ def get_vim(mydb, nfvo_tenant=None, datacenter_id=None, datacenter_name=None, da 'datacenter_id': vim.get('datacenter_id'), '_vim_type_internal': vim.get('type')} if vim["config"]: - extra.update(yaml.load(vim["config"])) + extra.update(yaml.load(vim["config"], Loader=yaml.Loader)) if vim.get('dt_config'): - extra.update(yaml.load(vim["dt_config"])) - if vim["type"] not in vimconn_imported: - module_info=None + extra.update(yaml.load(vim["dt_config"], Loader=yaml.Loader)) + plugin_name = "rovim_" + vim["type"] + if plugin_name not in plugins: try: - module = "vimconn_" + vim["type"] - pkg = __import__("osm_ro." + module) - vim_conn = getattr(pkg, module) - # module_info = imp.find_module(module, [__file__[:__file__.rfind("/")]]) - # vim_conn = imp.load_module(vim["type"], *module_info) - vimconn_imported[vim["type"]] = vim_conn - except (IOError, ImportError) as e: - # if module_info and module_info[0]: - # file.close(module_info[0]) + _load_vim_plugin(plugin_name) + except NfvoException as e: if ignore_errors: - logger.error("Unknown vim type '{}'. Can not open file '{}.py'; {}: {}".format( - vim["type"], module, type(e).__name__, str(e))) + logger.error("{}".format(e)) continue - raise NfvoException("Unknown vim type '{}'. Can not open file '{}.py'; {}: {}".format( - vim["type"], module, type(e).__name__, str(e)), httperrors.Bad_Request) - + else: + raise try: if 'datacenter_tenant_id' in vim: thread_id = vim["datacenter_tenant_id"] @@ -418,7 +414,7 @@ def get_vim(mydb, nfvo_tenant=None, datacenter_id=None, datacenter_name=None, da persistent_info = {} #if not tenant: # return -httperrors.Bad_Request, "You must provide a valid tenant name or uuid for VIM %s" % ( vim["type"]) - vim_dict[ vim['datacenter_id'] ] = vimconn_imported[ vim["type"] ].vimconnector( + vim_dict[vim['datacenter_id']] = plugins[plugin_name].vimconnector( uuid=vim['datacenter_id'], name=vim['datacenter_name'], tenant_id=vim.get('vim_tenant_id',vim_tenant), tenant_name=vim.get('vim_tenant_name',vim_tenant_name), @@ -541,7 +537,7 @@ def check_vnf_descriptor(vnf_descriptor, vnf_descriptor_version=1): for internal_connection in vnf_descriptor["vnf"].get("internal-connections",() ): if internal_connection["name"] in name_list: raise NfvoException( - "Error at vnf:internal-connections:name, value '%s' already used as an internal-connection".format( + "Error at vnf:internal-connections:name, value '{}' already used as an internal-connection".format( internal_connection["name"]), httperrors.Bad_Request) name_list.append(internal_connection["name"]) @@ -619,7 +615,7 @@ def create_or_use_image(mydb, vims, image_dict, rollback_list, only_create_at_vi image_mano_id = mydb.new_row('images', temp_image_dict, add_uuid=True) rollback_list.append({"where":"mano", "what":"image","uuid":image_mano_id}) #create image at every vim - for vim_id,vim in vims.iteritems(): + for vim_id,vim in vims.items(): datacenter_vim_id = vim["config"]["datacenter_tenant_id"] image_created="false" #look at database @@ -928,7 +924,7 @@ def new_vnfd_v3(mydb, tenant_id, vnf_descriptor): vnfd_descriptor_list = vnfd_catalog_descriptor.get("vnfd") if not vnfd_descriptor_list: vnfd_descriptor_list = vnfd_catalog_descriptor.get("vnfd:vnfd") - for vnfd_yang in myvnfd.vnfd_catalog.vnfd.itervalues(): + for vnfd_yang in myvnfd.vnfd_catalog.vnfd.values(): vnfd = vnfd_yang.get() # table vnf @@ -953,7 +949,7 @@ def new_vnfd_v3(mydb, tenant_id, vnf_descriptor): # table ip_profiles (ip-profiles) ip_profile_name2db_table_index = {} - for ip_profile in vnfd.get("ip-profiles").itervalues(): + for ip_profile in vnfd.get("ip-profiles").values(): db_ip_profile = { "ip_version": str(ip_profile["ip-profile-params"].get("ip-version", "ipv4")), "subnet_address": str(ip_profile["ip-profile-params"].get("subnet-address")), @@ -963,7 +959,7 @@ def new_vnfd_v3(mydb, tenant_id, vnf_descriptor): "dhcp_count": str(ip_profile["ip-profile-params"]["dhcp-params"].get("count")), } dns_list = [] - for dns in ip_profile["ip-profile-params"]["dns-server"].itervalues(): + for dns in ip_profile["ip-profile-params"]["dns-server"].values(): dns_list.append(str(dns.get("address"))) db_ip_profile["dns_address"] = ";".join(dns_list) if ip_profile["ip-profile-params"].get('security-group'): @@ -974,7 +970,7 @@ def new_vnfd_v3(mydb, tenant_id, vnf_descriptor): # table nets (internal-vld) net_id2uuid = {} # for mapping interface with network - for vld in vnfd.get("internal-vld").itervalues(): + for vld in vnfd.get("internal-vld").values(): net_uuid = str(uuid4()) uuid_list.append(net_uuid) db_net = { @@ -997,7 +993,7 @@ def new_vnfd_v3(mydb, tenant_id, vnf_descriptor): httperrors.Bad_Request) db_ip_profiles[ip_profile_name2db_table_index[ip_profile_name]]["net_id"] = net_uuid else: #check no ip-address has been defined - for icp in vld.get("internal-connection-point").itervalues(): + for icp in vld.get("internal-connection-point").values(): if icp.get("ip-address"): raise NfvoException("Error at 'vnfd[{}]':'vld[{}]':'internal-connection-point[{}]' " "contains an ip-address but no ip-profile has been defined at VLD".format( @@ -1015,7 +1011,7 @@ def new_vnfd_v3(mydb, tenant_id, vnf_descriptor): vdu_id2uuid = {} vdu_id2db_table_index = {} mgmt_access = {} - for vdu in vnfd.get("vdu").itervalues(): + for vdu in vnfd.get("vdu").values(): for vdu_descriptor in vnfd_descriptor["vdu"]: if vdu_descriptor["id"] == str(vdu["id"]): @@ -1048,7 +1044,7 @@ def new_vnfd_v3(mydb, tenant_id, vnf_descriptor): db_vm["image_id"] = image_uuid if vdu.get("alternative-images"): vm_alternative_images = [] - for alt_image in vdu.get("alternative-images").itervalues(): + for alt_image in vdu.get("alternative-images").values(): db_image = {} image_uuid = _lookfor_or_create_image(db_image, mydb, alt_image) if not image_uuid: @@ -1109,7 +1105,7 @@ def new_vnfd_v3(mydb, tenant_id, vnf_descriptor): boot_data['boot-data-drive'] = True if vdu["supplemental-boot-data"].get('config-file'): om_cfgfile_list = list() - for custom_config_file in vdu["supplemental-boot-data"]['config-file'].itervalues(): + for custom_config_file in vdu["supplemental-boot-data"]['config-file'].values(): # TODO Where this file content is present??? cfg_source = str(custom_config_file["source"]) om_cfgfile_list.append({"dest": custom_config_file["dest"], @@ -1123,8 +1119,8 @@ def new_vnfd_v3(mydb, tenant_id, vnf_descriptor): # table interfaces (internal/external interfaces) flavor_epa_interfaces = [] - # for iface in chain(vdu.get("internal-interface").itervalues(), vdu.get("external-interface").itervalues()): - for iface in vdu.get("interface").itervalues(): + # for iface in chain(vdu.get("internal-interface").values(), vdu.get("external-interface").values()): + for iface in vdu.get("interface").values(): flavor_epa_interface = {} iface_uuid = str(uuid4()) uuid_list.append(iface_uuid) @@ -1140,7 +1136,7 @@ def new_vnfd_v3(mydb, tenant_id, vnf_descriptor): if iface.get("virtual-interface").get("bandwidth"): bps = int(iface.get("virtual-interface").get("bandwidth")) - db_interface["bw"] = int(math.ceil(bps/1000000.0)) + db_interface["bw"] = int(math.ceil(bps / 1000000.0)) flavor_epa_interface["bandwidth"] = "{} Mbps".format(db_interface["bw"]) if iface.get("virtual-interface").get("type") == "OM-MGMT": @@ -1203,8 +1199,8 @@ def new_vnfd_v3(mydb, tenant_id, vnf_descriptor): raise KeyError("does not exist at vdu:internal-connection-point") icp = None icp_vld = None - for vld in vnfd.get("internal-vld").itervalues(): - for cp in vld.get("internal-connection-point").itervalues(): + for vld in vnfd.get("internal-vld").values(): + for cp in vld.get("internal-connection-point").values(): if cp.get("id-ref") == iface.get("internal-connection-point-ref"): if icp: raise KeyError("is referenced by more than one 'internal-vld'") @@ -1254,7 +1250,7 @@ def new_vnfd_v3(mydb, tenant_id, vnf_descriptor): if vdu["guest-epa"].get("numa-node-policy"): # TODO or dedicated_int: numa_node_policy = vdu["guest-epa"].get("numa-node-policy") if numa_node_policy.get("node"): - numa_node = numa_node_policy["node"].values()[0] + numa_node = next(iter(numa_node_policy["node"].values())) if numa_node.get("num-cores"): numa["cores"] = numa_node["num-cores"] epa_vcpu_set = True @@ -1264,7 +1260,7 @@ def new_vnfd_v3(mydb, tenant_id, vnf_descriptor): epa_vcpu_set = True if len(numa_node["paired-threads"].get("paired-thread-ids")): numa["paired-threads-id"] = [] - for pair in numa_node["paired-threads"]["paired-thread-ids"].itervalues(): + for pair in numa_node["paired-threads"]["paired-thread-ids"].values(): numa["paired-threads-id"].append( (str(pair["thread-a"]), str(pair["thread-b"])) ) @@ -1322,9 +1318,9 @@ def new_vnfd_v3(mydb, tenant_id, vnf_descriptor): db_vm["flavor_id"] = flavor_uuid # VNF affinity and antiaffinity - for pg in vnfd.get("placement-groups").itervalues(): + for pg in vnfd.get("placement-groups").values(): pg_name = get_str(pg, "name", 255) - for vdu in pg.get("member-vdus").itervalues(): + for vdu in pg.get("member-vdus").values(): vdu_id = get_str(vdu, "member-vdu-ref", 255) if vdu_id not in vdu_id2db_table_index: raise NfvoException("Error. Invalid VNF descriptor at 'vnfd[{vnf}]':'placement-groups[{pg}]':" @@ -1343,8 +1339,8 @@ def new_vnfd_v3(mydb, tenant_id, vnf_descriptor): "'{vdu}'. Reference to a non-existing vdu".format( vnf=vnfd_id, vdu=mgmt_vdu_id), httperrors.Bad_Request) - mgmt_access["vm_id"] = vdu_id2uuid[vnfd["mgmt-interface"]["vdu-id"]] - mgmt_access["vdu-id"] = vnfd["mgmt-interface"]["vdu-id"] + mgmt_access["vm_id"] = vdu_id2uuid[mgmt_vdu_id] + mgmt_access["vdu-id"] = mgmt_vdu_id # if only one cp is defined by this VDU, mark this interface as of type "mgmt" if vdu_id2cp_name.get(mgmt_vdu_id): if cp_name2db_interface[vdu_id2cp_name[mgmt_vdu_id]]: @@ -1447,7 +1443,7 @@ def new_vnf(mydb, tenant_id, vnf_descriptor): VNFCitem={} VNFCitem["name"] = vnfc['name'] VNFCitem["availability_zone"] = vnfc.get('availability_zone') - VNFCitem["description"] = vnfc.get("description", 'VM %s of the VNF %s' %(vnfc['name'],vnf_name)) + VNFCitem["description"] = vnfc.get("description", 'VM {} of the VNF {}'.format(vnfc['name'],vnf_name)) #print "Flavor name: %s. Description: %s" % (VNFCitem["name"]+"-flv", VNFCitem["description"]) @@ -1584,7 +1580,7 @@ def new_vnf_v02(mydb, tenant_id, vnf_descriptor): for vnfc in vnf_descriptor['vnf']['VNFC']: VNFCitem={} VNFCitem["name"] = vnfc['name'] - VNFCitem["description"] = vnfc.get("description", 'VM %s of the VNF %s' %(vnfc['name'],vnf_name)) + VNFCitem["description"] = vnfc.get("description", 'VM {} of the VNF {}'.format(vnfc['name'],vnf_name)) #print "Flavor name: %s. Description: %s" % (VNFCitem["name"]+"-flv", VNFCitem["description"]) @@ -1691,7 +1687,7 @@ def get_vnf_id(mydb, tenant_id, vnf_id): vnf_id = vnf["uuid"] filter_keys = ('uuid', 'name', 'description', 'public', "tenant_id", "osm_id", "created_at") - filtered_content = dict( (k,v) for k,v in vnf.iteritems() if k in filter_keys ) + filtered_content = dict( (k,v) for k,v in vnf.items() if k in filter_keys ) #change_keys_http2db(filtered_content, http2db_vnf, reverse=True) data={'vnf' : filtered_content} #GET VM @@ -1837,7 +1833,7 @@ def delete_vnf(mydb,tenant_id,vnf_id,datacenter=None,vim_tenant=None): mydb.delete_row_by_id('images', image) except db_base_Exception as e: logger.error("delete_vnf_error. Not possible to get image details and delete '%s'. %s", image, str(e)) - undeletedItems.append("image %s" % image) + undeletedItems.append("image {}".format(image)) return vnf_id + " " + vnf["name"] #if undeletedItems: @@ -1850,8 +1846,8 @@ def get_hosts_info(mydb, nfvo_tenant_id, datacenter_name=None): if result < 0: return result, vims elif result == 0: - return -httperrors.Not_Found, "datacenter '%s' not found" % datacenter_name - myvim = vims.values()[0] + return -httperrors.Not_Found, "datacenter '{}' not found".format(datacenter_name) + myvim = next(iter(vims.values())) result,servers = myvim.get_hosts_info() if result < 0: return result, servers @@ -1866,7 +1862,7 @@ def get_hosts(mydb, nfvo_tenant_id): elif len(vims)>1: #print "nfvo.datacenter_action() error. Several datacenters found" raise NfvoException("More than one datacenters found, try to identify with uuid", httperrors.Conflict) - myvim = vims.values()[0] + myvim = next(iter(vims.values())) try: hosts = myvim.get_hosts() logger.debug('VIM hosts response: '+ yaml.safe_dump(hosts, indent=4, default_flow_style=False)) @@ -2081,7 +2077,8 @@ def new_scenario(mydb, tenant_id, topo): for net_key in other_nets.keys(): if con[index][0]==net_key: if other_net_index>=0: - error_text="There is some interface connected both to net '%s' and net '%s'" % (con[other_net_index][0], net_key) + error_text = "There is some interface connected both to net '{}' and net '{}'".format( + con[other_net_index][0], net_key) #print "nfvo.new_scenario " + error_text raise NfvoException(error_text, httperrors.Bad_Request) else: @@ -2117,7 +2114,7 @@ def new_scenario(mydb, tenant_id, topo): net_type_data=False net_target = "__-__net"+str(net_nb) net_list[net_target] = {'name': conections_list_name[net_nb], #"net-"+str(net_nb), - 'description':"net-%s in scenario %s" %(net_nb,topo['name']), + 'description':"net-{} in scenario {}".format(net_nb,topo['name']), 'external':False} for iface in con: vnfs[ iface[0] ]['ifaces'][ iface[1] ]['net_key'] = net_target @@ -2127,7 +2124,7 @@ def new_scenario(mydb, tenant_id, topo): else: net_type_data = True if net_type_bridge and net_type_data: - error_text = "Error connection interfaces of bridge type with data type. Firs node %s, iface %s" % (iface[0], iface[1]) + error_text = "Error connection interfaces of bridge type with data type. Firs node {}, iface {}".format(iface[0], iface[1]) #print "nfvo.new_scenario " + error_text raise NfvoException(error_text, httperrors.Bad_Request) elif net_type_bridge: @@ -2137,7 +2134,7 @@ def new_scenario(mydb, tenant_id, topo): net_list[net_target]['type'] = type_ net_nb+=1 except Exception: - error_text = "Error connection node %s : %s does not match any VNF or interface" % (iface[0], iface[1]) + error_text = "Error connection node {} : {} does not match any VNF or interface".format(iface[0], iface[1]) #print "nfvo.new_scenario " + error_text #raise e raise NfvoException(error_text, httperrors.Bad_Request) @@ -2192,7 +2189,7 @@ def new_scenario_v02(mydb, tenant_id, scenario_dict, version): tenant_id=None # 1: Check that VNF are present at database table vnfs and update content into scenario dict - for name,vnf in scenario["vnfs"].iteritems(): + for name,vnf in scenario["vnfs"].items(): where = {"OR": {"tenant_id": tenant_id, 'public': "true"}} error_text = "" error_pos = "'scenario':'vnfs':'" + name + "'" @@ -2326,7 +2323,7 @@ def new_nsd_v3(mydb, tenant_id, nsd_descriptor): db_ip_profiles_index = 0 uuid_list = [] nsd_uuid_list = [] - for nsd_yang in mynsd.nsd_catalog.nsd.itervalues(): + for nsd_yang in mynsd.nsd_catalog.nsd.values(): nsd = nsd_yang.get() # table scenarios @@ -2348,7 +2345,7 @@ def new_nsd_v3(mydb, tenant_id, nsd_descriptor): # table sce_vnfs (constituent-vnfd) vnf_index2scevnf_uuid = {} vnf_index2vnf_uuid = {} - for vnf in nsd.get("constituent-vnfd").itervalues(): + for vnf in nsd.get("constituent-vnfd").values(): existing_vnf = mydb.get_rows(FROM="vnfs", WHERE={'osm_id': str(vnf["vnfd-id-ref"])[:255], 'tenant_id': tenant_id}) if not existing_vnf: @@ -2373,7 +2370,7 @@ def new_nsd_v3(mydb, tenant_id, nsd_descriptor): # table ip_profiles (ip-profiles) ip_profile_name2db_table_index = {} - for ip_profile in nsd.get("ip-profiles").itervalues(): + for ip_profile in nsd.get("ip-profiles").values(): db_ip_profile = { "ip_version": str(ip_profile["ip-profile-params"].get("ip-version", "ipv4")), "subnet_address": str(ip_profile["ip-profile-params"].get("subnet-address")), @@ -2383,7 +2380,7 @@ def new_nsd_v3(mydb, tenant_id, nsd_descriptor): "dhcp_count": str(ip_profile["ip-profile-params"]["dhcp-params"].get("count")), } dns_list = [] - for dns in ip_profile["ip-profile-params"]["dns-server"].itervalues(): + for dns in ip_profile["ip-profile-params"]["dns-server"].values(): dns_list.append(str(dns.get("address"))) db_ip_profile["dns_address"] = ";".join(dns_list) if ip_profile["ip-profile-params"].get('security-group'): @@ -2393,7 +2390,7 @@ def new_nsd_v3(mydb, tenant_id, nsd_descriptor): db_ip_profiles.append(db_ip_profile) # table sce_nets (internal-vld) - for vld in nsd.get("vld").itervalues(): + for vld in nsd.get("vld").values(): sce_net_uuid = str(uuid4()) uuid_list.append(sce_net_uuid) db_sce_net = { @@ -2430,7 +2427,7 @@ def new_nsd_v3(mydb, tenant_id, nsd_descriptor): db_sce_net["vim_network_name"] = get_str(vld, "vim-network-name", 255) # table sce_interfaces (vld:vnfd-connection-point-ref) - for iface in vld.get("vnfd-connection-point-ref").itervalues(): + for iface in vld.get("vnfd-connection-point-ref").values(): vnf_index = str(iface['member-vnf-index-ref']) # check correct parameters if vnf_index not in vnf_index2vnf_uuid: @@ -2472,7 +2469,7 @@ def new_nsd_v3(mydb, tenant_id, nsd_descriptor): db_sce_net["type"] = "bridge" # table sce_vnffgs (vnffgd) - for vnffg in nsd.get("vnffgd").itervalues(): + for vnffg in nsd.get("vnffgd").values(): sce_vnffg_uuid = str(uuid4()) uuid_list.append(sce_vnffg_uuid) db_sce_vnffg = { @@ -2485,7 +2482,7 @@ def new_nsd_v3(mydb, tenant_id, nsd_descriptor): db_sce_vnffgs.append(db_sce_vnffg) # deal with rsps - for rsp in vnffg.get("rsp").itervalues(): + for rsp in vnffg.get("rsp").values(): sce_rsp_uuid = str(uuid4()) uuid_list.append(sce_rsp_uuid) db_sce_rsp = { @@ -2495,7 +2492,7 @@ def new_nsd_v3(mydb, tenant_id, nsd_descriptor): "id": get_str(rsp, "id", 255), # only useful to link with classifiers; will be removed later in the code } db_sce_rsps.append(db_sce_rsp) - for iface in rsp.get("vnfd-connection-point-ref").itervalues(): + for iface in rsp.get("vnfd-connection-point-ref").values(): vnf_index = str(iface['member-vnf-index-ref']) if_order = int(iface['order']) # check correct parameters @@ -2547,7 +2544,7 @@ def new_nsd_v3(mydb, tenant_id, nsd_descriptor): db_sce_rsp_hops.append(db_sce_rsp_hop) # deal with classifiers - for classifier in vnffg.get("classifier").itervalues(): + for classifier in vnffg.get("classifier").values(): sce_classifier_uuid = str(uuid4()) uuid_list.append(sce_classifier_uuid) @@ -2585,7 +2582,7 @@ def new_nsd_v3(mydb, tenant_id, nsd_descriptor): db_sce_classifier["sce_rsp_id"] = rsp["uuid"] db_sce_classifiers.append(db_sce_classifier) - for match in classifier.get("match-attributes").itervalues(): + for match in classifier.get("match-attributes").values(): sce_classifier_match_uuid = str(uuid4()) uuid_list.append(sce_classifier_match_uuid) db_sce_classifier_match = { @@ -2663,7 +2660,7 @@ def start_scenario(mydb, tenant_id, scenario_id, instance_scenario_name, instanc for sce_net in scenarioDict['nets']: #print "Net name: %s. Description: %s" % (sce_net["name"], sce_net["description"]) - myNetName = "%s.%s" % (instance_scenario_name, sce_net['name']) + myNetName = "{}.{}".format(instance_scenario_name, sce_net['name']) myNetName = myNetName[0:255] #limit length myNetType = sce_net['type'] myNetDict = {} @@ -2683,7 +2680,8 @@ def start_scenario(mydb, tenant_id, scenario_id, instance_scenario_name, instanc sce_net["created"] = True else: if sce_net['vim_id'] == None: - error_text = "Error, datacenter '%s' does not have external network '%s'." % (datacenter_name, sce_net['name']) + error_text = "Error, datacenter '{}' does not have external network '{}'.".format( + datacenter_name, sce_net['name']) _, message = rollback(mydb, vims, rollbackList) logger.error("nfvo.start_scenario: %s", error_text) raise NfvoException(error_text, httperrors.Bad_Request) @@ -2697,7 +2695,7 @@ def start_scenario(mydb, tenant_id, scenario_id, instance_scenario_name, instanc for net in sce_vnf['nets']: #print "Net name: %s. Description: %s" % (net["name"], net["description"]) - myNetName = "%s.%s" % (instance_scenario_name,net['name']) + myNetName = "{}.{}".format(instance_scenario_name,net['name']) myNetName = myNetName[0:255] #limit length myNetType = net['type'] myNetDict = {} @@ -2755,7 +2753,7 @@ def start_scenario(mydb, tenant_id, scenario_id, instance_scenario_name, instanc #create flavor at vim in case it not exist flavor_dict = mydb.get_table_by_uuid_name("flavors", vm['flavor_id']) if flavor_dict['extended']!=None: - flavor_dict['extended']= yaml.load(flavor_dict['extended']) + flavor_dict['extended']= yaml.load(flavor_dict['extended'], Loader=yaml.Loader) flavor_id = create_or_use_flavor(mydb, vims, flavor_dict, [], True) vm['vim_flavor_id'] = flavor_id @@ -2786,7 +2784,8 @@ def start_scenario(mydb, tenant_id, scenario_id, instance_scenario_name, instanc if netDict["use"]=="data" and not netDict.get("type"): #print "netDict", netDict #print "iface", iface - e_text = "Cannot determine the interface type PF or VF of VNF '%s' VM '%s' iface '%s'" %(sce_vnf['name'], vm['name'], iface['internal_name']) + e_text = "Cannot determine the interface type PF or VF of VNF '{}' VM '{}' iface '{}'".format( + sce_vnf['name'], vm['name'], iface['internal_name']) if flavor_dict.get('extended')==None: raise NfvoException(e_text + "After database migration some information is not available. \ Try to delete and create the scenarios and VNFs again", httperrors.Conflict) @@ -3015,13 +3014,14 @@ def get_datacenter_by_name_uuid(mydb, tenant_id, datacenter_id_name=None, **extr elif len(vims)>1: #print "nfvo.datacenter_action() error. Several datacenters found" raise NfvoException("More than one datacenters found, try to identify with uuid", httperrors.Conflict) - return vims.keys()[0], vims.values()[0] + for vim_id, vim_content in vims.items(): + return vim_id, vim_content def update(d, u): """Takes dict d and updates it with the values in dict u. It merges all depth levels""" - for k, v in u.iteritems(): + for k, v in u.items(): if isinstance(v, collections.Mapping): r = update(d.get(k, {}), v) d[k] = r @@ -3122,7 +3122,7 @@ def create_instance(mydb, tenant_id, instance_dict): # yaml.safe_dump(scenarioDict, indent=4, default_flow_style=False)) try: # 0 check correct parameters - for net_name, net_instance_desc in instance_dict.get("networks", {}).iteritems(): + for net_name, net_instance_desc in instance_dict.get("networks", {}).items(): for scenario_net in scenarioDict['nets']: if net_name == scenario_net.get("name") or net_name == scenario_net.get("osm_id") or net_name == scenario_net.get("uuid"): break @@ -3148,7 +3148,7 @@ def create_instance(mydb, tenant_id, instance_dict): site_without_datacenter_field = True site["datacenter"] = default_datacenter_id # change name to id - for vnf_name, vnf_instance_desc in instance_dict.get("vnfs",{}).iteritems(): + for vnf_name, vnf_instance_desc in instance_dict.get("vnfs",{}).items(): for scenario_vnf in scenarioDict['vnfs']: if vnf_name == scenario_vnf['member_vnf_index'] or vnf_name == scenario_vnf['uuid'] or vnf_name == scenario_vnf['name']: break @@ -3163,7 +3163,7 @@ def create_instance(mydb, tenant_id, instance_dict): myvim_threads_id[d], _ = get_vim_thread(mydb, tenant_id, vnf_instance_desc["datacenter"]) scenario_vnf["datacenter"] = vnf_instance_desc["datacenter"] - for net_id, net_instance_desc in vnf_instance_desc.get("networks", {}).iteritems(): + for net_id, net_instance_desc in vnf_instance_desc.get("networks", {}).items(): for scenario_net in scenario_vnf['nets']: if net_id == scenario_net['osm_id'] or net_id == scenario_net['uuid'] or net_id == scenario_net["name"]: break @@ -3182,14 +3182,14 @@ def create_instance(mydb, tenant_id, instance_dict): else: update(scenario_net['ip_profile'], ipprofile_db) - for vdu_id, vdu_instance_desc in vnf_instance_desc.get("vdus", {}).iteritems(): + for vdu_id, vdu_instance_desc in vnf_instance_desc.get("vdus", {}).items(): for scenario_vm in scenario_vnf['vms']: if vdu_id == scenario_vm['osm_id'] or vdu_id == scenario_vm["name"]: break else: raise NfvoException("Invalid vdu id or name '{}' at instance:vnfs:vdus".format(vdu_id), httperrors.Bad_Request) scenario_vm["instance_parameters"] = vdu_instance_desc - for iface_id, iface_instance_desc in vdu_instance_desc.get("interfaces", {}).iteritems(): + for iface_id, iface_instance_desc in vdu_instance_desc.get("interfaces", {}).items(): for scenario_interface in scenario_vm['interfaces']: if iface_id == scenario_interface['internal_name'] or iface_id == scenario_interface["external_name"]: scenario_interface.update(iface_instance_desc) @@ -3203,7 +3203,7 @@ def create_instance(mydb, tenant_id, instance_dict): # 0.2 merge instance information into scenario # Ideally, the operation should be as simple as: update(scenarioDict,instance_dict) # However, this is not possible yet. - for net_name, net_instance_desc in instance_dict.get("networks", {}).iteritems(): + for net_name, net_instance_desc in instance_dict.get("networks", {}).items(): for scenario_net in scenarioDict['nets']: if net_name == scenario_net.get("name") or net_name == scenario_net.get("osm_id") or net_name == scenario_net.get("uuid"): if "wim_account" in net_instance_desc and net_instance_desc["wim_account"] is not None: @@ -3859,7 +3859,7 @@ def instantiate_vnf(mydb, sce_vnf, params, params_out, rollbackList): # create flavor at vim in case it not exist flavor_dict = mydb.get_table_by_uuid_name("flavors", vm['flavor_id']) if flavor_dict['extended'] != None: - flavor_dict['extended'] = yaml.load(flavor_dict['extended']) + flavor_dict['extended'] = yaml.load(flavor_dict['extended'], Loader=yaml.Loader) flavor_id = create_or_use_flavor(mydb, {datacenter_id: vim}, flavor_dict, rollbackList, True) # Obtain information for additional disks @@ -3868,11 +3868,11 @@ def instantiate_vnf(mydb, sce_vnf, params, params_out, rollbackList): if not extended_flavor_dict: raise NfvoException("flavor '{}' not found".format(flavor_id), httperrors.Not_Found) - # extended_flavor_dict_yaml = yaml.load(extended_flavor_dict[0]) + # extended_flavor_dict_yaml = yaml.load(extended_flavor_dict[0], Loader=yaml.Loader) myVMDict['disks'] = None extended_info = extended_flavor_dict[0]['extended'] if extended_info != None: - extended_flavor_dict_yaml = yaml.load(extended_info) + extended_flavor_dict_yaml = yaml.load(extended_info, Loader=yaml.Loader) if 'disks' in extended_flavor_dict_yaml: myVMDict['disks'] = extended_flavor_dict_yaml['disks'] if vm.get("instance_parameters") and vm["instance_parameters"].get("devices"): @@ -4112,7 +4112,7 @@ def delete_instance(mydb, tenant_id, instance_id): logger.error("datacenter '{}' with datacenter_tenant_id '{}' not found".format(sfp["datacenter_id"], sfp["datacenter_tenant_id"])) myvims[datacenter_key] = None else: - myvims[datacenter_key] = vims.values()[0] + myvims[datacenter_key] = next(iter(vims.values())) myvim = myvims[datacenter_key] myvim_thread = myvim_threads[datacenter_key] @@ -4151,7 +4151,7 @@ def delete_instance(mydb, tenant_id, instance_id): classification["datacenter_tenant_id"])) myvims[datacenter_key] = None else: - myvims[datacenter_key] = vims.values()[0] + myvims[datacenter_key] = next(iter(vims.values())) myvim = myvims[datacenter_key] myvim_thread = myvim_threads[datacenter_key] @@ -4191,7 +4191,7 @@ def delete_instance(mydb, tenant_id, instance_id): logger.error("datacenter '{}' with datacenter_tenant_id '{}' not found".format(sf["datacenter_id"], sf["datacenter_tenant_id"])) myvims[datacenter_key] = None else: - myvims[datacenter_key] = vims.values()[0] + myvims[datacenter_key] = next(iter(vims.values())) myvim = myvims[datacenter_key] myvim_thread = myvim_threads[datacenter_key] @@ -4230,7 +4230,7 @@ def delete_instance(mydb, tenant_id, instance_id): logger.error("datacenter '{}' with datacenter_tenant_id '{}' not found".format(sfi["datacenter_id"], sfi["datacenter_tenant_id"])) myvims[datacenter_key] = None else: - myvims[datacenter_key] = vims.values()[0] + myvims[datacenter_key] = next(iter(vims.values())) myvim = myvims[datacenter_key] myvim_thread = myvim_threads[datacenter_key] @@ -4272,7 +4272,7 @@ def delete_instance(mydb, tenant_id, instance_id): sce_vnf["datacenter_tenant_id"])) myvims[datacenter_key] = None else: - myvims[datacenter_key] = vims.values()[0] + myvims[datacenter_key] = next(iter(vims.values())) myvim = myvims[datacenter_key] myvim_thread = myvim_threads[datacenter_key] @@ -4320,7 +4320,7 @@ def delete_instance(mydb, tenant_id, instance_id): logger.error("datacenter '{}' with datacenter_tenant_id '{}' not found".format(net["datacenter_id"], net["datacenter_tenant_id"])) myvims[datacenter_key] = None else: - myvims[datacenter_key] = vims.values()[0] + myvims[datacenter_key] = next(iter(vims.values())) myvim = myvims[datacenter_key] myvim_thread = myvim_threads[datacenter_key] @@ -4426,7 +4426,7 @@ def refresh_instance(mydb, nfvo_tenant, instanceDict, datacenter=None, vim_tenan # logger.error("datacenter '{}' with datacenter_tenant_id '{}' not found".format(sce_vnf["datacenter_id"], sce_vnf["datacenter_tenant_id"])) # myvims[datacenter_key] = None # else: - # myvims[datacenter_key] = vims.values()[0] + # myvims[datacenter_key] = next(iter(vims.values())) # for vm in sce_vnf['vms']: # vm_list[datacenter_key].append(vm['vim_vm_id']) # vms_notupdated.append(vm["uuid"]) @@ -4445,7 +4445,7 @@ def refresh_instance(mydb, nfvo_tenant, instanceDict, datacenter=None, vim_tenan # logger.error("datacenter '{}' with datacenter_tenant_id '{}' not found".format(net["datacenter_id"], net["datacenter_tenant_id"])) # myvims[datacenter_key] = None # else: - # myvims[datacenter_key] = vims.values()[0] + # myvims[datacenter_key] = next(iter(vims.values())) # # net_list[datacenter_key].append(net['vim_net_id']) # nets_notupdated.append(net["uuid"]) @@ -4571,7 +4571,7 @@ def instance_action(mydb,nfvo_tenant,instance_id, action_dict): vims = get_vim(mydb, nfvo_tenant, instanceDict['datacenter_id']) if len(vims) == 0: raise NfvoException("datacenter '{}' not found".format(str(instanceDict['datacenter_id'])), httperrors.Not_Found) - myvim = vims.values()[0] + myvim = next(iter(vims.values())) vm_result = {} vm_error = 0 vm_ok = 0 @@ -4782,7 +4782,7 @@ def instance_action(mydb,nfvo_tenant,instance_id, action_dict): try: if "add_public_key" in action_dict: if sce_vnf.get('mgmt_access'): - mgmt_access = yaml.load(sce_vnf['mgmt_access']) + mgmt_access = yaml.load(sce_vnf['mgmt_access'], Loader=yaml.Loader) if not input_vms and mgmt_access.get("vdu-id") != vm['vdu_osm_id']: continue default_user = mgmt_access.get("default-user") @@ -4939,17 +4939,11 @@ def new_datacenter(mydb, datacenter_descriptor): # Check that datacenter-type is correct datacenter_type = datacenter_descriptor.get("type", "openvim"); # module_info = None - try: - module = "vimconn_" + datacenter_type - pkg = __import__("osm_ro." + module) - # vim_conn = getattr(pkg, module) - # module_info = imp.find_module(module, [__file__[:__file__.rfind("/")]]) - except (IOError, ImportError): - # if module_info and module_info[0]: - # file.close(module_info[0]) - raise NfvoException("Incorrect datacenter type '{}'. Plugin '{}.py' not installed".format(datacenter_type, - module), - httperrors.Bad_Request) + + # load plugin + plugin_name = "rovim_" + datacenter_type + if plugin_name not in plugins: + _load_vim_plugin(plugin_name) datacenter_id = mydb.new_row("datacenters", datacenter_descriptor, add_uuid=True, confidential_data=True) if sdn_port_mapping: @@ -4988,7 +4982,7 @@ def edit_datacenter(mydb, datacenter_id_name, datacenter_descriptor): config_text = datacenter.get("config") if not config_text: config_text = '{}' - config_dict = yaml.load(config_text) + config_dict = yaml.load(config_text, Loader=yaml.Loader) config_dict.update(new_config_dict) # delete null fields for k in to_delete: @@ -5101,8 +5095,8 @@ def create_vim_account(mydb, nfvo_tenant, datacenter_id, name=None, vim_id=None, # create thread thread_name = get_non_used_vim_name(datacenter_name, datacenter_id, tenant_dict['name'], tenant_dict['uuid']) - new_thread = vim_thread.vim_thread(task_lock, thread_name, datacenter_name, datacenter_tenant_id, - db=db, db_lock=db_lock, ovim=ovim) + new_thread = vim_thread(task_lock, plugins, thread_name, datacenter_name, datacenter_tenant_id, + db=db, db_lock=db_lock, ovim=ovim) new_thread.start() thread_id = datacenter_tenants_dict["uuid"] vim_threads["running"][thread_id] = new_thread @@ -5131,7 +5125,7 @@ def edit_vim_account(mydb, nfvo_tenant, datacenter_tenant_id, datacenter_id=None update_ = {} if config: - original_config_dict = yaml.load(original_config) + original_config_dict = yaml.load(original_config, Loader=yaml.Loader) original_config_dict.update(config) update["config"] = yaml.safe_dump(original_config_dict, default_flow_style=True, width=256) if name: @@ -5366,7 +5360,7 @@ def get_sdn_controller_id(mydb, datacenter): if not config: return None - return yaml.load(config).get('sdn-controller') + return yaml.load(config, Loader=yaml.Loader).get('sdn-controller') def vim_net_sdn_attach(mydb, tenant_id, datacenter, network_id, descriptor): try: @@ -5482,12 +5476,12 @@ def vim_action_get(mydb, tenant_id, datacenter, item, name): if name and len(content)==1: return {item[:-1]: content[0]} elif name and len(content)==0: - raise NfvoException("No {} found with ".format(item[:-1]) + " and ".join(map(lambda x: str(x[0])+": "+str(x[1]), filter_dict.iteritems())), + raise NfvoException("No {} found with ".format(item[:-1]) + " and ".join(map(lambda x: str(x[0])+": "+str(x[1]), filter_dict.items())), datacenter) else: return {item: content} except vimconn.vimconnException as e: - print "vim_action Not possible to get_%s_list from VIM: %s " % (item, str(e)) + print("vim_action Not possible to get_{}_list from VIM: {} ".format(item, str(e))) raise NfvoException("Not possible to get_{}_list from VIM: {}".format(item, str(e)), e.http_code) @@ -5500,7 +5494,7 @@ def vim_action_delete(mydb, tenant_id, datacenter, item, name): #get uuid name content = vim_action_get(mydb, tenant_id, datacenter, item, name) logger.debug("vim_action_delete vim response: " + str(content)) - items = content.values()[0] + items = next(iter(content.values())) if type(items)==list and len(items)==0: raise NfvoException("Not found " + item, httperrors.Not_Found) elif type(items)==list and len(items)>1: @@ -5519,7 +5513,7 @@ def vim_action_delete(mydb, tenant_id, datacenter, item, name): port_list = ovim.get_ports(columns={'uuid'}, filter={'net_id': sdn_network_id}) except ovimException as e: raise NfvoException( - "ovimException obtaining external ports for net {}. ".format(network_id) + str(e), + "ovimException obtaining external ports for net {}. ".format(sdn_network_id) + str(e), httperrors.Internal_Server_Error) # By calling one by one all ports to be detached we ensure that not only the external_ports get detached @@ -5528,10 +5522,12 @@ def vim_action_delete(mydb, tenant_id, datacenter, item, name): #Delete from 'instance_nets' the correspondence between the vim-net-id and the sdn-net-id try: - mydb.delete_row(FROM='instance_nets', WHERE={'instance_scenario_id': None, 'sdn_net_id': sdn_network_id, 'vim_net_id': item_id}) + mydb.delete_row(FROM='instance_nets', WHERE={'instance_scenario_id': None, + 'sdn_net_id': sdn_network_id, + 'vim_net_id': item_id}) except db_base_Exception as e: - raise NfvoException("Error deleting correspondence for VIM/SDN dataplane networks{}: ".format(correspondence) + - str(e), e.http_code) + raise NfvoException("Error deleting correspondence for VIM/SDN dataplane networks{}: {}".format( + item_id, e), e.http_code) #Delete the SDN network try: @@ -5638,7 +5634,7 @@ def sdn_controller_delete(mydb, tenant_id, controller_id): datacenters = mydb.get_rows(FROM='datacenters', SELECT=select_) for datacenter in datacenters: if datacenter['config']: - config = yaml.load(datacenter['config']) + config = yaml.load(datacenter['config'], Loader=yaml.Loader) if 'sdn-controller' in config and config['sdn-controller'] == controller_id: raise NfvoException("SDN controller {} is in use by datacenter {}".format(controller_id, datacenter['uuid']), httperrors.Conflict) @@ -5653,7 +5649,7 @@ def datacenter_sdn_port_mapping_set(mydb, tenant_id, datacenter_id, sdn_port_map raise NfvoException("Datacenter {} not present in the database".format(datacenter_id), httperrors.Not_Found) try: - sdn_controller_id = yaml.load(controller[0]["config"])["sdn-controller"] + sdn_controller_id = yaml.load(controller[0]["config"], Loader=yaml.Loader)["sdn-controller"] except: raise NfvoException("The datacenter {} has not an SDN controller associated".format(datacenter_id), httperrors.Bad_Request) @@ -5689,7 +5685,7 @@ def datacenter_sdn_port_mapping_list(mydb, tenant_id, datacenter_id): datacenter = mydb.get_table_by_uuid_name('datacenters', datacenter_id) if datacenter['config']: - config = yaml.load(datacenter['config']) + config = yaml.load(datacenter['config'], Loader=yaml.Loader) if 'sdn-controller' in config: controller_id = config['sdn-controller'] sdn_controller = sdn_controller_list(mydb, tenant_id, controller_id) diff --git a/osm_ro/nfvo_db.py b/RO/osm_ro/nfvo_db.py similarity index 99% rename from osm_ro/nfvo_db.py rename to RO/osm_ro/nfvo_db.py index eb72b133..afd9d152 100644 --- a/osm_ro/nfvo_db.py +++ b/RO/osm_ro/nfvo_db.py @@ -27,16 +27,16 @@ NFVO DB engine. It implements all the methods to interact with the Openmano Data __author__="Alfonso Tierno, Gerardo Garcia, Pablo Montes" __date__ ="$28-aug-2014 10:05:01$" -import db_base +from osm_ro import db_base import MySQLdb as mdb import json import yaml import time #import sys, os -from .db_base import retry, with_transaction -from .http_tools import errors as httperrors -from .utils import Attempt +from osm_ro.db_base import retry, with_transaction +from osm_ro.http_tools import errors as httperrors +from osm_ro.utils import Attempt _ATTEMPT = Attempt() @@ -77,7 +77,7 @@ class nfvo_db(db_base.db_base): #print "Adding new vms to the NFVO database" #For each vm, we must create the appropriate vm in the NFVO database. vmDict = {} - for _,vm in VNFCDict.iteritems(): + for _,vm in VNFCDict.items(): #This code could make the name of the vms grow and grow. #If we agree to follow this convention, we should check with a regex that the vnfc name is not including yet the vnf name #vm['name'] = "%s-%s" % (vnf_name,vm['name']) @@ -222,7 +222,7 @@ class nfvo_db(db_base.db_base): #print "Adding new vms to the NFVO database" #For each vm, we must create the appropriate vm in the NFVO database. vmDict = {} - for _,vm in VNFCDict.iteritems(): + for _,vm in VNFCDict.items(): #This code could make the name of the vms grow and grow. #If we agree to follow this convention, we should check with a regex that the vnfc name is not including yet the vnf name #vm['name'] = "%s-%s" % (vnf_name,vm['name']) @@ -561,7 +561,7 @@ class nfvo_db(db_base.db_base): raise db_base.db_base_Exception("More than one scenario found with this criteria " + where_text, httperrors.Bad_Request) scenario_dict = rows[0] if scenario_dict["cloud_config"]: - scenario_dict["cloud-config"] = yaml.load(scenario_dict["cloud_config"]) + scenario_dict["cloud-config"] = yaml.load(scenario_dict["cloud_config"], Loader=yaml.Loader) del scenario_dict["cloud_config"] # sce_vnfs cmd = "SELECT uuid,name,member_vnf_index,vnf_id,description FROM sce_vnfs WHERE scenario_id='{}' "\ @@ -576,7 +576,7 @@ class nfvo_db(db_base.db_base): self.cur.execute(cmd) mgmt_access_dict = self.cur.fetchall() if mgmt_access_dict[0].get('mgmt_access'): - vnf['mgmt_access'] = yaml.load(mgmt_access_dict[0]['mgmt_access']) + vnf['mgmt_access'] = yaml.load(mgmt_access_dict[0]['mgmt_access'], Loader=yaml.Loader) else: vnf['mgmt_access'] = None # sce_interfaces @@ -824,7 +824,7 @@ class nfvo_db(db_base.db_base): net["vim_id_sites"]["datacenter_site_id"] = {datacenter_site_id: net['vim_id']} sce_net_id = net.get("uuid") - for datacenter_site_id,vim_id in net["vim_id_sites"].iteritems(): + for datacenter_site_id,vim_id in net["vim_id_sites"].items(): INSERT_={'vim_net_id': vim_id, 'created': net.get('created', False), 'instance_scenario_id':instance_uuid } #, 'type': net['type'] INSERT_['datacenter_id'] = datacenter_site_id INSERT_['datacenter_tenant_id'] = scenarioDict["datacenter2tenant"][datacenter_site_id] @@ -939,7 +939,7 @@ class nfvo_db(db_base.db_base): httperrors.Bad_Request) instance_dict = rows[0] if instance_dict["cloud_config"]: - instance_dict["cloud-config"] = yaml.load(instance_dict["cloud_config"]) + instance_dict["cloud-config"] = yaml.load(instance_dict["cloud_config"], Loader=yaml.Loader) del instance_dict["cloud_config"] # instance_vnfs @@ -957,7 +957,7 @@ class nfvo_db(db_base.db_base): vnf_mgmt_access_iface = None vnf_mgmt_access_vm = None if vnf["mgmt_access"]: - vnf_mgmt_access = yaml.load(vnf["mgmt_access"]) + vnf_mgmt_access = yaml.load(vnf["mgmt_access"], Loader=yaml.Loader) vnf_mgmt_access_iface = vnf_mgmt_access.get("interface_id") vnf_mgmt_access_vm = vnf_mgmt_access.get("vm_id") vnf["ip_address"] = vnf_mgmt_access.get("ip-address") diff --git a/osm_ro/openmano_schemas.py b/RO/osm_ro/openmano_schemas.py similarity index 100% rename from osm_ro/openmano_schemas.py rename to RO/osm_ro/openmano_schemas.py diff --git a/osm_ro/openmanoclient.py b/RO/osm_ro/openmanoclient.py similarity index 99% rename from osm_ro/openmanoclient.py rename to RO/osm_ro/openmanoclient.py index e15824ab..fc8bde11 100644 --- a/osm_ro/openmanoclient.py +++ b/RO/osm_ro/openmanoclient.py @@ -37,10 +37,7 @@ __date__ = "$09-Mar-2016 09:09:48$" __version__ = "0.1.0-r470" version_date = "Oct 2017" -if sys.version_info.major == 3: - from urllib.parse import quote -elif sys.version_info.major == 2: - from urllib import quote +from urllib.parse import quote class OpenmanoException(Exception): '''Common Exception for all openmano client exceptions''' @@ -96,7 +93,7 @@ class openmanoclient(): elif index=='endpoint_url': return self.endpoint_url else: - raise KeyError("Invalid key '%s'" %str(index)) + raise KeyError("Invalid key '{}'".format(index)) def __setitem__(self,index, value): if index=='tenant_name': @@ -114,7 +111,7 @@ class openmanoclient(): elif index=='endpoint_url': self.endpoint_url = value else: - raise KeyError("Invalid key '%s'" %str(index)) + raise KeyError("Invalid key '{}'".format(index)) self.tenant = None # force to reload tenant with different credentials self.datacenter = None # force to reload datacenter with different credentials @@ -124,7 +121,7 @@ class openmanoclient(): raise OpenmanoBadParamsException("'descriptor_format' must be a 'json' or 'yaml' text") if descriptor_format != "json": try: - return yaml.load(descriptor) + return yaml.load(descriptor, Loader=yaml.SafeLoader) except yaml.YAMLError as exc: error_pos = "" if hasattr(exc, 'problem_mark'): @@ -144,7 +141,7 @@ class openmanoclient(): def _parse_yaml(self, descriptor, response=False): try: - return yaml.load(descriptor) + return yaml.load(descriptor, Loader=yaml.SafeLoader) except yaml.YAMLError as exc: error_pos = "" if hasattr(exc, 'problem_mark'): diff --git a/osm_ro/openmanod.cfg b/RO/osm_ro/openmanod.cfg similarity index 100% rename from osm_ro/openmanod.cfg rename to RO/osm_ro/openmanod.cfg diff --git a/openmanod b/RO/osm_ro/openmanod.py similarity index 99% rename from openmanod rename to RO/osm_ro/openmanod.py index ecd99720..cdf451a1 100755 --- a/openmanod +++ b/RO/osm_ro/openmanod.py @@ -53,8 +53,8 @@ import osm_ro __author__ = "Alfonso Tierno, Gerardo Garcia, Pablo Montes" __date__ = "$26-aug-2014 11:09:29$" -__version__ = "6.0.2.post2" -version_date = "Sep 2019" +__version__ = "6.0.3.post5" +version_date = "Oct 2019" database_version = 39 # expected database schema version global global_config @@ -81,7 +81,7 @@ def load_configuration(configuration_file): with open(configuration_file, 'r') as f: config_str = f.read() # Parse configuration file - config = yaml.load(config_str) + config = yaml.load(config_str, Loader=yaml.SafeLoader) # Validate configuration file with the config_schema js_v(config, config_schema) @@ -191,7 +191,7 @@ if __name__ == "__main__": "log-socket-host=", "log-socket-port=", "log-file=", "create-tenant="]) port = None port_admin = None - config_file = 'osm_ro/openmanod.cfg' + config_file = 'openmanod.cfg' vnf_repository = None log_file = None log_socket_host = None diff --git a/osm_ro/osm-ro.service b/RO/osm_ro/osm-ro.service similarity index 100% rename from osm_ro/osm-ro.service rename to RO/osm_ro/osm-ro.service diff --git a/scripts/RO-of b/RO/osm_ro/scripts/RO-of similarity index 100% rename from scripts/RO-of rename to RO/osm_ro/scripts/RO-of diff --git a/scripts/RO-start.sh b/RO/osm_ro/scripts/RO-start.sh similarity index 74% rename from scripts/RO-start.sh rename to RO/osm_ro/scripts/RO-start.sh index 47547cdd..1a8750dc 100755 --- a/scripts/RO-start.sh +++ b/RO/osm_ro/scripts/RO-start.sh @@ -92,7 +92,7 @@ wait_db "$RO_DB_HOST" "$RO_DB_PORT" || exit 1 echo "3/4 Init database" -RO_PATH=`python -c 'import osm_ro; print(osm_ro.__path__[0])'` +RO_PATH=`python3 -c 'import osm_ro; print(osm_ro.__path__[0])'` echo "RO_PATH: $RO_PATH" if ! is_db_created "$RO_DB_HOST" "$RO_DB_PORT" "$RO_DB_USER" "$RO_DB_PASSWORD" "$RO_DB_NAME" "27" then @@ -111,34 +111,35 @@ else -P "$RO_DB_PORT" -d "$RO_DB_NAME" -b /var/log/osm fi -OVIM_PATH=`python -c 'import lib_osm_openvim; print(lib_osm_openvim.__path__[0])'` -echo "OVIM_PATH: $OVIM_PATH" -if ! is_db_created "$RO_DB_OVIM_HOST" "$RO_DB_OVIM_PORT" "$RO_DB_OVIM_USER" "$RO_DB_OVIM_PASSWORD" "$RO_DB_OVIM_NAME" \ - "22" -then - if [ -n "$RO_DB_OVIM_ROOT_PASSWORD" ] ; then - mysqladmin -h"$RO_DB_OVIM_HOST" -uroot -p"$RO_DB_OVIM_ROOT_PASSWORD" create "$RO_DB_OVIM_NAME" - echo "CREATE USER '${RO_DB_OVIM_USER}'@'%' IDENTIFIED BY '${RO_DB_OVIM_PASSWORD}';" | - mysql -h"$RO_DB_OVIM_HOST" -uroot -p"$RO_DB_OVIM_ROOT_PASSWORD" || - echo "user ${RO_DB_OVIM_USER} already created?" - echo "GRANT ALL PRIVILEGES ON ${RO_DB_OVIM_NAME}.* TO '${RO_DB_OVIM_USER}'@'%';" | - mysql -h"$RO_DB_OVIM_HOST" -uroot -p"$RO_DB_OVIM_ROOT_PASSWORD" || - echo "user ${RO_DB_OVIM_USER} already granted?" - fi - ${OVIM_PATH}/database_utils/init_vim_db.sh -u "$RO_DB_OVIM_USER" -p "$RO_DB_OVIM_PASSWORD" -h "$RO_DB_OVIM_HOST" \ - -P "${RO_DB_OVIM_PORT}" -d "${RO_DB_OVIM_NAME}" || exit 1 -else - echo " migrate database version" - ${OVIM_PATH}/database_utils/migrate_vim_db.sh -u "$RO_DB_OVIM_USER" -p "$RO_DB_OVIM_PASSWORD" -h "$RO_DB_OVIM_HOST"\ - -P "$RO_DB_OVIM_PORT" -d "$RO_DB_OVIM_NAME" -b /var/log/osm -fi - +# TODO py3 BEGIN +#OVIM_PATH=`python3 -c 'import lib_osm_openvim; print(lib_osm_openvim.__path__[0])'` +#echo "OVIM_PATH: $OVIM_PATH" +#if ! is_db_created "$RO_DB_OVIM_HOST" "$RO_DB_OVIM_PORT" "$RO_DB_OVIM_USER" "$RO_DB_OVIM_PASSWORD" "$RO_DB_OVIM_NAME" \ +# "22" +#then +# if [ -n "$RO_DB_OVIM_ROOT_PASSWORD" ] ; then +# mysqladmin -h"$RO_DB_OVIM_HOST" -uroot -p"$RO_DB_OVIM_ROOT_PASSWORD" create "$RO_DB_OVIM_NAME" +# echo "CREATE USER '${RO_DB_OVIM_USER}'@'%' IDENTIFIED BY '${RO_DB_OVIM_PASSWORD}';" | +# mysql -h"$RO_DB_OVIM_HOST" -uroot -p"$RO_DB_OVIM_ROOT_PASSWORD" || +# echo "user ${RO_DB_OVIM_USER} already created?" +# echo "GRANT ALL PRIVILEGES ON ${RO_DB_OVIM_NAME}.* TO '${RO_DB_OVIM_USER}'@'%';" | +# mysql -h"$RO_DB_OVIM_HOST" -uroot -p"$RO_DB_OVIM_ROOT_PASSWORD" || +# echo "user ${RO_DB_OVIM_USER} already granted?" +# fi +# ${OVIM_PATH}/database_utils/init_vim_db.sh -u "$RO_DB_OVIM_USER" -p "$RO_DB_OVIM_PASSWORD" -h "$RO_DB_OVIM_HOST" \ +# -P "${RO_DB_OVIM_PORT}" -d "${RO_DB_OVIM_NAME}" || exit 1 +#else +# echo " migrate database version" +# ${OVIM_PATH}/database_utils/migrate_vim_db.sh -u "$RO_DB_OVIM_USER" -p "$RO_DB_OVIM_PASSWORD" -h "$RO_DB_OVIM_HOST"\ +# -P "$RO_DB_OVIM_PORT" -d "$RO_DB_OVIM_NAME" -b /var/log/osm +#fi +# TODO py3 END echo "4/4 Try to start" # look for openmanod.cfg RO_CONFIG_FILE="/etc/osm/openmanod.cfg" -[ -f "$RO_CONFIG_FILE" ] || RO_CONFIG_FILE=$(python -c 'import osm_ro; print(osm_ro.__path__[0])')/openmanod.cfg +[ -f "$RO_CONFIG_FILE" ] || RO_CONFIG_FILE=$(python3 -c 'import osm_ro; print(osm_ro.__path__[0])')/openmanod.cfg [ -f "$RO_CONFIG_FILE" ] || ! echo "configuration file 'openmanod.cfg' not found" || exit 1 -openmanod -c "$RO_CONFIG_FILE" --create-tenant=osm # --log-file=/var/log/osm/openmano.log +python3 -m osm_ro.openmanod -c "$RO_CONFIG_FILE" --create-tenant=osm # --log-file=/var/log/osm/openmano.log diff --git a/scripts/get-options.sh b/RO/osm_ro/scripts/get-options.sh similarity index 100% rename from scripts/get-options.sh rename to RO/osm_ro/scripts/get-options.sh diff --git a/scripts/install-lib-osm-openvim.sh b/RO/osm_ro/scripts/install-lib-osm-openvim.sh similarity index 98% rename from scripts/install-lib-osm-openvim.sh rename to RO/osm_ro/scripts/install-lib-osm-openvim.sh index c1374d50..93df95e4 100755 --- a/scripts/install-lib-osm-openvim.sh +++ b/RO/osm_ro/scripts/install-lib-osm-openvim.sh @@ -21,6 +21,8 @@ # author: Alfonso Tierno +exit 0 # TODO py3 for the moment no openvim library is installed + # It uses following env, if not provided filling by default [ -z "$GIT_OVIM_URL" ] && GIT_OVIM_URL=https://osm.etsi.org/gerrit/osm/openvim.git [ -z "$DEVELOP" ] && DEVELOP="" diff --git a/scripts/install-openmano-service.sh b/RO/osm_ro/scripts/install-openmano-service.sh similarity index 100% rename from scripts/install-openmano-service.sh rename to RO/osm_ro/scripts/install-openmano-service.sh diff --git a/scripts/install-openmano.sh b/RO/osm_ro/scripts/install-openmano.sh similarity index 100% rename from scripts/install-openmano.sh rename to RO/osm_ro/scripts/install-openmano.sh diff --git a/scripts/install-osm-im.sh b/RO/osm_ro/scripts/install-osm-im.sh similarity index 93% rename from scripts/install-osm-im.sh rename to RO/osm_ro/scripts/install-osm-im.sh index 2fad2145..8f733ce5 100755 --- a/scripts/install-osm-im.sh +++ b/RO/osm_ro/scripts/install-osm-im.sh @@ -25,7 +25,7 @@ [ -z "$GIT_OSMIM_URL" ] && GIT_OSMIM_URL=https://osm.etsi.org/gerrit/osm/IM.git [ -z "$DEVELOP" ] && DEVELOP="" # folder where RO is installed -[ -z "$BASEFOLDER" ] && HERE=$(dirname $(readlink -f ${BASH_SOURCE[0]})) && BASEFOLDER=$(dirname $HERE) +[ -z "$BASEFOLDER" ] && HERE=$(dirname $(readlink -f ${BASH_SOURCE[0]})) && BASEFOLDER=$(dirname $(dirname $HERE)) [ -z "$SUDO_USER" ] && SUDO_USER="$USER" [ -z "$NO_PACKAGES" ] && NO_PACKAGES="" [ -z "$_DISTRO" ] && _DISTRO="Ubuntu" @@ -96,10 +96,10 @@ then # apt-get update # apt-get install -y git python-pip # pip2 install pip==9.0.3 - pip2 install pyangbind || exit 1 + python3 -m pip install pyangbind || exit 1 fi -PYBINDPLUGIN=$(python2 -c 'import pyangbind; import os; print "%s/plugin" % os.path.dirname(pyangbind.__file__)') +PYBINDPLUGIN=$(python3 -c 'import pyangbind; import os; print(os.path.dirname(pyangbind.__file__)+"/plugin")') su $SUDO_USER -c 'mkdir -p "'${BASEFOLDER}/IM/osm_im'"' su $SUDO_USER -c 'touch "'${BASEFOLDER}/IM/osm_im/__init__.py'"' # wget -q https://raw.githubusercontent.com/RIFTIO/RIFT.ware/RIFT.ware-4.4.1/modules/core/util/yangtools/yang/rw-pb-ext.yang -O "${BASEFOLDER}/IM/models/yang/rw-pb-ext.yang" @@ -108,4 +108,4 @@ for target in vnfd nsd ; do -o "${BASEFOLDER}/IM/osm_im/${target}.py" "${BASEFOLDER}/IM/models/yang/${target}.yang" done -pip2 install -e "${BASEFOLDER}/IM" || ! echo "ERROR installing python-osm-im library!!!" >&2 || exit 1 +python3 -m pip install -e "${BASEFOLDER}/IM" || ! echo "ERROR installing python-osm-im library!!!" >&2 || exit 1 diff --git a/scripts/openmano-report b/RO/osm_ro/scripts/openmano-report similarity index 100% rename from scripts/openmano-report rename to RO/osm_ro/scripts/openmano-report diff --git a/scripts/service-openmano b/RO/osm_ro/scripts/service-openmano similarity index 100% rename from scripts/service-openmano rename to RO/osm_ro/scripts/service-openmano diff --git a/osm_ro/tests/__init__.py b/RO/osm_ro/tests/__init__.py similarity index 100% rename from osm_ro/tests/__init__.py rename to RO/osm_ro/tests/__init__.py diff --git a/osm_ro/tests/db_helpers.py b/RO/osm_ro/tests/db_helpers.py similarity index 100% rename from osm_ro/tests/db_helpers.py rename to RO/osm_ro/tests/db_helpers.py diff --git a/osm_ro/tests/helpers.py b/RO/osm_ro/tests/helpers.py similarity index 98% rename from osm_ro/tests/helpers.py rename to RO/osm_ro/tests/helpers.py index 787fbced..011e8803 100644 --- a/osm_ro/tests/helpers.py +++ b/RO/osm_ro/tests/helpers.py @@ -36,9 +36,9 @@ import logging import unittest from collections import defaultdict -from six import StringIO +from io import StringIO -from mock import MagicMock, patch +from unittest.mock import MagicMock, patch logger = logging.getLogger() diff --git a/osm_ro/tests/test_db.py b/RO/osm_ro/tests/test_db.py similarity index 99% rename from osm_ro/tests/test_db.py rename to RO/osm_ro/tests/test_db.py index e152347e..5e90bd97 100644 --- a/osm_ro/tests/test_db.py +++ b/RO/osm_ro/tests/test_db.py @@ -3,8 +3,6 @@ import unittest from MySQLdb import connect, cursors, DatabaseError, IntegrityError -import mock -from mock import Mock from ..db_base import retry, with_transaction from ..nfvo_db import nfvo_db diff --git a/osm_ro/tests/test_utils.py b/RO/osm_ro/tests/test_utils.py similarity index 100% rename from osm_ro/tests/test_utils.py rename to RO/osm_ro/tests/test_utils.py diff --git a/osm_ro/utils.py b/RO/osm_ro/utils.py similarity index 87% rename from osm_ro/utils.py rename to RO/osm_ro/utils.py index 625ff6dd..ac291c1d 100644 --- a/osm_ro/utils.py +++ b/RO/osm_ro/utils.py @@ -35,16 +35,12 @@ import warnings from functools import reduce, partial, wraps from itertools import tee -import six -from six.moves import filter, filterfalse +from itertools import filterfalse from jsonschema import exceptions as js_e from jsonschema import validate as js_v -if six.PY3: - from inspect import getfullargspec as getspec -else: - from inspect import getargspec as getspec +from inspect import getfullargspec as getspec #from bs4 import BeautifulSoup @@ -77,28 +73,31 @@ def format_in(http_response, schema): #print "Input data: ", str(client_data) return True, client_data except js_e.ValidationError as exc: - print "validate_in error, jsonschema exception ", exc.message, "at", exc.path + print("validate_in error, jsonschema exception ", exc.message, "at", exc.path) return False, ("validate_in error, jsonschema exception ", exc.message, "at", exc.path) def remove_extra_items(data, schema): deleted = [] - if type(data) is tuple or type(data) is list: + if isinstance(data, (tuple, list)): for d in data: a = remove_extra_items(d, schema['items']) - if a is not None: + if a: deleted.append(a) - elif type(data) is dict: + elif isinstance(data, dict): # TODO deal with patternProperties if 'properties' not in schema: return None + to_delete = [] for k in data.keys(): - if k in schema['properties'].keys(): + if k in schema['properties']: a = remove_extra_items(data[k], schema['properties'][k]) - if a is not None: + if a: deleted.append({k: a}) elif not schema.get('additionalProperties'): - del data[k] + to_delete.append(k) deleted.append(k) + for k in to_delete: + del data[k] if len(deleted) == 0: return None elif len(deleted) == 1: @@ -113,16 +112,24 @@ def remove_extra_items(data, schema): def delete_nulls(var): - if type(var) is dict: + if isinstance(var, dict): + to_delete = [] for k in var.keys(): - if var[k] is None: del var[k] - elif type(var[k]) is dict or type(var[k]) is list or type(var[k]) is tuple: - if delete_nulls(var[k]): del var[k] - if len(var) == 0: return True - elif type(var) is list or type(var) is tuple: + if var[k] is None: + to_delete.append([k]) + elif isinstance(var[k], (dict, list, tuple)): + if delete_nulls(var[k]): + to_delete.append(k) + for k in to_delete: + del var[k] + if len(var) == 0: + return True + elif isinstance(var, (list, tuple)): for k in var: - if type(k) is dict: delete_nulls(k) - if len(var) == 0: return True + if isinstance(k, dict): + delete_nulls(k) + if len(var) == 0: + return True return False @@ -135,9 +142,9 @@ def convert_bandwidth(data, reverse=False): Return: None ''' - if type(data) is dict: + if isinstance(data, dict): for k in data.keys(): - if type(data[k]) is dict or type(data[k]) is tuple or type(data[k]) is list: + if isinstance(data[k], (dict, tuple, list)): convert_bandwidth(data[k], reverse) if "bandwidth" in data: try: @@ -145,19 +152,24 @@ def convert_bandwidth(data, reverse=False): if not reverse: pos = value.find("bps") if pos>0: - if value[pos-1]=="G": data["bandwidth"] = int(data["bandwidth"][:pos-1]) * 1000 - elif value[pos-1]=="k": data["bandwidth"]= int(data["bandwidth"][:pos-1]) / 1000 - else: data["bandwidth"]= int(data["bandwidth"][:pos-1]) + if value[pos-1]=="G": + data["bandwidth"] = int(data["bandwidth"][:pos-1]) * 1000 + elif value[pos-1]=="k": + data["bandwidth"]= int(data["bandwidth"][:pos-1]) // 1000 + else: + data["bandwidth"]= int(data["bandwidth"][:pos]) else: value = int(data["bandwidth"]) - if value % 1000 == 0: data["bandwidth"]=str(value/1000) + " Gbps" - else: data["bandwidth"]=str(value) + " Mbps" + if value % 1000 == 0 and value > 1000: + data["bandwidth"] = str(value // 1000) + " Gbps" + else: + data["bandwidth"] = str(value) + " Mbps" except: - print "convert_bandwidth exception for type", type(data["bandwidth"]), " data", data["bandwidth"] + print("convert_bandwidth exception for type", type(data["bandwidth"]), " data", data["bandwidth"]) return - if type(data) is tuple or type(data) is list: + if isinstance(data, (tuple, list)): for k in data: - if type(k) is dict or type(k) is tuple or type(k) is list: + if isinstance(k, (dict, tuple, list)): convert_bandwidth(k, reverse) def convert_float_timestamp2str(var): diff --git a/osm_ro/vim_thread.py b/RO/osm_ro/vim_thread.py similarity index 97% rename from osm_ro/vim_thread.py rename to RO/osm_ro/vim_thread.py index 38a73d12..1e1e6d20 100644 --- a/osm_ro/vim_thread.py +++ b/RO/osm_ro/vim_thread.py @@ -78,34 +78,20 @@ The task content is (M: stored at memory, D: stored at database): import threading import time -import Queue +import queue import logging -import vimconn -import vimconn_openvim -import vimconn_aws -import vimconn_opennebula -import vimconn_openstack -import vimconn_vmware -import vimconn_fos -import vimconn_azure +from osm_ro import vimconn import yaml -from db_base import db_base_Exception -from lib_osm_openvim.ovim import ovimException +from osm_ro.db_base import db_base_Exception +# TODO py3 BEGIN +class ovimException(Exception): + pass +# TODO py3 END from copy import deepcopy __author__ = "Alfonso Tierno, Pablo Montes" __date__ = "$28-Sep-2017 12:07:15$" -vim_module = { - "openvim": vimconn_openvim, - "aws": vimconn_aws, - "opennebula": vimconn_opennebula, - "openstack": vimconn_openstack, - "vmware": vimconn_vmware, - "fos": vimconn_fos, - "azure": vimconn_azure, -} - def is_task_id(task_id): return task_id.startswith("TASK-") @@ -125,7 +111,7 @@ class vim_thread(threading.Thread): REFRESH_ERROR = 600 REFRESH_DELETE = 3600 * 10 - def __init__(self, task_lock, name=None, datacenter_name=None, datacenter_tenant_id=None, + def __init__(self, task_lock, plugins, name=None, datacenter_name=None, datacenter_tenant_id=None, db=None, db_lock=None, ovim=None): """Init a thread. Arguments: @@ -135,6 +121,7 @@ class vim_thread(threading.Thread): 'db', 'db_lock': database class and lock to use it in exclusion """ threading.Thread.__init__(self) + self.plugins = plugins self.vim = None self.error_status = None self.datacenter_name = datacenter_name @@ -152,7 +139,7 @@ class vim_thread(threading.Thread): self.db_lock = db_lock self.task_lock = task_lock - self.task_queue = Queue.Queue(2000) + self.task_queue = queue.Queue(2000) def get_vimconnector(self): try: @@ -166,9 +153,9 @@ class vim_thread(threading.Thread): vim = vims[0] vim_config = {} if vim["config"]: - vim_config.update(yaml.load(vim["config"])) + vim_config.update(yaml.load(vim["config"], Loader=yaml.Loader)) if vim["dt_config"]: - vim_config.update(yaml.load(vim["dt_config"])) + vim_config.update(yaml.load(vim["dt_config"], Loader=yaml.Loader)) vim_config['datacenter_tenant_id'] = vim.get('datacenter_tenant_id') vim_config['datacenter_id'] = vim.get('datacenter_id') @@ -177,7 +164,7 @@ class vim_thread(threading.Thread): vim_config["wim_external_ports"] = self.ovim.get_of_port_mappings( db_filter={"region": vim_config['datacenter_id'], "pci": None}) - self.vim = vim_module[vim["type"]].vimconnector( + self.vim = self.plugins["rovim_" + vim["type"]].vimconnector( uuid=vim['datacenter_id'], name=vim['datacenter_name'], tenant_id=vim['vim_tenant_id'], tenant_name=vim['vim_tenant_name'], url=vim['vim_url'], url_admin=vim['vim_url_admin'], @@ -260,7 +247,7 @@ class vim_thread(threading.Thread): task["params"] = None if task["extra"]: - extra = yaml.load(task["extra"]) + extra = yaml.load(task["extra"], Loader=yaml.Loader) else: extra = {} task["extra"] = extra @@ -310,7 +297,7 @@ class vim_thread(threading.Thread): task_create = related_task # TASK_CREATE if related_task["extra"]: - extra_created = yaml.load(related_task["extra"]) + extra_created = yaml.load(related_task["extra"], Loader=yaml.Loader) if extra_created.get("created"): deletion_needed = True related_task["extra"] = extra_created @@ -329,7 +316,7 @@ class vim_thread(threading.Thread): return elif dependency_task: # move create information from task_create to relate_task - extra_new_created = yaml.load(dependency_task["extra"]) or {} + extra_new_created = yaml.load(dependency_task["extra"], Loader=yaml.Loader) or {} extra_new_created["created"] = extra_created["created"] copy_extra_created(copy_to=extra_new_created, copy_from=extra_created) @@ -575,7 +562,7 @@ class vim_thread(threading.Thread): task["status"] = related_tasks[0]["status"] task["error_msg"] = related_tasks[0]["error_msg"] task["vim_id"] = related_tasks[0]["vim_id"] - extra = yaml.load(related_tasks[0]["extra"]) + extra = yaml.load(related_tasks[0]["extra"], Loader=yaml.Loader) task["extra"]["vim_status"] = extra.get("vim_status") next_refresh = related_tasks[0]["modified_at"] + 0.001 database_update = {"status": task["extra"].get("vim_status", "VIM_ERROR"), @@ -721,7 +708,7 @@ class vim_thread(threading.Thread): try: self.task_queue.put(task, False) return None - except Queue.Full: + except queue.Full: raise vimconn.vimconnException(self.name + ": timeout inserting a task") def del_task(self, task): @@ -794,7 +781,7 @@ class vim_thread(threading.Thread): task["params"] = None task["depends"] = {} if task["extra"]: - extra = yaml.load(task["extra"]) + extra = yaml.load(task["extra"], Loader=yaml.Loader) task["extra"] = extra task["params"] = extra.get("params") else: @@ -1067,12 +1054,12 @@ class vim_thread(threading.Thread): egress_interface_id = task.get("extra").get("params").get("egress_interface_id") ingress_vim_interface_id = None egress_vim_interface_id = None - for vim_interface, interface_data in interfaces.iteritems(): + for vim_interface, interface_data in interfaces.items(): if interface_data.get("interface_id") == ingress_interface_id: ingress_vim_interface_id = vim_interface break if ingress_interface_id != egress_interface_id: - for vim_interface, interface_data in interfaces.iteritems(): + for vim_interface, interface_data in interfaces.items(): if interface_data.get("interface_id") == egress_interface_id: egress_vim_interface_id = vim_interface break @@ -1091,7 +1078,7 @@ class vim_thread(threading.Thread): # only the first ingress and first egress ports will be used to create the SFI (Port Pair). ingress_port_id_list = [ingress_vim_interface_id] egress_port_id_list = [egress_vim_interface_id] - name = "sfi-%s" % task["item_id"][:8] + name = "sfi-{}".format(task["item_id"][:8]) # By default no form of IETF SFC Encapsulation will be used vim_sfi_id = self.vim.new_sfi(name, ingress_port_id_list, egress_port_id_list, sfc_encap=False) @@ -1135,12 +1122,12 @@ class vim_thread(threading.Thread): task_id = task["instance_action_id"] + "." + str(task["task_index"]) error_text = "" depending_tasks = ["TASK-" + str(dep_id) for dep_id in task["extra"]["depends_on"]] - # sfis = task.get("depends").values()[0].get("extra").get("params")[5] + # sfis = next(iter(task.get("depends").values())).get("extra").get("params")[5] sfis = [task.get("depends").get(dep_task) for dep_task in depending_tasks] sfi_id_list = [] for sfi in sfis: sfi_id_list.append(sfi.get("vim_id")) - name = "sf-%s" % task["item_id"][:8] + name = "sf-{}".format(task["item_id"][:8]) # By default no form of IETF SFC Encapsulation will be used vim_sf_id = self.vim.new_sf(name, sfi_id_list, sfc_encap=False) @@ -1191,7 +1178,7 @@ class vim_thread(threading.Thread): # to create the Classification(s) (the "logical source port" of the "Flow Classifier"). # Since the VNFFG classifier match lacks the ethertype, classification defaults to # using the IPv4 flow classifier. - name = "c-%s" % task["item_id"][:8] + name = "c-{}".format(task["item_id"][:8]) # if not CIDR is given for the IP addresses, add /32: ip_proto = int(params.get("ip_proto")) source_ip = params.get("source_ip") @@ -1277,7 +1264,7 @@ class vim_thread(threading.Thread): elif resource == "instance_classifications": classification_id_list.append(vim_id) - name = "sfp-%s" % task["item_id"][:8] + name = "sfp-{}".format(task["item_id"][:8]) # By default no form of IETF SFC Encapsulation will be used vim_sfp_id = self.vim.new_sfp(name, classification_id_list, sf_id_list, sfc_encap=False) diff --git a/osm_ro/vimconn.py b/RO/osm_ro/vimconn.py similarity index 99% rename from osm_ro/vimconn.py rename to RO/osm_ro/vimconn.py index 957c4107..6e20654c 100644 --- a/osm_ro/vimconn.py +++ b/RO/osm_ro/vimconn.py @@ -29,12 +29,12 @@ vimconn implement an Abstract class for the vim connector plugins import logging import paramiko import socket -import StringIO +from io import StringIO import yaml import sys from email.mime.multipart import MIMEMultipart from email.mime.text import MIMEText -from utils import deprecated +from osm_ro.utils import deprecated __author__ = "Alfonso Tierno, Igor D.C." __date__ = "$14-aug-2017 23:59:59$" @@ -635,12 +635,12 @@ class vimconnector(): elif not ro_key and not password: raise vimconnNotSupportedException("All parameters should be different from 'None'") else: - commands = {'mkdir -p ~/.ssh/', 'echo "%s" >> ~/.ssh/authorized_keys' % key, + commands = {'mkdir -p ~/.ssh/', 'echo "{}" >> ~/.ssh/authorized_keys'.format(key), 'chmod 644 ~/.ssh/authorized_keys', 'chmod 700 ~/.ssh/'} client = paramiko.SSHClient() try: if ro_key: - pkey = paramiko.RSAKey.from_private_key(StringIO.StringIO(ro_key)) + pkey = paramiko.RSAKey.from_private_key(StringIO(ro_key)) else: pkey = None client.set_missing_host_key_policy(paramiko.AutoAddPolicy()) diff --git a/osm_ro/vmwarecli.py b/RO/osm_ro/vmwarecli.py similarity index 95% rename from osm_ro/vmwarecli.py rename to RO/osm_ro/vmwarecli.py index 80fe3949..b7b27428 100755 --- a/osm_ro/vmwarecli.py +++ b/RO/osm_ro/vmwarecli.py @@ -67,17 +67,17 @@ import sys from pyvcloud import Http import logging -import vimconn +from osm_ro import vimconn import time import uuid import urllib3 import requests -from vimconn_vmware import vimconnector -from requests.packages.urllib3.exceptions import InsecureRequestWarning +from osm_ro.vimconn_vmware import vimconnector +# TODO py3 uncoment from requests.packages.urllib3.exceptions import InsecureRequestWarning from prettytable import PrettyTable -requests.packages.urllib3.disable_warnings(InsecureRequestWarning) +# TODO py3 uncoment requests.packages.urllib3.disable_warnings(InsecureRequestWarning) __author__ = "Mustafa Bayramov" __date__ = "$16-Sep-2016 11:09:29$" @@ -108,7 +108,7 @@ def delete_network_action(vca=None, network_uuid=None): verify=vca.verify, logger=vca.logger) if response.status_code == requests.codes.ok: - print response.content + print(response.content) return response.content return None @@ -161,7 +161,7 @@ def print_vapp(vapp_dict=None): vm_table.add_row(entry) - print vm_table + print(vm_table) def print_org(org_dict=None): @@ -182,7 +182,7 @@ def print_org(org_dict=None): entry = [k, org_dict[k]] org_table.add_row(entry) - print org_table + print(org_table) def print_vm_list(vm_dict=None): @@ -213,7 +213,7 @@ def print_vm_list(vm_dict=None): entry.append(vm_dict[k]['memoryMB']) entry.append(vm_dict[k]['status']) vm_table.add_row(entry) - print vm_table + print(vm_table) except KeyError: logger.error("wrong key {}".format(KeyError.message)) pass @@ -232,14 +232,14 @@ def print_vdc_list(org_dict=None): return try: vdcs_dict = {} - if org_dict.has_key('vdcs'): + if 'vdcs' in org_dict: vdcs_dict = org_dict['vdcs'] vdc_table = PrettyTable(['vdc uuid', 'vdc name']) for k in vdcs_dict: entry = [k, vdcs_dict[k]] vdc_table.add_row(entry) - print vdc_table + print(vdc_table) except KeyError: logger.error("wrong key {}".format(KeyError.message)) logger.logger.debug(traceback.format_exc()) @@ -259,14 +259,14 @@ def print_network_list(org_dict=None): return try: network_dict = {} - if org_dict.has_key('networks'): + if 'networks' in org_dict: network_dict = org_dict['networks'] network_table = PrettyTable(['network uuid', 'network name']) for k in network_dict: entry = [k, network_dict[k]] network_table.add_row(entry) - print network_table + print(network_table) except KeyError: logger.error("wrong key {}".format(KeyError.message)) @@ -290,7 +290,7 @@ def print_org_details(org_dict=None): print_vdc_list(org_dict=org_dict) print_network_list(org_dict=org_dict) - if org_dict.has_key('catalogs'): + if 'catalogs' in org_dict: catalogs_dict = org_dict['catalogs'] catalog_table = PrettyTable(['catalog uuid', 'catalog name']) @@ -298,7 +298,7 @@ def print_org_details(org_dict=None): entry = [k, catalogs_dict[k]] catalog_table.add_row(entry) - print catalog_table + print(catalog_table) except KeyError: logger.error("wrong key {}".format(KeyError.message)) @@ -369,9 +369,9 @@ def list_actions(vim=None, action=None, namespace=None): def print_network_details(network_dict=None): try: network_table = PrettyTable(network_dict.keys()) - entry = [network_dict.values()] + entry = list(network_dict.values()) network_table.add_row(entry[0]) - print network_table + print(network_table) except KeyError: logger.error("wrong key {}".format(KeyError.message)) logger.logger.debug(traceback.format_exc()) @@ -382,9 +382,9 @@ def osm_print(generic_dict=None): try: for element in generic_dict: table = PrettyTable(element.keys()) - entry = [element.values()] + entry = list(element.values()) table.add_row(entry[0]) - print table + print(table) except KeyError: logger.error("wrong key {}".format(KeyError.message)) logger.logger.debug(traceback.format_exc()) @@ -433,10 +433,10 @@ def view_actions(vim=None, action=None, namespace=None): print("Can't find vapp by given name {}".format(namespace.vapp_name)) return - print " namespace {}".format(namespace) + print(" namespace {}".format(namespace)) if vapp_dict is not None and namespace.osm: vm_info_dict = vim.get_vminstance(vim_vm_uuid=vapp_uuid) - print vm_info_dict + print(vm_info_dict) if vapp_dict is not None and namespace.osm != True: vapp_dict = vim.get_vapp(vdc_name=namespace.vcdvdc, vapp_name=vapp_uuid, isuuid=True) print_vapp(vapp_dict=vapp_dict) @@ -448,7 +448,7 @@ def view_actions(vim=None, action=None, namespace=None): # if request name based we need find UUID # TODO optimize it or move to external function if not namespace.uuid: - if not myorg.has_key('networks'): + if 'networks' not in myorg: print("Network {} is undefined in vcloud director for org {} vdc {}".format(namespace.network_name, vim.name, vim.tenant_name)) @@ -460,7 +460,7 @@ def view_actions(vim=None, action=None, namespace=None): network_uuid = network break - print print_network_details(network_dict=vim.get_vcd_network(network_uuid=network_uuid)) + print(print_network_details(network_dict=vim.get_vcd_network(network_uuid=network_uuid))) def create_actions(vim=None, action=None, namespace=None): @@ -477,16 +477,16 @@ def create_actions(vim=None, action=None, namespace=None): logger.debug("Creating a network in vcloud director".format(namespace.network_name)) network_uuid = vim.create_network(namespace.network_name) if network_uuid is not None: - print ("Crated new network {} and uuid: {}".format(namespace.network_name, network_uuid)) + print("Crated new network {} and uuid: {}".format(namespace.network_name, network_uuid)) else: - print ("Failed create a new network {}".format(namespace.network_name)) + print("Failed create a new network {}".format(namespace.network_name)) elif action == 'vdc' or namespace.action == 'vdc': logger.debug("Creating a new vdc in vcloud director.".format(namespace.vdc_name)) vdc_uuid = vim.create_vdc(namespace.vdc_name) if vdc_uuid is not None: - print ("Crated new vdc {} and uuid: {}".format(namespace.vdc_name, vdc_uuid)) + print("Crated new vdc {} and uuid: {}".format(namespace.vdc_name, vdc_uuid)) else: - print ("Failed create a new vdc {}".format(namespace.vdc_name)) + print("Failed create a new vdc {}".format(namespace.vdc_name)) else: return None @@ -553,7 +553,7 @@ def boot_image(vim=None, image_name=None, vm_name=None): if vim_catalog is None: return None - print (" Booting {} image id {} ".format(vm_name, vim_catalog)) + print(" Booting {} image id {} ".format(vm_name, vim_catalog)) vm_uuid, _ = vim.new_vminstance(name=vm_name, image_id=vim_catalog) if vm_uuid is not None and validate_uuid4(vm_uuid): print("Image booted and vm uuid {}".format(vm_uuid)) @@ -606,9 +606,6 @@ def vmwarecli(command=None, action=None, namespace=None): vcdhost = None vcdorg = None - if hasattr(__builtins__, 'raw_input'): - input = raw_input - if namespace.vcdvdc is None: while True: vcduser = input("Enter vcd username: ") diff --git a/osm_ro/wim/__init__.py b/RO/osm_ro/wim/__init__.py similarity index 100% rename from osm_ro/wim/__init__.py rename to RO/osm_ro/wim/__init__.py diff --git a/osm_ro/wim/actions.py b/RO/osm_ro/wim/actions.py similarity index 99% rename from osm_ro/wim/actions.py rename to RO/osm_ro/wim/actions.py index f2244608..e199fd07 100644 --- a/osm_ro/wim/actions.py +++ b/RO/osm_ro/wim/actions.py @@ -36,9 +36,6 @@ """Common logic for task management""" import logging from time import time -from types import StringTypes - -from six.moves import range import yaml @@ -412,7 +409,7 @@ class DeleteAction(Action): def _expand_extra(record): extra = record.pop('extra', None) or {} - if isinstance(extra, StringTypes): + if isinstance(extra, str): extra = yaml.safe_load(extra) record['params'] = extra.get('params') diff --git a/osm_ro/wim/engine.py b/RO/osm_ro/wim/engine.py similarity index 98% rename from osm_ro/wim/engine.py rename to RO/osm_ro/wim/engine.py index 3fdd0324..cf5b85a0 100644 --- a/osm_ro/wim/engine.py +++ b/RO/osm_ro/wim/engine.py @@ -51,8 +51,6 @@ from operator import itemgetter from sys import exc_info from uuid import uuid4 -from six import reraise - from ..utils import remove_none_items from .actions import Action from .errors import ( @@ -95,13 +93,13 @@ class WimEngine(object): if port_mapping: try: self.create_wim_port_mappings(uuid, port_mapping) - except DbBaseException: + except DbBaseException as e: # Rollback self.delete_wim(uuid) ex = UnexpectedDatabaseError('Failed to create port mappings' 'Rolling back wim creation') self.logger.exception(str(ex)) - reraise(ex.__class__, ex, exc_info()[2]) + raise ex from e return uuid @@ -139,13 +137,13 @@ class WimEngine(object): self.persist.delete_wim_port_mappings(uuid) # ^ Calling from persistence avoid reloading twice the thread self.create_wim_port_mappings(uuid, port_mapping) - except DbBaseException: + except DbBaseException as e: # Rollback self.update_wim(uuid_or_name, orig_props) ex = UnexpectedDatabaseError('Failed to update port mappings' 'Rolling back wim updates\n') self.logger.exception(str(ex)) - reraise(ex.__class__, ex, exc_info()[2]) + raise ex from e return response @@ -487,7 +485,7 @@ class WimEngine(object): """Stop the threads responsible for processing WIM Actions""" for uuid, thread in self.threads.items(): thread.exit() - del self.threads[uuid] + self.threads.clear() @contextmanager def threads_running(self): diff --git a/osm_ro/wim/errors.py b/RO/osm_ro/wim/errors.py similarity index 99% rename from osm_ro/wim/errors.py rename to RO/osm_ro/wim/errors.py index ca8c2b73..e8d4b63e 100644 --- a/osm_ro/wim/errors.py +++ b/RO/osm_ro/wim/errors.py @@ -31,7 +31,7 @@ # funded by the European Commission under Grant number 761727 through the # Horizon 2020 and 5G-PPP programmes. ## -from six.moves import queue +import queue from ..db_base import db_base_Exception as DbBaseException from ..http_tools.errors import ( diff --git a/osm_ro/wim/failing_connector.py b/RO/osm_ro/wim/failing_connector.py similarity index 100% rename from osm_ro/wim/failing_connector.py rename to RO/osm_ro/wim/failing_connector.py diff --git a/osm_ro/wim/http_handler.py b/RO/osm_ro/wim/http_handler.py similarity index 100% rename from osm_ro/wim/http_handler.py rename to RO/osm_ro/wim/http_handler.py diff --git a/osm_ro/wim/persistence.py b/RO/osm_ro/wim/persistence.py similarity index 99% rename from osm_ro/wim/persistence.py rename to RO/osm_ro/wim/persistence.py index 74f7dc61..f0f1ac33 100644 --- a/osm_ro/wim/persistence.py +++ b/RO/osm_ro/wim/persistence.py @@ -48,8 +48,6 @@ from sys import exc_info # from time import time from uuid import uuid1 as generate_uuid -from six import reraise - import yaml from ..utils import ( @@ -388,8 +386,7 @@ class WimPersistence(object): if all([msg in error_msg for msg in ("already in use", "'wim_nfvo_tenant'")]): ex = WimAndTenantAlreadyAttached(wim_id, nfvo_tenant_id) - reraise(ex.__class__, ex, exc_info()[2]) - + raise ex from db_exception raise def create_wim_account(self, wim, tenant, properties): @@ -530,7 +527,7 @@ class WimPersistence(object): "wan_service_mapping_info: " "('wan_switch_dpid' and 'wan_switch_port') or " "'wan_service_endpoint_id}'") - reraise(ex.__class__, ex, exc_info()[2]) + raise ex from old_exception return properties @@ -929,7 +926,7 @@ def hide_confidential_fields(record, fields=_CONFIDENTIAL_FIELDS): if not(isinstance(record, dict) and fields): return record - keys = record.iterkeys() + keys = list(record.keys()) keys = (k for k in keys for f in fields if k == f or k.endswith('.'+f)) return merge_dicts(record, {k: '********' for k in keys if record[k]}) @@ -940,7 +937,7 @@ def unserialize_fields(record, hide=_CONFIDENTIAL_FIELDS, """Unserialize fields that where stored in the database as a serialized YAML (or JSON) """ - keys = record.iterkeys() + keys = list(record.keys()) keys = (k for k in keys for f in fields if k == f or k.endswith('.'+f)) return merge_dicts(record, { @@ -951,7 +948,7 @@ def unserialize_fields(record, hide=_CONFIDENTIAL_FIELDS, def serialize_fields(record, fields=_SERIALIZED_FIELDS): """Serialize fields to be stored in the database as YAML""" - keys = record.iterkeys() + keys = list(record.keys()) keys = (k for k in keys for f in fields if k == f or k.endswith('.'+f)) return merge_dicts(record, { diff --git a/osm_ro/wim/schemas.py b/RO/osm_ro/wim/schemas.py similarity index 100% rename from osm_ro/wim/schemas.py rename to RO/osm_ro/wim/schemas.py diff --git a/osm_ro/wim/tests/__init__.py b/RO/osm_ro/wim/tests/__init__.py similarity index 100% rename from osm_ro/wim/tests/__init__.py rename to RO/osm_ro/wim/tests/__init__.py diff --git a/osm_ro/wim/tests/fixtures.py b/RO/osm_ro/wim/tests/fixtures.py similarity index 99% rename from osm_ro/wim/tests/fixtures.py rename to RO/osm_ro/wim/tests/fixtures.py index c39e9d7d..8984020d 100644 --- a/osm_ro/wim/tests/fixtures.py +++ b/RO/osm_ro/wim/tests/fixtures.py @@ -36,12 +36,9 @@ from __future__ import unicode_literals import json -from itertools import izip from time import time from textwrap import wrap -from six.moves import range - from ...tests.db_helpers import uuid, sha1 NUM_WIMS = 3 @@ -101,7 +98,7 @@ def datacenter(identifier, external_ports_config=False): 'provider:physical_network': 'provider', 'encapsulation_type': 'vlan'}, 'vim_external_port': - dict(izip(('switch', 'port'), + dict(zip(('switch', 'port'), _datacenter_to_switch_port(identifier)))} ]}) diff --git a/osm_ro/wim/tests/test_actions.py b/RO/osm_ro/wim/tests/test_actions.py similarity index 99% rename from osm_ro/wim/tests/test_actions.py rename to RO/osm_ro/wim/tests/test_actions.py index cee3c96f..37568692 100644 --- a/osm_ro/wim/tests/test_actions.py +++ b/RO/osm_ro/wim/tests/test_actions.py @@ -33,13 +33,13 @@ ## # pylint: disable=E1101 -from __future__ import unicode_literals, print_function +#from __future__ import unicode_literals, print_function import json import unittest from time import time -from mock import MagicMock, patch +from unittest.mock import MagicMock, patch from . import fixtures as eg from ...tests.db_helpers import ( diff --git a/osm_ro/wim/tests/test_engine.py b/RO/osm_ro/wim/tests/test_engine.py similarity index 99% rename from osm_ro/wim/tests/test_engine.py rename to RO/osm_ro/wim/tests/test_engine.py index 9bb7bca0..d518123a 100644 --- a/osm_ro/wim/tests/test_engine.py +++ b/RO/osm_ro/wim/tests/test_engine.py @@ -32,11 +32,9 @@ # Horizon 2020 and 5G-PPP programmes. ## -from __future__ import unicode_literals - import unittest -from mock import MagicMock +from unittest.mock import MagicMock from . import fixtures as eg from ...tests.db_helpers import TestCaseWithDatabasePerTest, uuid diff --git a/osm_ro/wim/tests/test_http_handler.py b/RO/osm_ro/wim/tests/test_http_handler.py similarity index 99% rename from osm_ro/wim/tests/test_http_handler.py rename to RO/osm_ro/wim/tests/test_http_handler.py index 428b1ce8..e42e53c6 100644 --- a/osm_ro/wim/tests/test_http_handler.py +++ b/RO/osm_ro/wim/tests/test_http_handler.py @@ -32,12 +32,10 @@ # Horizon 2020 and 5G-PPP programmes. ## -from __future__ import unicode_literals - import unittest import bottle -from mock import MagicMock, patch +from unittest.mock import MagicMock, patch from webtest import TestApp from . import fixtures as eg # "examples" diff --git a/osm_ro/wim/tests/test_persistence.py b/RO/osm_ro/wim/tests/test_persistence.py similarity index 98% rename from osm_ro/wim/tests/test_persistence.py rename to RO/osm_ro/wim/tests/test_persistence.py index e3e6cf61..ecca4fac 100644 --- a/osm_ro/wim/tests/test_persistence.py +++ b/RO/osm_ro/wim/tests/test_persistence.py @@ -32,13 +32,8 @@ # Horizon 2020 and 5G-PPP programmes. ## -from __future__ import unicode_literals - import unittest from itertools import chain -from types import StringType - -from six.moves import range from . import fixtures as eg from ...tests.db_helpers import ( @@ -75,7 +70,7 @@ class TestPersistenceUtils(unittest.TestCase): } result = serialize_fields(example, fields=('config', 'info')) for field in 'config', 'nested.info': - self.assertIsInstance(result[field], StringType) + self.assertIsInstance(result[field], str) self.assertIs(result['nested.config'], None) def test_unserialize_fields(self): diff --git a/osm_ro/wim/tests/test_wim_thread.py b/RO/osm_ro/wim/tests/test_wim_thread.py similarity index 99% rename from osm_ro/wim/tests/test_wim_thread.py rename to RO/osm_ro/wim/tests/test_wim_thread.py index 6d61848c..b8c8231b 100644 --- a/osm_ro/wim/tests/test_wim_thread.py +++ b/RO/osm_ro/wim/tests/test_wim_thread.py @@ -32,8 +32,6 @@ # Horizon 2020 and 5G-PPP programmes. ## -from __future__ import unicode_literals, print_function - import unittest from difflib import unified_diff from operator import itemgetter @@ -41,7 +39,7 @@ from time import time import json -from mock import MagicMock, patch +from unittest.mock import MagicMock, patch from . import fixtures as eg from ...tests.db_helpers import ( diff --git a/osm_ro/wim/tox.ini b/RO/osm_ro/wim/tox.ini similarity index 100% rename from osm_ro/wim/tox.ini rename to RO/osm_ro/wim/tox.ini diff --git a/osm_ro/wim/wan_link_actions.py b/RO/osm_ro/wim/wan_link_actions.py similarity index 99% rename from osm_ro/wim/wan_link_actions.py rename to RO/osm_ro/wim/wan_link_actions.py index 034e4159..0d878b2c 100644 --- a/osm_ro/wim/wan_link_actions.py +++ b/RO/osm_ro/wim/wan_link_actions.py @@ -37,8 +37,6 @@ from pprint import pformat from sys import exc_info from time import time -from six import reraise - from ..utils import filter_dict_keys as filter_keys from ..utils import merge_dicts, remove_none_items, safe_get, truncate from .actions import CreateAction, DeleteAction, FindAction @@ -47,7 +45,7 @@ from .errors import ( NoRecordFound, NoExternalPortFound ) -from wimconn import WimConnectorError +from .wimconn import WimConnectorError INSTANCE_NET_STATUS_ERROR = ('DOWN', 'ERROR', 'VIM_ERROR', 'DELETED', 'SCHEDULED_DELETION') @@ -194,11 +192,11 @@ class WanLinkCreate(RefreshMixin, CreateAction): wan_port_mapping = persistence.query_one( FROM='wim_port_mappings', WHERE=criteria) - except NoRecordFound: + except NoRecordFound as e: ex = InconsistentState('No WIM port mapping found:' 'wim_account: {}\ncriteria:\n{}'.format( self.wim_account_id, pformat(criteria))) - reraise(ex.__class__, ex, exc_info()[2]) + raise ex from e # It is important to return encapsulation information if present mapping = merge_dicts( diff --git a/osm_ro/wim/wim_thread.py b/RO/osm_ro/wim/wim_thread.py similarity index 98% rename from osm_ro/wim/wim_thread.py rename to RO/osm_ro/wim/wim_thread.py index f37aba74..13502b99 100644 --- a/osm_ro/wim/wim_thread.py +++ b/RO/osm_ro/wim/wim_thread.py @@ -48,8 +48,7 @@ from operator import itemgetter, attrgetter from sys import exc_info from time import time, sleep -from six import reraise -from six.moves import queue +import queue from . import wan_link_actions from ..utils import ensure, partition, pipe @@ -343,9 +342,9 @@ class WimThread(threading.Thread): try: self.task_queue.put(task, False) return None - except queue.Full: + except queue.Full as e: ex = QueueFull(self.name) - reraise(ex.__class__, ex, exc_info()[2]) + raise ex from e def reload(self): """Send a message to the running thread to reload itself""" @@ -437,6 +436,6 @@ def action_from(record, logger=None, mapping=ACTIONS): try: factory = mapping[record['item']][record['action']] return factory(record, logger=logger) - except KeyError: + except KeyError as e: ex = UndefinedAction(record['item'], record['action']) - reraise(ex.__class__, ex, exc_info()[2]) + raise ex from e diff --git a/osm_ro/wim/wimconn.py b/RO/osm_ro/wim/wimconn.py similarity index 100% rename from osm_ro/wim/wimconn.py rename to RO/osm_ro/wim/wimconn.py diff --git a/osm_ro/wim/wimconn_dynpac.py b/RO/osm_ro/wim/wimconn_dynpac.py similarity index 99% rename from osm_ro/wim/wimconn_dynpac.py rename to RO/osm_ro/wim/wimconn_dynpac.py index cc9376b0..661f6f6e 100644 --- a/osm_ro/wim/wimconn_dynpac.py +++ b/RO/osm_ro/wim/wimconn_dynpac.py @@ -26,7 +26,7 @@ import json import logging from enum import Enum -from wimconn import WimConnector, WimConnectorError +from .wimconn import WimConnector, WimConnectorError class WimError(Enum): diff --git a/osm_ro/wim/wimconn_fake.py b/RO/osm_ro/wim/wimconn_fake.py similarity index 100% rename from osm_ro/wim/wimconn_fake.py rename to RO/osm_ro/wim/wimconn_fake.py diff --git a/osm_ro/wim/wimconn_ietfl2vpn.py b/RO/osm_ro/wim/wimconn_ietfl2vpn.py similarity index 100% rename from osm_ro/wim/wimconn_ietfl2vpn.py rename to RO/osm_ro/wim/wimconn_ietfl2vpn.py diff --git a/osm_ro/wim/wimconn_odl.py b/RO/osm_ro/wim/wimconn_odl.py similarity index 100% rename from osm_ro/wim/wimconn_odl.py rename to RO/osm_ro/wim/wimconn_odl.py diff --git a/RO/requirements.txt b/RO/requirements.txt new file mode 100644 index 00000000..731b5050 --- /dev/null +++ b/RO/requirements.txt @@ -0,0 +1,9 @@ +PyYAML +bottle +MySQL-python +jsonschema +paramiko +requests==2.18.* +netaddr +logutils +git+https://osm.etsi.org/gerrit/osm/IM.git#egg=osm-im diff --git a/RO/setup.py b/RO/setup.py new file mode 100755 index 00000000..5cb1fe90 --- /dev/null +++ b/RO/setup.py @@ -0,0 +1,76 @@ +#!/usr/bin/env python3 + +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +# implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# from distutils.core import setup +# from distutils.command.install_data import install_data +from setuptools import setup +from os import system +# import glob + +_name = 'osm_ro' +_description = 'OSM Resource Orchestrator' +_author = 'ETSI OSM' +_author_email = 'alfonso.tiernosepulveda@telefonica.com' +_maintainer = 'garciadeblas' +_maintainer_email = 'gerardo.garciadeblas@telefonica.com' +_license = 'Apache 2.0' +_url = 'https://osm.etsi.org/gitweb/?p=osm/RO.git;a=summary' +_requirements = [ + # TODO py3 revise + "osm-im", + "PyYAML", + "bottle", + "logutils", + "jsonschema", + "paramiko", + "mysqlclient", + #"MySQLdb", + + # common to VIMS + "requests", + "netaddr", # openstack, aws, vmware +] + +setup( + name=_name, + version_command=('git -C .. describe --match v* --tags --long --dirty', 'pep440-git-full'), + description = _description, + long_description = open('README.rst').read(), + author = _author, + author_email = _author_email, + maintainer = _maintainer, + maintainer_email = _maintainer_email, + url = _url, + license = _license, + packages = [_name], + #packages = ['osm_ro', 'osm_roclient'], + package_dir = {_name: _name}, + # package_data = {_name: ['vnfs/*.yaml', 'vnfs/examples/*.yaml', + # 'scenarios/*.yaml', 'scenarios/examples/*.yaml', + # 'instance-scenarios/examples/*.yaml', 'database_utils/*', + # 'scripts/*']}, + # data_files = [('/etc/osm/', ['osm_ro/openmanod.cfg']), + # ('/etc/systemd/system/', ['osm_ro/osm-ro.service']), + # ], + scripts=['osm_ro/scripts/RO-start.sh' + #'openmanod', 'openmano', 'osm_ro/scripts/service-openmano', 'osm_ro/scripts/openmano-report', + ], + dependency_links=["git+https://osm.etsi.org/gerrit/osm/IM.git#egg=osm-im"], + install_requires=_requirements, + include_package_data=True, + setup_requires=['setuptools-version-command'], + #test_suite='nose.collector', +) + diff --git a/RO/stdeb.cfg b/RO/stdeb.cfg new file mode 100644 index 00000000..6260296c --- /dev/null +++ b/RO/stdeb.cfg @@ -0,0 +1,23 @@ +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +# implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +[DEFAULT] +X-Python3-Version : >= 3.5 +Maintainer: Gerardo Garcia +Depends3 : python3-bottle, python3-jsonschema, python3-mysqldb, python3-paramiko, python3-yaml, + libmysqlclient-dev, mysql-client, + python3-requests, python3-netaddr, + python3-osm-im, + +# TODO py3 libssl-dev, libffi-dev, python-logutils, python-lib-osm-openvim, +# TODO py3 python3-networkx diff --git a/test/RO_tests/afiinity_vnf/scenario_simple_2_vnf_afinnity.yaml b/RO/test/RO_tests/afiinity_vnf/scenario_simple_2_vnf_afinnity.yaml similarity index 100% rename from test/RO_tests/afiinity_vnf/scenario_simple_2_vnf_afinnity.yaml rename to RO/test/RO_tests/afiinity_vnf/scenario_simple_2_vnf_afinnity.yaml diff --git a/test/RO_tests/afiinity_vnf/vnfd_linux_2_vnfc_affinity.yaml b/RO/test/RO_tests/afiinity_vnf/vnfd_linux_2_vnfc_affinity.yaml similarity index 100% rename from test/RO_tests/afiinity_vnf/vnfd_linux_2_vnfc_affinity.yaml rename to RO/test/RO_tests/afiinity_vnf/vnfd_linux_2_vnfc_affinity.yaml diff --git a/test/RO_tests/empy_volume/scenario_additional_disk_empty_volume.yaml b/RO/test/RO_tests/empy_volume/scenario_additional_disk_empty_volume.yaml similarity index 100% rename from test/RO_tests/empy_volume/scenario_additional_disk_empty_volume.yaml rename to RO/test/RO_tests/empy_volume/scenario_additional_disk_empty_volume.yaml diff --git a/test/RO_tests/empy_volume/vnfd_additional_disk_empty_volume.yaml b/RO/test/RO_tests/empy_volume/vnfd_additional_disk_empty_volume.yaml similarity index 100% rename from test/RO_tests/empy_volume/vnfd_additional_disk_empty_volume.yaml rename to RO/test/RO_tests/empy_volume/vnfd_additional_disk_empty_volume.yaml diff --git a/test/RO_tests/floating_ip/scenario_floating_ip.yaml b/RO/test/RO_tests/floating_ip/scenario_floating_ip.yaml similarity index 100% rename from test/RO_tests/floating_ip/scenario_floating_ip.yaml rename to RO/test/RO_tests/floating_ip/scenario_floating_ip.yaml diff --git a/test/RO_tests/floating_ip/vnfd_floating_ip.yaml b/RO/test/RO_tests/floating_ip/vnfd_floating_ip.yaml similarity index 100% rename from test/RO_tests/floating_ip/vnfd_floating_ip.yaml rename to RO/test/RO_tests/floating_ip/vnfd_floating_ip.yaml diff --git a/test/RO_tests/image_based_volume/scenario_additional_disk_based_image.yaml b/RO/test/RO_tests/image_based_volume/scenario_additional_disk_based_image.yaml similarity index 100% rename from test/RO_tests/image_based_volume/scenario_additional_disk_based_image.yaml rename to RO/test/RO_tests/image_based_volume/scenario_additional_disk_based_image.yaml diff --git a/test/RO_tests/image_based_volume/vnfd_additional_disk_based_image.yaml b/RO/test/RO_tests/image_based_volume/vnfd_additional_disk_based_image.yaml similarity index 100% rename from test/RO_tests/image_based_volume/vnfd_additional_disk_based_image.yaml rename to RO/test/RO_tests/image_based_volume/vnfd_additional_disk_based_image.yaml diff --git a/test/RO_tests/no_port_security/scenario_vnf_no_port_security.yaml b/RO/test/RO_tests/no_port_security/scenario_vnf_no_port_security.yaml similarity index 100% rename from test/RO_tests/no_port_security/scenario_vnf_no_port_security.yaml rename to RO/test/RO_tests/no_port_security/scenario_vnf_no_port_security.yaml diff --git a/test/RO_tests/no_port_security/vnfd_no_port_security.yaml b/RO/test/RO_tests/no_port_security/vnfd_no_port_security.yaml similarity index 100% rename from test/RO_tests/no_port_security/vnfd_no_port_security.yaml rename to RO/test/RO_tests/no_port_security/vnfd_no_port_security.yaml diff --git a/test/RO_tests/passthrough/scenario_p2p_passthrough.yaml b/RO/test/RO_tests/passthrough/scenario_p2p_passthrough.yaml similarity index 100% rename from test/RO_tests/passthrough/scenario_p2p_passthrough.yaml rename to RO/test/RO_tests/passthrough/scenario_p2p_passthrough.yaml diff --git a/test/RO_tests/passthrough/vnfd_1passthrough.yaml b/RO/test/RO_tests/passthrough/vnfd_1passthrough.yaml similarity index 100% rename from test/RO_tests/passthrough/vnfd_1passthrough.yaml rename to RO/test/RO_tests/passthrough/vnfd_1passthrough.yaml diff --git a/test/RO_tests/pmp_passthrough/scenario_pmp_passthrough.yaml b/RO/test/RO_tests/pmp_passthrough/scenario_pmp_passthrough.yaml similarity index 100% rename from test/RO_tests/pmp_passthrough/scenario_pmp_passthrough.yaml rename to RO/test/RO_tests/pmp_passthrough/scenario_pmp_passthrough.yaml diff --git a/test/RO_tests/pmp_passthrough/vnfd_1passthrough.yaml b/RO/test/RO_tests/pmp_passthrough/vnfd_1passthrough.yaml similarity index 100% rename from test/RO_tests/pmp_passthrough/vnfd_1passthrough.yaml rename to RO/test/RO_tests/pmp_passthrough/vnfd_1passthrough.yaml diff --git a/test/RO_tests/pmp_sriov/scenario_pmp_sriov.yaml b/RO/test/RO_tests/pmp_sriov/scenario_pmp_sriov.yaml similarity index 100% rename from test/RO_tests/pmp_sriov/scenario_pmp_sriov.yaml rename to RO/test/RO_tests/pmp_sriov/scenario_pmp_sriov.yaml diff --git a/test/RO_tests/pmp_sriov/vnfd_1sriov.yaml b/RO/test/RO_tests/pmp_sriov/vnfd_1sriov.yaml similarity index 100% rename from test/RO_tests/pmp_sriov/vnfd_1sriov.yaml rename to RO/test/RO_tests/pmp_sriov/vnfd_1sriov.yaml diff --git a/test/RO_tests/pmp_sriov_passthrough/scenario_pmp_sriov_passthrough.yaml b/RO/test/RO_tests/pmp_sriov_passthrough/scenario_pmp_sriov_passthrough.yaml similarity index 100% rename from test/RO_tests/pmp_sriov_passthrough/scenario_pmp_sriov_passthrough.yaml rename to RO/test/RO_tests/pmp_sriov_passthrough/scenario_pmp_sriov_passthrough.yaml diff --git a/test/RO_tests/pmp_sriov_passthrough/vnfd_1passthrough.yaml b/RO/test/RO_tests/pmp_sriov_passthrough/vnfd_1passthrough.yaml similarity index 100% rename from test/RO_tests/pmp_sriov_passthrough/vnfd_1passthrough.yaml rename to RO/test/RO_tests/pmp_sriov_passthrough/vnfd_1passthrough.yaml diff --git a/test/RO_tests/pmp_sriov_passthrough/vnfd_1sriov.yaml b/RO/test/RO_tests/pmp_sriov_passthrough/vnfd_1sriov.yaml similarity index 100% rename from test/RO_tests/pmp_sriov_passthrough/vnfd_1sriov.yaml rename to RO/test/RO_tests/pmp_sriov_passthrough/vnfd_1sriov.yaml diff --git a/test/RO_tests/simple_2_vnf/scenario_simple_2_vnf.yaml b/RO/test/RO_tests/simple_2_vnf/scenario_simple_2_vnf.yaml similarity index 100% rename from test/RO_tests/simple_2_vnf/scenario_simple_2_vnf.yaml rename to RO/test/RO_tests/simple_2_vnf/scenario_simple_2_vnf.yaml diff --git a/test/RO_tests/simple_2_vnf/vnfd_linux.yaml b/RO/test/RO_tests/simple_2_vnf/vnfd_linux.yaml similarity index 100% rename from test/RO_tests/simple_2_vnf/vnfd_linux.yaml rename to RO/test/RO_tests/simple_2_vnf/vnfd_linux.yaml diff --git a/test/RO_tests/simple_cloud_init/scenario_simple-cloud-init.yaml b/RO/test/RO_tests/simple_cloud_init/scenario_simple-cloud-init.yaml similarity index 100% rename from test/RO_tests/simple_cloud_init/scenario_simple-cloud-init.yaml rename to RO/test/RO_tests/simple_cloud_init/scenario_simple-cloud-init.yaml diff --git a/test/RO_tests/simple_cloud_init/vnfd_linux-cloud-init.yaml b/RO/test/RO_tests/simple_cloud_init/vnfd_linux-cloud-init.yaml similarity index 100% rename from test/RO_tests/simple_cloud_init/vnfd_linux-cloud-init.yaml rename to RO/test/RO_tests/simple_cloud_init/vnfd_linux-cloud-init.yaml diff --git a/test/RO_tests/simple_count3/scenario_linux_count3.yaml b/RO/test/RO_tests/simple_count3/scenario_linux_count3.yaml similarity index 100% rename from test/RO_tests/simple_count3/scenario_linux_count3.yaml rename to RO/test/RO_tests/simple_count3/scenario_linux_count3.yaml diff --git a/test/RO_tests/simple_count3/vnfd_count3.yaml b/RO/test/RO_tests/simple_count3/vnfd_count3.yaml similarity index 100% rename from test/RO_tests/simple_count3/vnfd_count3.yaml rename to RO/test/RO_tests/simple_count3/vnfd_count3.yaml diff --git a/test/RO_tests/simple_linux/scenario_simple_linux.yaml b/RO/test/RO_tests/simple_linux/scenario_simple_linux.yaml similarity index 100% rename from test/RO_tests/simple_linux/scenario_simple_linux.yaml rename to RO/test/RO_tests/simple_linux/scenario_simple_linux.yaml diff --git a/test/RO_tests/simple_linux/vnfd_linux.yaml b/RO/test/RO_tests/simple_linux/vnfd_linux.yaml similarity index 100% rename from test/RO_tests/simple_linux/vnfd_linux.yaml rename to RO/test/RO_tests/simple_linux/vnfd_linux.yaml diff --git a/test/RO_tests/simple_multi_vnfc/scenario_multi_vnfc.yaml b/RO/test/RO_tests/simple_multi_vnfc/scenario_multi_vnfc.yaml similarity index 100% rename from test/RO_tests/simple_multi_vnfc/scenario_multi_vnfc.yaml rename to RO/test/RO_tests/simple_multi_vnfc/scenario_multi_vnfc.yaml diff --git a/test/RO_tests/simple_multi_vnfc/vnfd_linux_2VMs_v02.yaml b/RO/test/RO_tests/simple_multi_vnfc/vnfd_linux_2VMs_v02.yaml similarity index 100% rename from test/RO_tests/simple_multi_vnfc/vnfd_linux_2VMs_v02.yaml rename to RO/test/RO_tests/simple_multi_vnfc/vnfd_linux_2VMs_v02.yaml diff --git a/test/RO_tests/sr_iov/scenario_p2p_sriov.yaml b/RO/test/RO_tests/sr_iov/scenario_p2p_sriov.yaml similarity index 100% rename from test/RO_tests/sr_iov/scenario_p2p_sriov.yaml rename to RO/test/RO_tests/sr_iov/scenario_p2p_sriov.yaml diff --git a/test/RO_tests/sr_iov/vnfd_1sriov.yaml b/RO/test/RO_tests/sr_iov/vnfd_1sriov.yaml similarity index 100% rename from test/RO_tests/sr_iov/vnfd_1sriov.yaml rename to RO/test/RO_tests/sr_iov/vnfd_1sriov.yaml diff --git a/test/RO_tests/sriov_passthrough/scenario_p2p_sriov_passthrough.yaml b/RO/test/RO_tests/sriov_passthrough/scenario_p2p_sriov_passthrough.yaml similarity index 100% rename from test/RO_tests/sriov_passthrough/scenario_p2p_sriov_passthrough.yaml rename to RO/test/RO_tests/sriov_passthrough/scenario_p2p_sriov_passthrough.yaml diff --git a/test/RO_tests/sriov_passthrough/vnfd_1passthrough.yaml b/RO/test/RO_tests/sriov_passthrough/vnfd_1passthrough.yaml similarity index 100% rename from test/RO_tests/sriov_passthrough/vnfd_1passthrough.yaml rename to RO/test/RO_tests/sriov_passthrough/vnfd_1passthrough.yaml diff --git a/test/RO_tests/sriov_passthrough/vnfd_1sriov.yaml b/RO/test/RO_tests/sriov_passthrough/vnfd_1sriov.yaml similarity index 100% rename from test/RO_tests/sriov_passthrough/vnfd_1sriov.yaml rename to RO/test/RO_tests/sriov_passthrough/vnfd_1sriov.yaml diff --git a/test/RO_tests/v3_2vdu_set_ip_mac/scenario_2vdu_set_ip_mac.yaml b/RO/test/RO_tests/v3_2vdu_set_ip_mac/scenario_2vdu_set_ip_mac.yaml similarity index 100% rename from test/RO_tests/v3_2vdu_set_ip_mac/scenario_2vdu_set_ip_mac.yaml rename to RO/test/RO_tests/v3_2vdu_set_ip_mac/scenario_2vdu_set_ip_mac.yaml diff --git a/test/RO_tests/v3_2vdu_set_ip_mac/vnfd_2vdu_set_ip_mac.yaml b/RO/test/RO_tests/v3_2vdu_set_ip_mac/vnfd_2vdu_set_ip_mac.yaml similarity index 100% rename from test/RO_tests/v3_2vdu_set_ip_mac/vnfd_2vdu_set_ip_mac.yaml rename to RO/test/RO_tests/v3_2vdu_set_ip_mac/vnfd_2vdu_set_ip_mac.yaml diff --git a/test/RO_tests/v3_2vdu_set_ip_mac/vnfd_2vdu_set_ip_mac2.yaml b/RO/test/RO_tests/v3_2vdu_set_ip_mac/vnfd_2vdu_set_ip_mac2.yaml similarity index 100% rename from test/RO_tests/v3_2vdu_set_ip_mac/vnfd_2vdu_set_ip_mac2.yaml rename to RO/test/RO_tests/v3_2vdu_set_ip_mac/vnfd_2vdu_set_ip_mac2.yaml diff --git a/test/basictest.sh b/RO/test/basictest.sh similarity index 100% rename from test/basictest.sh rename to RO/test/basictest.sh diff --git a/test/test-multivim.sh b/RO/test/test-multivim.sh similarity index 100% rename from test/test-multivim.sh rename to RO/test/test-multivim.sh diff --git a/test/test_RO.py b/RO/test/test_RO.py similarity index 99% rename from test/test_RO.py rename to RO/test/test_RO.py index 932853c5..5d170877 100755 --- a/test/test_RO.py +++ b/RO/test/test_RO.py @@ -369,7 +369,7 @@ class test_vimconn_new_network(test_base): for vnfd in vnfd_files: with open(vnfd, 'r') as stream: - vnf_descriptor = yaml.load(stream) + vnf_descriptor = yaml.load(stream, Loader=yaml.Loader) internal_connections_list = vnf_descriptor['vnf']['internal-connections'] for item in internal_connections_list: @@ -736,7 +736,7 @@ class test_vimconn_get_flavor(test_base): for vnfd in vnfd_files: with open(vnfd, 'r') as stream: - vnf_descriptor = yaml.load(stream) + vnf_descriptor = yaml.load(stream, Loader=yaml.Loader) vnfc_list = vnf_descriptor['vnf']['VNFC'] for item in vnfc_list: @@ -1987,7 +1987,7 @@ class descriptor_based_scenario_test(test_base): scenario_descriptors = [] for descriptor_file in descriptor_files: with open(descriptor_file, 'r') as stream: - descriptor = yaml.load(stream) + descriptor = yaml.load(stream, Loader=yaml.Loader) if "vnf" in descriptor or "vnfd:vnfd-catalog" in descriptor or "vnfd-catalog" in descriptor: vnf_descriptors.append(descriptor) else: @@ -2055,7 +2055,7 @@ class descriptor_based_scenario_test(test_base): self.__class__.test_index += 1 if test_config["manual"]: - raw_input('Scenario has been deployed. Perform manual check and press any key to resume') + input('Scenario has been deployed. Perform manual check and press any key to resume') return keep_waiting = test_config["timeout"] @@ -2121,7 +2121,7 @@ def test_vimconnector(args): tenant_name = args.tenant_name test_config['tenant'] = tenant_name - config_params = yaml.load(args.config_param) + config_params = yaml.load(args.config_param, Loader=yaml.Loader) org_name = config_params.get('orgname') org_user = config_params.get('user') org_passwd = config_params.get('passwd') @@ -2142,7 +2142,7 @@ def test_vimconnector(args): tenant_name = args.tenant_name test_config['tenant'] = tenant_name - config_params = yaml.load(args.config_param) + config_params = yaml.load(args.config_param, Loader=yaml.Loader) os_user = config_params.get('user') os_passwd = config_params.get('passwd') vim_url = args.endpoint_url diff --git a/test/test_on_container.sh b/RO/test/test_on_container.sh similarity index 100% rename from test/test_on_container.sh rename to RO/test/test_on_container.sh diff --git a/test/test_openmanocli.sh b/RO/test/test_openmanocli.sh similarity index 100% rename from test/test_openmanocli.sh rename to RO/test/test_openmanocli.sh diff --git a/test/test_openmanoclient.py b/RO/test/test_openmanoclient.py similarity index 100% rename from test/test_openmanoclient.py rename to RO/test/test_openmanoclient.py diff --git a/test/test_osconnector.py b/RO/test/test_osconnector.py similarity index 69% rename from test/test_osconnector.py rename to RO/test/test_osconnector.py index 92d54376..3619ae44 100755 --- a/test/test_osconnector.py +++ b/RO/test/test_osconnector.py @@ -49,27 +49,27 @@ import osconnector version="0.1" def usage(): - print "Usage: ", sys.argv[0], "[options]" - print " -v|--version openstack version (by default 2)" - print " -u|--username USER user to authenticate (by default bash:OS_USERNAME)" - print " -p|--password PASSWD password to authenticate (by default bash:OS_PASSWORD)" - print " -U|--auth_url URL url of authentication over keystone (by default bash:OS_AUTH_URL)" - print " -t|--tenant_name TENANT password to authenticate (by default bash:OS_TENANT_NAME)" - print " -i|--image IMAGE use this local path or url for loading image (by default cirros)" - print " --skip-admin-tests skip tests that requires administrative permissions, like create tenants" - print " -h|--help shows this help" + print("Usage: ", sys.argv[0], "[options]") + print(" -v|--version openstack version (by default 2)") + print(" -u|--username USER user to authenticate (by default bash:OS_USERNAME)") + print(" -p|--password PASSWD password to authenticate (by default bash:OS_PASSWORD)") + print(" -U|--auth_url URL url of authentication over keystone (by default bash:OS_AUTH_URL)") + print(" -t|--tenant_name TENANT password to authenticate (by default bash:OS_TENANT_NAME)") + print(" -i|--image IMAGE use this local path or url for loading image (by default cirros)") + print(" --skip-admin-tests skip tests that requires administrative permissions, like create tenants") + print(" -h|--help shows this help") return def delete_items(): global myvim global rollback_list - print "Making rollback, deleting items" + print("Making rollback, deleting items") for i in range(len(rollback_list)-1, -1, -1): item,name,id_ = rollback_list[i] if item=="creds": - print ("changing credentials %s='%s'" % (name, id_)).ljust(50), + print("changing credentials {}='{}'".format(name, id_)).ljust(50), else: - print ("deleting %s '%s'" % (item, name)).ljust(50), + print("deleting {} '{}'".format(item, name)).ljust(50), sys.stdout.flush() if item=="flavor": result,message=myvim.delete_tenant_flavor(id_) @@ -91,26 +91,26 @@ def delete_items(): result=-1 message= " " + str(type(e))[6:-1] + ": "+ str(e) else: - print "Internal error unknown item rollback %s,%s,%s" % (item,name,id_) + print("Internal error unknown item rollback {},{},{}".format(item,name,id_)) continue if result<0: - print " Fail" - print " VIM response:", message + print(" Fail") + print(" VIM response:", message) continue else: - print " Ok" + print(" Ok") if __name__=="__main__": global myvim global rollback_list - #print "(c) Copyright Telefonica" + #print("(c) Copyright Telefonica" rollback_list=[] try: opts, args = getopt.getopt(sys.argv[1:], "hv:u:U:p:t:i:", ["username=", "help", "version=", "password=", "tenant=", "url=","skip-admin-tests",'image=']) except getopt.GetoptError as err: - # print help information and exit: - print "Error:", err # will print something like "option -a not recognized" + # print(help information and exit: + print("Error:", err) # will print something like "option -a not recognized") usage() sys.exit(2) @@ -144,129 +144,129 @@ if __name__=="__main__": assert False, "Unhandled option" if creds['auth_url']==None: - print "you must provide openstack url with -U or bash OS_AUTH_URL" + print("you must provide openstack url with -U or bash OS_AUTH_URL") sys.exit() - print "creds:", creds + print("creds:", creds) try: - print 'load osconnector class'.ljust(50), + print('load osconnector class'.ljust(50)) sys.stdout.flush() try: myvim=osconnector.osconnector(uuid=None, name='test-openstack', tenant=creds['tenant_name'], url=creds['auth_url'], url_admin=None, user=creds['username'], passwd=creds['password'], debug = False, config={'network_vlan_ranges':'physnet_sriov'} ) - print " Ok" + print(" Ok") except Exception as e: - print " Fail" - print str(type(e))[6:-1] + ": "+ str(e) + print(" Fail") + print(str(type(e))[6:-1] + ": "+ str(e)) exit(-1) if not skip_admin_tests: tenant_name="tos-tenant" - print ("creating new tenant '%s'" % tenant_name).ljust(50), + print("creating new tenant '{}'".format(tenant_name)).ljust(50), sys.stdout.flush() result,new_tenant=myvim.new_tenant(tenant_name, "test tenant_description, trying a long description to get the limit. 2 trying a long description to get the limit. 3. trying a long description to get the limit.") if result<0: - print " Fail" - print " you can skip tenant creation with param'--skip-admin-tests'" - print " VIM response:", new_tenant + print(" Fail") + print(" you can skip tenant creation with param'--skip-admin-tests'") + print(" VIM response:", new_tenant) exit(-1) else: - print " Ok", new_tenant + print(" Ok", new_tenant) rollback_list.append(("tenant",tenant_name,new_tenant)) user_name="tos-user" - print ("creating new user '%s'" % user_name).ljust(50), + print("creating new user '{}'".format(user_name).ljust(50), end="") sys.stdout.flush() result,new_user=myvim.new_user(user_name, user_name, tenant_id=new_tenant) if result<0: - print " Fail" - print " VIM response:", new_user + print(" Fail") + print(" VIM response:", new_user) exit(-1) else: - print " Ok", new_user + print(" Ok", new_user) rollback_list.append(("user",user_name,new_user)) name="tos-fl1" - print ("creating new flavor '%s'"%name).ljust(50), + print("creating new flavor '{}'".format(name)).ljust(50), sys.stdout.flush() flavor={} flavor['name']=name result,new_flavor1=myvim.new_tenant_flavor(flavor, True) if result<0: - print " Fail" - print " VIM response:", new_flavor1 + print(" Fail") + print(" VIM response:", new_flavor1) exit(-1) else: - print " Ok", new_flavor1 + print(" Ok", new_flavor1) rollback_list.append(("flavor",name,new_flavor1)) name="tos-cirros" - print ("creating new image '%s'"%name).ljust(50), + print("creating new image '{}'".format(name).ljust(50)) sys.stdout.flush() image={} image['name']=name image['location']=image_path #"/home/atierno/cirros-0.3.3-x86_64-disk.img" result,new_image1=myvim.new_tenant_image(image) if result<0: - print " Fail" - print " VIM response:", new_image1 + print(" Fail") + print(" VIM response:", new_image1) exit(-1) else: - print " Ok", new_image1 + print(" Ok", new_image1) rollback_list.append(("image",name, new_image1)) if not skip_admin_tests: try: - print 'changing credentials to new tenant'.ljust(50), + print('changing credentials to new tenant'.ljust(50)) sys.stdout.flush() myvim['tenant'] =tenant_name myvim['user']=user_name myvim['passwd']=user_name - print " Ok" + print(" Ok") rollback_list.append(("creds", "tenant", creds["tenant_name"])) rollback_list.append(("creds", "user", creds["username"])) rollback_list.append(("creds", "passwd", creds["password"])) except Exception as e: - print " Fail" - print " Error setting osconnector to new tenant:", str(type(e))[6:-1] + ": "+ str(e) + print(" Fail") + print(" Error setting osconnector to new tenant:", str(type(e))[6:-1] + ": "+ str(e)) exit(-1) name="tos-net-bridge" - print ("creating new net '%s'"%name).ljust(50), + print("creating new net '{}'".format(name)).ljust(50), sys.stdout.flush() result,new_net1=myvim.new_tenant_network(name, "bridge") if result<0: - print " Fail" - print " VIM response:", new_net1 + print(" Fail") + print(" VIM response:", new_net1) exit(-1) else: - print " Ok", new_net1 + print(" Ok", new_net1) rollback_list.append(("network",name, new_net1)) name="tos-vm-cloud" - print ("creating new VM '%s'"%name).ljust(50), + print("creating new VM '{}'".format(name).ljust(50)) sys.stdout.flush() result,new_vm1=myvim.new_tenant_vminstance(name, "vm-cloud-description", False,new_image1,new_flavor1, [{"net_id":new_net1, "type":"virtio"}] ) if result<0: - print " Fail" - print " VIM response:", new_vm1 + print(" Fail") + print(" VIM response:", new_vm1) exit(-1) else: - print " Ok", new_vm1 + print(" Ok", new_vm1) rollback_list.append(("vm",name, new_vm1)) - print 'DONE Ok' - print "Type ENTER to delete items" - raw_input('> ') + print('DONE Ok') + print("Type ENTER to delete items") + input('> ') exit() except KeyboardInterrupt: - print " Canceled!" + print(" Canceled!") except SystemExit: pass if len(rollback_list): diff --git a/test/test_vimconn.sh b/RO/test/test_vimconn.sh similarity index 100% rename from test/test_vimconn.sh rename to RO/test/test_vimconn.sh diff --git a/RO/tox.ini b/RO/tox.ini new file mode 100644 index 00000000..810ab397 --- /dev/null +++ b/RO/tox.ini @@ -0,0 +1,35 @@ +# 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. + +[tox] +#envlist = py27,py3 +envlist = py35 +toxworkdir={homedir}/.tox + +[testenv] +deps=nose + mock +commands=nosetests + +[testenv:flake8] +basepython = python +deps = flake8 +# TODO for the moment few files are tested. +commands = flake8 osm_ro/wim --max-line-length 120 \ + --exclude .svn,CVS,.gz,.git,__pycache__,.tox,local,temp,osm_im --ignore W291,W293,E226,E402,W504 + +[testenv:build] +basepython = python3 +deps = stdeb + setuptools-version-command +commands = python3 setup.py --command-packages=stdeb.command bdist_deb diff --git a/devops-stages/stage-archive.sh b/devops-stages/stage-archive.sh index cc1cfc05..2bc3e4d5 100755 --- a/devops-stages/stage-archive.sh +++ b/devops-stages/stage-archive.sh @@ -1,8 +1,22 @@ #!/bin/sh + +# 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. + rm -rf pool rm -rf dists mkdir -p pool/RO -mv .build/*.deb pool/RO/ +mv deb_dist/*.deb pool/RO/ mkdir -p dists/unstable/RO/binary-amd64/ apt-ftparchive packages pool/RO > dists/unstable/RO/binary-amd64/Packages gzip -9fk dists/unstable/RO/binary-amd64/Packages diff --git a/devops-stages/stage-build.sh b/devops-stages/stage-build.sh index 25de71a7..b1640eb4 100755 --- a/devops-stages/stage-build.sh +++ b/devops-stages/stage-build.sh @@ -1,4 +1,53 @@ -#!/bin/sh -make clean all BRANCH=master -#make install && \ -#make test +#!/bin/bash + +# 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. + +rm -rf deb_dist/* +mkdir -p deb_dist + +# main RO module +make -C RO clean package BRANCH=master +cp RO/deb_dist/python3-osm-ro_*.deb deb_dist/ + +# RO client +make -C RO-client clean package +cp RO-client/deb_dist/python3-osm-roclient_*.deb deb_dist/ + +# VIM vmware plugin +make -C RO-VIM-vmware clean package +cp RO-VIM-vmware/deb_dist/python3-osm-rovim-vmware_*.deb deb_dist/ + +# VIM Openstack plugin +make -C RO-VIM-openstack clean package +cp RO-VIM-openstack/deb_dist/python3-osm-rovim-openstack_*.deb deb_dist/ + +# VIM Openvim plugin +make -C RO-VIM-openvim clean package +cp RO-VIM-openvim/deb_dist/python3-osm-rovim-openvim_*.deb deb_dist/ + +# VIM AWS plugin +make -C RO-VIM-aws clean package +cp RO-VIM-aws/deb_dist/python3-osm-rovim-aws_*.deb deb_dist/ + +# VIM fos plugin +make -C RO-VIM-fos clean package +cp RO-VIM-fos/deb_dist/python3-osm-rovim-fos_*.deb deb_dist/ + +# VIM azure plugin +make -C RO-VIM-azure clean package +cp RO-VIM-azure/deb_dist/python3-osm-rovim-azure_*.deb deb_dist/ + +# VIM Opennebula plugin +make -C RO-VIM-opennebula clean package +cp RO-VIM-opennebula/deb_dist/python3-osm-rovim-opennebula_*.deb deb_dist/ diff --git a/devops-stages/stage-test.sh b/devops-stages/stage-test.sh index cb72fb1e..13cef859 100755 --- a/devops-stages/stage-test.sh +++ b/devops-stages/stage-test.sh @@ -13,6 +13,6 @@ # See the License for the specific language governing permissions and # limitations under the License. -flake8 osm_ro/wim osm_ro/vim_thread.py --max-line-length 120 \ +flake8 RO/osm_ro/wim RO/osm_ro/vim_thread.py --max-line-length 120 \ --exclude .svn,CVS,.gz,.git,__pycache__,.tox,local,temp,osm_im --ignore W291,W293,E226,E402,W504 diff --git a/docker/Dockerfile-local b/docker/Dockerfile-local deleted file mode 100644 index 1dff02d1..00000000 --- a/docker/Dockerfile-local +++ /dev/null @@ -1,92 +0,0 @@ -## -# 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. -## - -######################################################################## - -from ubuntu:18.04 - -LABEL authors="Gennadiy Dubina, Alfonso Tierno, Gerardo Garcia" - -RUN apt-get update && \ - DEBIAN_FRONTEND=noninteractive apt-get -y install software-properties-common && \ - DEBIAN_FRONTEND=noninteractive apt-get update && \ - DEBIAN_FRONTEND=noninteractive apt-get -y install git python python-pip && \ - DEBIAN_FRONTEND=noninteractive apt-get -y install wget tox && \ - DEBIAN_FRONTEND=noninteractive pip2 install pip==9.0.3 && \ - DEBIAN_FRONTEND=noninteractive pip2 install -U progressbar pyvmomi pyvcloud==19.1.1 && \ - DEBIAN_FRONTEND=noninteractive pip2 install -U fog05rest && \ - DEBIAN_FRONTEND=noninteractive pip2 install -U azure && \ - DEBIAN_FRONTEND=noninteractive apt-get -y install python-requests && \ - DEBIAN_FRONTEND=noninteractive apt-get -y install python-novaclient python-keystoneclient python-glanceclient python-cinderclient python-neutronclient python-networking-l2gw && \ - DEBIAN_FRONTEND=noninteractive apt-get -y install python-cffi libmysqlclient-dev libssl-dev libffi-dev python-mysqldb && \ - DEBIAN_FRONTEND=noninteractive apt-get -y install python-openstacksdk python-openstackclient && \ - DEBIAN_FRONTEND=noninteractive apt-get -y install python-networkx && \ - DEBIAN_FRONTEND=noninteractive apt-get -y install genisoimage && \ - DEBIAN_FRONTEND=noninteractive pip2 install untangle && \ - DEBIAN_FRONTEND=noninteractive pip2 install pyone && \ - DEBIAN_FRONTEND=noninteractive pip2 install -e git+https://github.com/python-oca/python-oca#egg=oca && \ - DEBIAN_FRONTEND=noninteractive apt-get -y install mysql-client - -COPY . /root/RO - -RUN /root/RO/scripts/install-osm-im.sh --develop && \ - /root/RO/scripts/install-lib-osm-openvim.sh --develop && \ - make -C /root/RO prepare && \ - mkdir -p /var/log/osm && \ - pip2 install -e /root/RO/build && \ - rm -rf /root/.cache && \ - apt-get clean && \ - rm -rf /var/lib/apt/lists/* - -VOLUME /var/log/osm - -EXPOSE 9090 - -# Two mysql databases are needed (DB and DB_OVIM). Can be hosted on same or separated containers -# These ENV must be provided -# RO_DB_HOST: host of the main -# RO_DB_OVIM_HOST: ... if empty RO_DB_HOST is assumed -# RO_DB_ROOT_PASSWORD: this has to be provided first time for creating database. It will create and init only if empty! -# RO_DB_OVIM_ROOT_PASSWORD: ... if empty RO_DB_ROOT_PASSWORD is assumed -# RO_DB_USER: default value 'mano' -# RO_DB_OVIM_USER: default value 'mano' -# RO_DB_PASSWORD: default value 'manopw' -# RO_DB_OVIM_PASSWORD: default value 'manopw' -# RO_DB_PORT: default value '3306' -# RO_DB_OVIM_PORT: default value '3306' -# RO_DB_NAME: default value 'mano_db' -# RO_DB_OVIM_NAME: default value 'mano_vim_db' -# RO_LOG_FILE: default log to stderr if not defined - -ENV RO_DB_HOST="" \ - RO_DB_OVIM_HOST="" \ - RO_DB_ROOT_PASSWORD="" \ - RO_DB_OVIM_ROOT_PASSWORD="" \ - RO_DB_USER=mano \ - RO_DB_OVIM_USER=mano \ - RO_DB_PASSWORD=manopw \ - RO_DB_OVIM_PASSWORD=manopw \ - RO_DB_PORT=3306 \ - RO_DB_OVIM_PORT=3306 \ - RO_DB_NAME=mano_db \ - RO_DB_OVIM_NAME=mano_vim_db \ - OPENMANO_TENANT=osm \ - RO_LOG_LEVEL=DEBUG - -CMD RO-start.sh - -# HEALTHCHECK --start-period=30s --interval=10s --timeout=5s --retries=12 \ -# CMD curl --silent --fail localhost:9090/openmano/tenants || exit 1 diff --git a/requirements.txt b/requirements.txt deleted file mode 100644 index bda5b8a4..00000000 --- a/requirements.txt +++ /dev/null @@ -1,25 +0,0 @@ -PyYAML -bottle -MySQL-python -jsonschema -paramiko -argcomplete -requests -logutils -python-openstackclient -python-novaclient -python-keystoneclient -python-glanceclient -python-neutronclient -networking-l2gw -python-cinderclient -pyvcloud==19.1.1 -pyvmomi -progressbar -prettytable -boto -genisoimage -untangle -pyone -oca -azure diff --git a/scripts/python-osm-ro.postinst b/scripts/python-osm-ro.postinst deleted file mode 100755 index 0f6e5a8f..00000000 --- a/scripts/python-osm-ro.postinst +++ /dev/null @@ -1,58 +0,0 @@ -#!/bin/bash - -## -# 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. -# -# For those usages not covered by the Apache License, Version 2.0 please -# contact with: OSM_TECH@list.etsi.org -## - -echo "POST INSTALL OSM-RO" -OSMRO_PATH=`python -c 'import osm_ro; print osm_ro.__path__[0]'` -#OSMLIBOVIM_PATH=`python -c 'import lib_osm_openvim; print lib_osm_openvim.__path__[0]'` - -#Pip packages required for vmware connector -pip2 install pip==9.0.3 -pip2 install --upgrade pyvcloud==19.1.1 -pip2 install --upgrade progressbar -pip2 install --upgrade prettytable -pip2 install --upgrade pyvmomi -pip2 install --upgrade pyang pyangbind -pip2 install untangle -pip2 install pyone -pip2 install -e git+https://github.com/python-oca/python-oca#egg=oca -pip2 install azure - -# Packages required for fos connector -pip2 install fog05rest - - -systemctl enable osm-ro.service - -#Creation of log folder -mkdir -p /var/log/osm - -#configure arg-autocomplete for this user -su $SUDO_USER -c 'activate-global-python-argcomplete --user' -if ! su $SUDO_USER -c 'grep -q bash_completion.d/python-argcomplete.sh ${HOME}/.bashrc' -then - echo " inserting .bash_completion.d/python-argcomplete.sh execution at .bashrc" - su $SUDO_USER -c 'echo ". ${HOME}/.bash_completion.d/python-argcomplete.sh" >> ~/.bashrc' -fi - -echo ' -To make OSM RO work, you have to install mysql and a database, and finally start osm-ro service' -echo " ${OSMRO_PATH}/database_utils/install-db-server.sh # -h for help" -echo ' service osm-ro start' - - diff --git a/setup.py b/setup.py deleted file mode 100755 index 5d78ec3b..00000000 --- a/setup.py +++ /dev/null @@ -1,73 +0,0 @@ -#!/usr/bin/env python - -#from distutils.core import setup -#from distutils.command.install_data import install_data -from setuptools import setup -from os import system -#import glob - -_name = 'osm_ro' -_description = 'OSM Resource Orchestrator' -_author = 'ETSI OSM' -_author_email = 'alfonso.tiernosepulveda@telefonica.com' -_maintainer = 'garciadeblas' -_maintainer_email = 'gerardo.garciadeblas@telefonica.com' -_license = 'Apache 2.0' -_url = 'https://osm.etsi.org/gitweb/?p=osm/RO.git;a=summary' -_requirements = [ - "six", # python 2 x 3 compatibility - "PyYAML", - "bottle", - #"mysqlclient", - #"MySQLdb", - "jsonschema", - "paramiko", - "argcomplete", - "requests", - "logutils", - "python-openstackclient", - "python-novaclient", - "python-keystoneclient", - "python-glanceclient", - "python-neutronclient", - "python-cinderclient", - "networking-l2gw", - #"pyvcloud", - #"progressbar", - "prettytable", - #"pyvmomi", - "boto", - #"lib_osm_openvim", - #"osm_im", - "pycrypto", - "netaddr", -] - -setup(name=_name, - version_command=('git describe --match v*', 'pep440-git-full'), - description = _description, - long_description = open('README.rst').read(), - author = _author, - author_email = _author_email, - maintainer = _maintainer, - maintainer_email = _maintainer_email, - url = _url, - license = _license, - packages = [_name], - #packages = ['osm_ro', 'osm_roclient'], - package_dir = {_name: _name}, - package_data = {_name: ['vnfs/*.yaml', 'vnfs/examples/*.yaml', - 'scenarios/*.yaml', 'scenarios/examples/*.yaml', - 'instance-scenarios/examples/*.yaml', 'database_utils/*', - 'scripts/*']}, - data_files = [('/etc/osm/', ['osm_ro/openmanod.cfg']), - ('/etc/systemd/system/', ['osm_ro/osm-ro.service']), - ], - scripts=['openmanod', 'openmano', 'osm_ro/scripts/service-openmano', 'osm_ro/scripts/openmano-report', - 'osm_ro/scripts/RO-start.sh'], - install_requires=_requirements, - include_package_data=True, - setup_requires=['setuptools-version-command'], - #test_suite='nose.collector', - ) - diff --git a/stdeb.cfg b/stdeb.cfg deleted file mode 100644 index 3751334c..00000000 --- a/stdeb.cfg +++ /dev/null @@ -1,6 +0,0 @@ -[DEFAULT] -Suite: xenial -XS-Python-Version: >= 2.7 -Maintainer: Gerardo Garcia -Depends: python-pip, libmysqlclient-dev, libssl-dev, libffi-dev, python-argcomplete, python-boto, python-bottle, python-jsonschema, python-logutils, python-cinderclient, python-glanceclient, python-keystoneclient, python-neutronclient, python-networking-l2gw, python-novaclient, python-openstackclient, python-mysqldb, python-lib-osm-openvim, python-osm-im, python-networkx, genisoimage - diff --git a/test-docker/Dockerfile-devops b/test-docker/Dockerfile-devops new file mode 100644 index 00000000..25eb0130 --- /dev/null +++ b/test-docker/Dockerfile-devops @@ -0,0 +1,65 @@ +## +# Copyright 2019 ETSI +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +## + +######################################################################## + +from ubuntu:18.04 + +MAINTAINER Alfonso Tierno + +RUN apt-get update && apt-get -y install curl software-properties-common git tox python3-pip \ + && python3 -m pip install --upgrade pip && python3 -m pip install pyangbind + +ARG REPOSITORY_BASE=http://osm-download.etsi.org/repository/osm/debian +ARG RELEASE=ReleaseSIX-daily +ARG REPOSITORY_KEY=OSM%20ETSI%20Release%20Key.gpg +ARG REPOSITORY=testing + +RUN curl ${REPOSITORY_BASE}/${RELEASE}/${REPOSITORY_KEY} | apt-key add - +RUN add-apt-repository -y "deb ${REPOSITORY_BASE}/${RELEASE} ${REPOSITORY} IM common openvim" && apt-get update + +ARG RO_VERSION +ARG IM_VERSION + +COPY temp /app +RUN DEBIAN_FRONTEND=noninteractive apt-get install -y python3-osm-im${IM_VERSION} \ + && DEBIAN_FRONTEND=noninteractive dpkg -i --force-depends /app/*.deb \ + && DEBIAN_FRONTEND=noninteractive apt-get -y -f install + +EXPOSE 9090 + +# Two mysql databases are needed (DB and DB_OVIM). Can be hosted on same or separated containers +# These ENV must be provided +ENV RO_DB_HOST="" +ENV RO_DB_OVIM_HOST="" + # if empty RO_DB_HOST is assumed + +# These ENV should be provided first time for creating database. It will create and init only if empty! +ENV RO_DB_ROOT_PASSWORD="" +ENV RO_DB_OVIM_ROOT_PASSWORD="" + # if empty RO_DB_ROOT_PASSWORD is assumed + +# These ENV can be provided, but default values are ok +ENV RO_DB_USER=mano +ENV RO_DB_OVIM_USER=mano +ENV RO_DB_PASSWORD=manopw +ENV RO_DB_OVIM_PASSWORD=manopw +ENV RO_DB_PORT=3306 +ENV RO_DB_OVIM_PORT=3306 +ENV RO_DB_NAME=mano_db +ENV RO_DB_OVIM_NAME=mano_vim_db + +CMD RO-start.sh diff --git a/test-docker/test-gen-devops.sh b/test-docker/test-gen-devops.sh new file mode 100755 index 00000000..3f797876 --- /dev/null +++ b/test-docker/test-gen-devops.sh @@ -0,0 +1,65 @@ +#!/bin/bash + +## +# 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. +# +# For those usages not covered by the Apache License, Version 2.0 please +# contact with: nfvlabs@tid.es +## + +# Generates the debian packages; and then generates a docker image base on Dockerfile-devops and update a +# running docker stack with the generated image + +HERE=$(dirname $(readlink -f ${BASH_SOURCE[0]})) +export RO_BASE=$(dirname $HERE) + +# clean +docker rm -f ro_pkg 2>/dev/null && echo docker ro_pkg removed +rm -rf $HERE/temp/* +mkdir -p $HERE/temp + +echo -e "\n\n[STAGE 1] Builind dockerfile userd for the package generation" +docker build $RO_BASE -f $RO_BASE/Dockerfile -t opensourcemano/ro_pkg +sleep 2 + +echo "[STAGE 1.1] Generting packages inside docker ro_pkg" +docker run -d --name ro_pkg opensourcemano/ro_pkg bash -c 'sleep 3600' +docker cp $RO_BASE ro_pkg:/RO +docker exec ro_pkg bash -c 'cd /RO; ./devops-stages/stage-build.sh' +deb_files=`docker exec ro_pkg bash -c 'ls /RO/deb_dist/'` +[ -z "$deb_files" ] && echo "No packages generated" >&2 && exit 1 +echo $deb_files + +echo -e "\n\n[STAGE 1.2] Print package information and copy to '$HERE/temp/'" +# print package information and copy to "$HERE/temp/" +for deb_file in $deb_files ; do + echo; echo; echo + echo $deb_file info: + echo "===========================" + docker cp ro_pkg:/RO/deb_dist/$deb_file $HERE/temp/ + dpkg -I $HERE/temp/$(basename $deb_file) +done + +# docker rm -f ro_pkg +echo -e "\n\n[STAGE 2] Building docker image opensourcemano/ro:py3_devops based on debian packages" +docker build $HERE -f $HERE/Dockerfile-devops -t opensourcemano/ro:py3_devops || + ! echo "error generating devops dockerfile" >&2 || exit 1 +sleep 2 +# docker run -d --name ro_devops opensourcemano/ro:py3_devops +# docker run -ti exec ro_devops ro tenant-list || ! echo "Cannot exec ro client to get server tenants" >&2 || exit 1 + +echo -e "\n\n[STAGE 3] Update service osm_ro with generated docker image" +docker service update osm_ro --force --image opensourcemano/ro:py3_devops +sleep 2 +docker container prune -f +docker service logs osm_ro diff --git a/test-docker/test-gen-local.sh b/test-docker/test-gen-local.sh new file mode 100755 index 00000000..0b9c73e9 --- /dev/null +++ b/test-docker/test-gen-local.sh @@ -0,0 +1,32 @@ +#!/bin/bash + +## +# 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. +# +# For those usages not covered by the Apache License, Version 2.0 please +# contact with: nfvlabs@tid.es +## + +# Generates a docker image base on Dockerfile-local and update a running docker stack with the generated image + +HERE=$(dirname $(readlink -f ${BASH_SOURCE[0]})) +export RO_BASE=$(dirname $HERE) + +echo -e "\n\n[STAGE 1] Building docker image opensourcemano/ro:py3_local based on debian packages" +docker build $RO_BASE -f $RO_BASE/Dockerfile-local -t opensourcemano/ro:py3_local || + ! echo "error generating local dockerfile" >&2 || exit 1 +sleep 2 +docker service update osm_ro --force --image opensourcemano/ro:py3_local +sleep 2 +docker container prune -f +docker service logs osm_ro diff --git a/tox.ini b/tox.ini deleted file mode 100644 index e451bb80..00000000 --- a/tox.ini +++ /dev/null @@ -1,23 +0,0 @@ -[tox] -#envlist = py27,py3 -envlist = py27 -toxworkdir={homedir}/.tox - -[testenv] -deps=nose - mock -commands=nosetests - -[testenv:flake8] -basepython = python -deps = flake8 -# TODO for the moment few files are tested. -commands = flake8 osm_ro/wim --max-line-length 120 \ - --exclude .svn,CVS,.gz,.git,__pycache__,.tox,local,temp,osm_im --ignore W291,W293,E226,E402,W504 - -[testenv:build] -basepython = python -deps = stdeb - setuptools-version-command -commands = python setup.py --command-packages=stdeb.command bdist_deb - -- 2.17.1