From 308ed21a13c44ad685e16160927b8dcc35ced306 Mon Sep 17 00:00:00 2001 From: Toshiaki Takahashi Date: Mon, 15 Feb 2021 23:29:04 +0900 Subject: [PATCH] Separate nodes of FT and split FT Cherry-picked the following commits from the master branch. No functional changes are included. * 06b58b9e Increase timeout value of heat stack creation * 0d412ba7 Add new FT set for tests with separated NFVO * ba813054 Split FT to Legacy and SOL implementation * 578b12e9 Add a seperate controller subnode to subdivide the memory load Change-Id: I94c692a0a0576fbffdd7781994e99c476bb145df --- .zuul.yaml | 75 +++- devstack/lib/tacker | 52 ++- devstack/plugin.sh | 8 +- devstack/settings | 54 ++- playbooks/devstack/pre.yaml | 1 + playbooks/devstack/run.yaml | 2 +- roles/modify-heat-policy/tasks/main.yaml | 9 + roles/setup-default-vim/tasks/main.yaml | 125 +++--- .../BaseHOT/simple/helloworld3.yaml | 101 +++++ .../BaseHOT/simple/nested/VDU1.yaml | 63 +++ .../BaseHOT/simple/nested/VDU2.yaml | 61 +++ .../Definitions/helloworld3_df_simple.yaml | 396 ++++++++++++++++++ .../Definitions/helloworld3_top.vnfd.yaml | 31 ++ .../Definitions/helloworld3_types.yaml | 55 +++ .../nfv/functional6/TOSCA-Metadata/TOSCA.meta | 4 + .../nfv/functional6/UserData}/__init__.py | 0 .../nfv/functional6/UserData/lcm_user_data.py | 35 ++ .../functional/{vnflcm => legacy}/__init__.py | 0 .../{vnfm => legacy/nfvo}/__init__.py | 0 .../functional/{ => legacy}/nfvo/test_nfvo.py | 0 .../functional/{ => legacy}/nfvo/test_vim.py | 0 .../{vnfpkgm => legacy/vnfm}/__init__.py | 0 .../{ => legacy}/vnfm/test_tosca_vnf.py | 0 .../{ => legacy}/vnfm/test_tosca_vnf_alarm.py | 0 .../vnfm/test_tosca_vnf_block_storage.py | 0 .../vnfm/test_tosca_vnf_floatingip.py | 0 .../vnfm/test_tosca_vnf_maintenance.py | 0 .../vnfm/test_tosca_vnf_multiple_vdu.py | 0 .../vnfm/test_tosca_vnf_reservation.py | 0 .../{ => legacy}/vnfm/test_tosca_vnf_scale.py | 0 .../{ => legacy}/vnfm/test_tosca_vnfc.py | 2 +- .../{ => legacy}/vnfm/test_tosca_vnfd.py | 0 .../functional/{ => legacy}/vnfm/test_vnf.py | 0 .../{ => legacy}/vnfm/test_vnf_monitoring.py | 0 .../vnfm/test_vnf_placement_policy.py | 0 .../{ => legacy}/vnfm/test_vnfm_param.py | 0 tacker/tests/functional/sol/__init__.py | 0 .../tests/functional/sol/vnflcm/__init__.py | 0 .../tests/functional/{ => sol}/vnflcm/base.py | 2 +- .../{ => sol}/vnflcm/fake_vnflcm.py | 0 .../{ => sol}/vnflcm/fake_vnfpkgm.py | 0 .../{ => sol}/vnflcm/test_kubernetes.py | 4 +- .../{ => sol}/vnflcm/test_vnf_instance.py | 2 +- .../test_vnf_instance_with_user_data.py | 28 +- .../tests/functional/sol/vnfpkgm/__init__.py | 0 .../{ => sol}/vnfpkgm/test_vnf_package.py | 2 +- .../functional/sol_separated_nfvo/__init__.py | 0 .../sol_separated_nfvo/vnflcm/__init__.py | 0 .../sol_separated_nfvo/vnflcm/fake_grant.py | 205 +++++++++ .../sol_separated_nfvo/vnflcm/fake_vnfpkgm.py | 105 +++++ ...f_instance_with_user_data_nfvo_separate.py | 316 ++++++++++++++ tox.ini | 18 + 52 files changed, 1616 insertions(+), 140 deletions(-) create mode 100644 roles/modify-heat-policy/tasks/main.yaml create mode 100644 tacker/tests/etc/samples/etsi/nfv/functional6/BaseHOT/simple/helloworld3.yaml create mode 100644 tacker/tests/etc/samples/etsi/nfv/functional6/BaseHOT/simple/nested/VDU1.yaml create mode 100644 tacker/tests/etc/samples/etsi/nfv/functional6/BaseHOT/simple/nested/VDU2.yaml create mode 100644 tacker/tests/etc/samples/etsi/nfv/functional6/Definitions/helloworld3_df_simple.yaml create mode 100644 tacker/tests/etc/samples/etsi/nfv/functional6/Definitions/helloworld3_top.vnfd.yaml create mode 100644 tacker/tests/etc/samples/etsi/nfv/functional6/Definitions/helloworld3_types.yaml create mode 100644 tacker/tests/etc/samples/etsi/nfv/functional6/TOSCA-Metadata/TOSCA.meta rename tacker/tests/{functional/nfvo => etc/samples/etsi/nfv/functional6/UserData}/__init__.py (100%) create mode 100644 tacker/tests/etc/samples/etsi/nfv/functional6/UserData/lcm_user_data.py rename tacker/tests/functional/{vnflcm => legacy}/__init__.py (100%) rename tacker/tests/functional/{vnfm => legacy/nfvo}/__init__.py (100%) rename tacker/tests/functional/{ => legacy}/nfvo/test_nfvo.py (100%) rename tacker/tests/functional/{ => legacy}/nfvo/test_vim.py (100%) rename tacker/tests/functional/{vnfpkgm => legacy/vnfm}/__init__.py (100%) rename tacker/tests/functional/{ => legacy}/vnfm/test_tosca_vnf.py (100%) rename tacker/tests/functional/{ => legacy}/vnfm/test_tosca_vnf_alarm.py (100%) rename tacker/tests/functional/{ => legacy}/vnfm/test_tosca_vnf_block_storage.py (100%) rename tacker/tests/functional/{ => legacy}/vnfm/test_tosca_vnf_floatingip.py (100%) rename tacker/tests/functional/{ => legacy}/vnfm/test_tosca_vnf_maintenance.py (100%) rename tacker/tests/functional/{ => legacy}/vnfm/test_tosca_vnf_multiple_vdu.py (100%) rename tacker/tests/functional/{ => legacy}/vnfm/test_tosca_vnf_reservation.py (100%) rename tacker/tests/functional/{ => legacy}/vnfm/test_tosca_vnf_scale.py (100%) rename tacker/tests/functional/{ => legacy}/vnfm/test_tosca_vnfc.py (98%) rename tacker/tests/functional/{ => legacy}/vnfm/test_tosca_vnfd.py (100%) rename tacker/tests/functional/{ => legacy}/vnfm/test_vnf.py (100%) rename tacker/tests/functional/{ => legacy}/vnfm/test_vnf_monitoring.py (100%) rename tacker/tests/functional/{ => legacy}/vnfm/test_vnf_placement_policy.py (100%) rename tacker/tests/functional/{ => legacy}/vnfm/test_vnfm_param.py (100%) create mode 100644 tacker/tests/functional/sol/__init__.py create mode 100644 tacker/tests/functional/sol/vnflcm/__init__.py rename tacker/tests/functional/{ => sol}/vnflcm/base.py (99%) rename tacker/tests/functional/{ => sol}/vnflcm/fake_vnflcm.py (100%) rename tacker/tests/functional/{ => sol}/vnflcm/fake_vnfpkgm.py (100%) rename tacker/tests/functional/{ => sol}/vnflcm/test_kubernetes.py (99%) rename tacker/tests/functional/{ => sol}/vnflcm/test_vnf_instance.py (99%) rename tacker/tests/functional/{ => sol}/vnflcm/test_vnf_instance_with_user_data.py (98%) create mode 100644 tacker/tests/functional/sol/vnfpkgm/__init__.py rename tacker/tests/functional/{ => sol}/vnfpkgm/test_vnf_package.py (99%) create mode 100644 tacker/tests/functional/sol_separated_nfvo/__init__.py create mode 100644 tacker/tests/functional/sol_separated_nfvo/vnflcm/__init__.py create mode 100644 tacker/tests/functional/sol_separated_nfvo/vnflcm/fake_grant.py create mode 100644 tacker/tests/functional/sol_separated_nfvo/vnflcm/fake_vnfpkgm.py create mode 100644 tacker/tests/functional/sol_separated_nfvo/vnflcm/test_vnf_instance_with_user_data_nfvo_separate.py diff --git a/.zuul.yaml b/.zuul.yaml index 045b64f52..6d7f2fcc8 100644 --- a/.zuul.yaml +++ b/.zuul.yaml @@ -1,8 +1,10 @@ - nodeset: - name: openstack-3-nodes-focal + name: openstack-4-nodes-focal nodes: - name: controller label: ubuntu-focal + - name: controller-tacker + label: ubuntu-focal - name: compute1 label: ubuntu-focal - name: compute2 @@ -16,6 +18,7 @@ # Nodes that are not the controller - name: subnode nodes: + - controller-tacker - compute1 - compute2 # Switch node for multinode networking setup @@ -25,15 +28,16 @@ # Peer nodes for multinode networking setup - name: peers nodes: + - controller-tacker - compute1 - compute2 - job: - name: tacker-functional-devstack-multinode-python3 + name: tacker-functional-devstack-multinode-legacy parent: devstack description: | Base multinodes job for devstack-based functional tests - nodeset: openstack-3-nodes-focal + nodeset: openstack-4-nodes-focal pre-run: playbooks/devstack/pre.yaml run: playbooks/devstack/run.yaml post-run: playbooks/devstack/post.yaml @@ -75,8 +79,15 @@ vars: devstack_localrc: CELLSV2_SETUP: singleconductor + PHYSICAL_NETWORK: mgmtphysnet0 + OVS_BRIDGE_MAPPINGS: public:br-ex,mgmtphysnet0:br-infra Q_DVR_MODE: dvr DATABASE_TYPE: mysql + KEYSTONE_SERVICE_HOST: "{{ hostvars['controller']['nodepool']['private_ipv4'] }}" + MYSQL_HOST: "{{ hostvars['controller']['nodepool']['private_ipv4'] }}" + TACKER_HOST: "{{ hostvars['controller-tacker']['nodepool']['private_ipv4'] }}" + TACKER_MODE: standalone + IS_ZUUL_FT: True Q_SERVICE_PLUGIN_CLASSES: router,neutron.services.metering.metering_plugin.MeteringPlugin,networking_sfc.services.flowclassifier.plugin.FlowClassifierPlugin,neutron.services.qos.qos_plugin.QoSPlugin,qos Q_ML2_PLUGIN_EXT_DRIVERS: port_security,qos L2_AGENT_EXTENSIONS: qos @@ -101,7 +112,6 @@ # https://storyboard.openstack.org/#!/story/2007732 # barbican: https://opendev.org/openstack/barbican mistral: https://opendev.org/openstack/mistral - tacker: https://opendev.org/openstack/tacker blazar: https://opendev.org/openstack/blazar fenix: https://opendev.org/x/fenix devstack_services: @@ -138,9 +148,6 @@ c-sch: true c-vol: true cinder: true - # Tacker services - tacker: true - tacker-conductor: true # Services we don't need. # This section is not really needed, it's for readability. horizon: false @@ -152,14 +159,33 @@ s-proxy: false c-bak: false tox_install_siblings: false - tox_envlist: dsvm-functional + controller-tacker: + devstack_local_conf: {} + devstack_services: + q-agt: true + # Tacker services + tacker: true + tacker-conductor: true + devstack_plugins: + # Temporarily remove because of Ubuntu Focal Migration issue + # https://storyboard.openstack.org/#!/story/2008121 + # https://review.opendev.org/#/c/752294/ + # ceilometer: https://opendev.org/openstack/ceilometer + tacker: https://opendev.org/openstack/tacker + tox_envlist: dsvm-functional-legacy group-vars: subnode: devstack_localrc: CELLSV2_SETUP: singleconductor PHYSICAL_NETWORK: mgmtphysnet0 OVS_BRIDGE_MAPPINGS: public:br-ex,mgmtphysnet0:br-infra + Q_DVR_MODE: dvr DATABASE_TYPE: mysql + KEYSTONE_SERVICE_HOST: "{{ hostvars['controller']['nodepool']['private_ipv4'] }}" + MYSQL_HOST: "{{ hostvars['controller']['nodepool']['private_ipv4'] }}" + TACKER_HOST: "{{ hostvars['controller-tacker']['nodepool']['private_ipv4'] }}" + TACKER_MODE: standalone + IS_ZUUL_FT: True # Since a VirtualInterfaceCreateException occurs during a test, # the setting of network-vif-plugged is changed by the reference of # the following URL. @@ -182,6 +208,35 @@ horizon: false tls-proxy: false +- job: + name: tacker-functional-devstack-multinode-sol + parent: tacker-functional-devstack-multinode-legacy + description: | + Multinodes job for SOL devstack-based functional tests + host-vars: + controller-tacker: + tox_envlist: dsvm-functional-sol + +- job: + name: tacker-functional-devstack-multinode-sol-separated-nfvo + parent: tacker-functional-devstack-multinode-sol + description: | + Multinodes job for SOL devstack-based functional tests + with separated NFVO + host-vars: + controller-tacker: + devstack_local_conf: + post-config: + $TACKER_CONF: + connect_vnf_packages: + base_url: http://127.0.0.1:9990/vnfpkgm/v1/vnf_packages + pipeline: package_content,vnfd,artifacts + connect_grant: + base_url: http://127.0.0.1:9990/grant/v1/grants + openstack_vim: + stack_retries: 120 + tox_envlist: dsvm-functional-sol-separated-nfvo + - project: templates: - check-requirements @@ -192,4 +247,6 @@ - release-notes-jobs-python3 check: jobs: - - tacker-functional-devstack-multinode-python3 + - tacker-functional-devstack-multinode-legacy + - tacker-functional-devstack-multinode-sol + - tacker-functional-devstack-multinode-sol-separated-nfvo diff --git a/devstack/lib/tacker b/devstack/lib/tacker index b5c08a774..e6cbe56d5 100644 --- a/devstack/lib/tacker +++ b/devstack/lib/tacker @@ -80,7 +80,6 @@ TACKER_NOVA_URL=${TACKER_NOVA_URL:-http://127.0.0.1:8774/v2} TACKER_NOVA_CA_CERTIFICATES_FILE=${TACKER_NOVA_CA_CERTIFICATES_FILE:-} TACKER_NOVA_API_INSECURE=${TACKER_NOVA_API_INSECURE:-False} -HEAT_CONF_DIR=/etc/heat CEILOMETER_CONF_DIR=/etc/ceilometer source ${TACKER_DIR}/tacker/tests/contrib/post_test_hook_lib.sh @@ -91,13 +90,6 @@ GLANCE_DEFAULT_BACKEND=${GLANCE_DEFAULT_BACKEND:=file} # Functions # --------- -# Test if any Tacker services are enabled -# is_tacker_enabled -function is_tacker_enabled { - [[ ,${ENABLED_SERVICES} =~ ,"tacker" ]] && return 0 - return 1 -} - # create_tacker_cache_dir() - Part of the _tacker_setup_keystone() process function create_tacker_cache_dir { # Create cache dir @@ -105,6 +97,28 @@ function create_tacker_cache_dir { rm -f $TACKER_AUTH_CACHE_DIR/* } +# function install_db_client_mysql() - ensure mysql client is installed +function install_db_client_mysql { + if is_oraclelinux; then + install_package mysql-community-client + elif is_fedora || is_suse; then + install_package mariadb-client + elif is_ubuntu; then + install_package mysql-client + else + exit_distro_not_supported "mysql client installation" + fi +} + +# function install_db_client_postgresql() - ensure postgresql client is installed +function install_db_client_postgresql { + if is_ubuntu || is_fedora || is_suse; then + install_package postgresql-client + else + exit_distro_not_supported "postgresql client installation" + fi +} + # create_tacker_accounts() - Set up common required tacker accounts # Tenant User Roles @@ -123,9 +137,9 @@ function create_tacker_accounts { "nfv-orchestration" "Tacker NFV Orchestration Service") get_or_create_endpoint $tacker_service \ "$REGION_NAME" \ - "$TACKER_PROTOCOL://$SERVICE_HOST:$TACKER_PORT/" \ - "$TACKER_PROTOCOL://$SERVICE_HOST:$TACKER_PORT/" \ - "$TACKER_PROTOCOL://$SERVICE_HOST:$TACKER_PORT/" + "$TACKER_PROTOCOL://$TACKER_HOST:$TACKER_PORT/" \ + "$TACKER_PROTOCOL://$TACKER_HOST:$TACKER_PORT/" \ + "$TACKER_PROTOCOL://$TACKER_HOST:$TACKER_PORT/" fi } @@ -134,6 +148,9 @@ function create_tacker_accounts { # init_tacker() - Initialize databases, etc. function init_tacker { + # In case db service is disabled, which would have installed cli commands. + install_db_client_$DATABASE_TYPE + recreate_database $TACKER_DB_NAME # Run Tacker db migrations @@ -241,7 +258,7 @@ function configure_tacker { iniset $TACKER_CONF DEFAULT auth_strategy $TACKER_AUTH_STRATEGY _tacker_setup_keystone $TACKER_CONF keystone_authtoken - if [[ "${TACKER_MODE}" == "all" ]]; then + if [[ "${TACKER_MODE}" == "all" || -v IS_ZUUL_FT ]]; then iniset "/$Q_PLUGIN_CONF_FILE" ml2_type_flat flat_networks $PUBLIC_PHYSICAL_NETWORK,$MGMT_PHYS_NET iniset "/$Q_PLUGIN_CONF_FILE" ovs bridge_mappings $PUBLIC_PHYSICAL_NETWORK:$PUBLIC_BRIDGE,$MGMT_PHYS_NET:$BR_MGMT @@ -417,9 +434,9 @@ function tacker_create_initial_network { sudo ip address add ${NETWORK_GATEWAY_MGMT_IP} dev ${BR_MGMT} } -function tacker_register_default_vim { +function tacker_setup_default_vim_resources { # Note: These must be the same as in tacker/tests/etc/samples/local-vim.yaml - # and devstack/lib/tacker/vim_config.yaml + # and devstack/vim_config.yaml DEFAULT_VIM_PROJECT_NAME="nfv" DEFAULT_VIM_USER="nfv_user" DEFAULT_VIM_PASSWORD="devstack" @@ -475,13 +492,6 @@ function tacker_register_default_vim { } -function modify_heat_flavor_policy_rule { - local policy_file=$HEAT_CONF_DIR/policy.yaml - touch $policy_file - # Allow non-admin projects with 'admin' roles to create flavors in Heat - echo '"resource_types:OS::Nova::Flavor": "role:admin"' >> $policy_file -} - function configure_maintenance_event_types { local event_definitions_file=$CEILOMETER_CONF_DIR/event_definitions.yaml local maintenance_events_file=$TACKER_DIR/etc/ceilometer/maintenance_event_types.yaml diff --git a/devstack/plugin.sh b/devstack/plugin.sh index 1d050d6ce..4bd7d7656 100644 --- a/devstack/plugin.sh +++ b/devstack/plugin.sh @@ -32,15 +32,13 @@ if is_service_enabled tacker; then tacker_horizon_install fi - if [[ "${TACKER_MODE}" == "all" ]]; then - echo_summary "Modifying Heat policy.json file" - modify_heat_flavor_policy_rule + if [[ "${TACKER_MODE}" == "all" || -v IS_ZUUL_FT ]]; then echo_summary "Setup initial tacker network" tacker_create_initial_network echo_summary "Check and download images for tacker initial" tacker_check_and_download_images - echo_summary "Registering default VIM" - tacker_register_default_vim + echo_summary "Setup default VIM resources" + tacker_setup_default_vim_resources if is_service_enabled ceilometer; then echo_summary "Configure maintenance event types" diff --git a/devstack/settings b/devstack/settings index 1f4a4c3dd..fc3573fd6 100644 --- a/devstack/settings +++ b/devstack/settings @@ -4,6 +4,28 @@ TACKER_MODE=${TACKER_MODE:-all} USE_BARBICAN=False KUBERNETES_VIM=${KUBERNETES_VIM:-False} +if [ "${TACKER_MODE}" == "all" -o ${IS_ZUUL_FT+yes} ]; then + MGMT_PHYS_NET=${MGMT_PHYS_NET:-mgmtphysnet0} + # br-infra is created by devstack multi node job + # https://opendev.org/zuul/zuul-jobs/src/branch/master/roles/multi-node-bridge + BR_MGMT=${BR_MGMT:-br-infra} + NET_MGMT=${NET_MGMT:-net_mgmt} + SUBNET_MGMT=${SUBNET_MGMT:-subnet_mgmt} + FIXED_RANGE_MGMT=${FIXED_RANGE_MGMT:-192.168.120.0/24} + NETWORK_GATEWAY_MGMT=${NETWORK_GATEWAY_MGMT:-192.168.120.1} + NETWORK_GATEWAY_MGMT_IP=${NETWORK_GATEWAY_MGMT_IP:-192.168.120.1/24} + + NET0=${NET0:-net0} + SUBNET0=${SUBNET0:-subnet0} + FIXED_RANGE0=${FIXED_RANGE0:-10.10.0.0/24} + NETWORK_GATEWAY0=${NETWORK_GATEWAY0:-10.10.0.1} + + NET1=${NET1:-net1} + SUBNET1=${SUBNET1:-subnet1} + FIXED_RANGE1=${FIXED_RANGE1:-10.10.1.0/24} + NETWORK_GATEWAY1=${NETWORK_GATEWAY1:-10.10.1.1} +fi + if [ "${TACKER_MODE}" == "all" ]; then # Nova disable_service n-net @@ -23,25 +45,6 @@ if [ "${TACKER_MODE}" == "all" ]; then enable_service tacker # enable tacker-conductor will make systemctl enable conductor service enable_service tacker-conductor - MGMT_PHYS_NET=${MGMT_PHYS_NET:-mgmtphysnet0} - # br-infra is created by devstack multi node job - # https://opendev.org/zuul/zuul-jobs/src/branch/master/roles/multi-node-bridge - BR_MGMT=${BR_MGMT:-br-infra} - NET_MGMT=${NET_MGMT:-net_mgmt} - SUBNET_MGMT=${SUBNET_MGMT:-subnet_mgmt} - FIXED_RANGE_MGMT=${FIXED_RANGE_MGMT:-192.168.120.0/24} - NETWORK_GATEWAY_MGMT=${NETWORK_GATEWAY_MGMT:-192.168.120.1} - NETWORK_GATEWAY_MGMT_IP=${NETWORK_GATEWAY_MGMT_IP:-192.168.120.1/24} - - NET0=${NET0:-net0} - SUBNET0=${SUBNET0:-subnet0} - FIXED_RANGE0=${FIXED_RANGE0:-10.10.0.0/24} - NETWORK_GATEWAY0=${NETWORK_GATEWAY0:-10.10.0.1} - - NET1=${NET1:-net1} - SUBNET1=${SUBNET1:-subnet1} - FIXED_RANGE1=${FIXED_RANGE1:-10.10.1.0/24} - NETWORK_GATEWAY1=${NETWORK_GATEWAY1:-10.10.1.1} if [ "${KUBERNETES_VIM}" == "True" ]; then KURYR_NEUTRON_DEFAULT_PROJECT="default" @@ -61,8 +64,17 @@ if [ "${TACKER_MODE}" == "all" ]; then done fi elif [ "${TACKER_MODE}" == "standalone" ]; then - # set the enabled services here. This will need tacker devstack plugin put as the last one in local.conf - ENABLED_SERVICES=key,horizon,tacker,tacker-conductor,mysql,dstat,barbican,mistral,mistral-api,mistral-engine,mistral-executor,mistral-event-engine + # TODO(takahashi-tsc) Remove gawk installation after the following bug is fixed. + # https://bugs.launchpad.net/devstack/+bug/1909041 + # post-config requires gawk. + # Generally, gawk is requires by Nova, + # but Nova is not mandatory for Tacker. + # So we install gawk manually until the bug is fixed. + install_package gawk + + enable_service dstat + enable_service tacker + enable_service tacker-conductor else die $LINENO "invalid value: $TACKER_MODE for TACKER_MODE" fi diff --git a/playbooks/devstack/pre.yaml b/playbooks/devstack/pre.yaml index a980ee244..5efc60ace 100644 --- a/playbooks/devstack/pre.yaml +++ b/playbooks/devstack/pre.yaml @@ -1,6 +1,7 @@ - hosts: all roles: - orchestrate-devstack + - modify-heat-policy - setup-default-vim - role: bindep bindep_profile: test diff --git a/playbooks/devstack/run.yaml b/playbooks/devstack/run.yaml index e5cd69eec..fefd9eee6 100644 --- a/playbooks/devstack/run.yaml +++ b/playbooks/devstack/run.yaml @@ -1,3 +1,3 @@ -- hosts: controller +- hosts: controller-tacker roles: - tox diff --git a/roles/modify-heat-policy/tasks/main.yaml b/roles/modify-heat-policy/tasks/main.yaml new file mode 100644 index 000000000..3d7eb9290 --- /dev/null +++ b/roles/modify-heat-policy/tasks/main.yaml @@ -0,0 +1,9 @@ +- name: Modify heat flavor policy rule + become: true + lineinfile: + path: /etc/heat/policy.yaml + regexp: '^"resource_types:OS::Nova::Flavor":' + line: '"resource_types:OS::Nova::Flavor": "role:admin"' + mode: 0644 + create: true + when: devstack_plugins['heat']|default(false) diff --git a/roles/setup-default-vim/tasks/main.yaml b/roles/setup-default-vim/tasks/main.yaml index 5a3676dab..c965a33ce 100644 --- a/roles/setup-default-vim/tasks/main.yaml +++ b/roles/setup-default-vim/tasks/main.yaml @@ -1,68 +1,67 @@ -- name: Copy files test setup default vim sh - copy: - remote_src=True - src={{ devstack_base_dir }}/tacker/tools/test-setup-default-vim.sh - dest={{ zuul_work_dir }}/tools/test-setup-default-vim.sh - mode=0755 - when: inventory_hostname == "controller" +- block: + - name: Copy tools/test-setup-default-vim.sh + copy: + remote_src=True + src={{ devstack_base_dir }}/tacker/tools/test-setup-default-vim.sh + dest={{ zuul_work_dir }}/tools/test-setup-default-vim.sh + mode=0755 -- name: Copy test vim file - copy: - remote_src=True - src={{ devstack_base_dir }}/tacker/tacker/tests/etc/samples/local-vim.yaml - dest={{ zuul_work_dir }}/tacker/tests/etc/samples/local-vim.yaml - when: inventory_hostname == "controller" + - name: Copy test vim file + copy: + remote_src=True + src={{ devstack_base_dir }}/tacker/tacker/tests/etc/samples/local-vim.yaml + dest={{ zuul_work_dir }}/tacker/tests/etc/samples/local-vim.yaml -- name: Check if project's tools/test-setup-default-vim.sh exists - stat: - path: "{{ zuul_work_dir }}/tools/test-setup-default-vim.sh" - register: p -- fail: - msg: > - {{ zuul_work_dir }}/tools/test-setup-default-vim.sh doesn't exists - or it doesn't have execute permission. - when: p.stat.exists != True or p.stat.executable != True + - name: Check if project's tools/test-setup-default-vim.sh exists + stat: + path: "{{ zuul_work_dir }}/tools/test-setup-default-vim.sh" + register: p + - fail: + msg: > + {{ zuul_work_dir }}/tools/test-setup-default-vim.sh doesn't exists + or it doesn't have execute permission. + when: p.stat.exists != True or p.stat.executable != True -- name: Get stackenv from devstack environment - slurp: - src: "{{ devstack_base_dir }}/devstack/.stackenv" - register: stackenv + - name: Get stackenv from devstack environment + slurp: + src: "{{ devstack_base_dir }}/devstack/.stackenv" + register: stackenv + + - name: Set a keystone authentication uri + set_fact: + auth_uri: "{{ + stackenv.content + | b64decode + | regex_replace('\n', ' ') + | regex_replace('^.*KEYSTONE_SERVICE_URI=([^ ]+).*$', '\\1') + }}" + when: + - p.stat.exists + + - name: Replace auth uri in test-setup-default-vim.sh and local-vim.yaml + replace: + path: "{{ item }}" + regexp: "http://127.0.0.1/identity" + replace: "{{ auth_uri }}" + with_items: + - "{{ zuul_work_dir }}/tools/test-setup-default-vim.sh" + - "{{ zuul_work_dir }}/tacker/tests/etc/samples/local-vim.yaml" + when: + - p.stat.exists + + - name: Replace the config file path in the test-setup-default-vim.sh + replace: + path: "{{ zuul_work_dir }}/tools/test-setup-default-vim.sh" + regexp: '(?<=config-file )([^ ]+)(?= )' + replace: "{{ ansible_env.HOME }}/{{ zuul_work_dir }}/tacker/tests/etc/samples/local-vim.yaml" + + - name: Run tools/test-setup-default-vim.sh + command: tools/test-setup-default-vim.sh + args: + chdir: "{{ zuul_work_dir }}" + when: + - p.stat.exists + - p.stat.executable -- name: Set a keystone authentication uri - set_fact: - auth_uri: "{{ - stackenv.content - | b64decode - | regex_replace('\n', ' ') - | regex_replace('^.*KEYSTONE_SERVICE_URI=([^ ]+).*$', '\\1') - }}" when: - - p.stat.exists - -- name: Replace the keystone authentication uri in the test-setup-default-vim.sh and local-vim.yaml - replace: - path: "{{ item }}" - regexp: "http://127.0.0.1/identity" - replace: "{{ auth_uri }}" - with_items: - - "{{ zuul_work_dir }}/tools/test-setup-default-vim.sh" - - "{{ zuul_work_dir }}/tacker/tests/etc/samples/local-vim.yaml" - when: - - inventory_hostname == 'controller' - - p.stat.exists - -- name: Replace the config file path in the test-setup-default-vim.sh - replace: - path: "{{ zuul_work_dir }}/tools/test-setup-default-vim.sh" - regexp: '(?<=config-file )([^ ]+)(?= )' - replace: "{{ ansible_env.HOME }}/{{ zuul_work_dir }}/tacker/tests/etc/samples/local-vim.yaml" - when: inventory_hostname == 'controller' - -- name: Run tools/test-setup-default-vim.sh - command: tools/test-setup-default-vim.sh - args: - chdir: "{{ zuul_work_dir }}" - when: - - inventory_hostname == 'controller' - - p.stat.exists - - p.stat.executable + - inventory_hostname == 'controller-tacker' diff --git a/tacker/tests/etc/samples/etsi/nfv/functional6/BaseHOT/simple/helloworld3.yaml b/tacker/tests/etc/samples/etsi/nfv/functional6/BaseHOT/simple/helloworld3.yaml new file mode 100644 index 000000000..6e5fb4992 --- /dev/null +++ b/tacker/tests/etc/samples/etsi/nfv/functional6/BaseHOT/simple/helloworld3.yaml @@ -0,0 +1,101 @@ +heat_template_version: 2013-05-23 +description: 'Simple Base HOT for Sample VNF' + +parameters: + nfv: + type: json + +resources: + VDU1: + type: OS::Heat::AutoScalingGroup + properties: + min_size: 1 + max_size: 3 + desired_capacity: 1 + resource: + type: VDU1.yaml + properties: + flavor: { get_param: [ nfv, VDU, VDU1, flavor ] } + image: { get_param: [ nfv, VDU, VDU1, image ] } + zone: { get_param: [ nfv, vdu, VDU1, zone ] } + net1: { get_param: [ nfv, CP, VDU1_CP1, network ] } + net2: { get_param: [ nfv, CP, VDU1_CP2, network ] } + net3: { get_resource: extmanageNW_1 } + net4: { get_resource: extmanageNW_2 } + net5: { get_resource: internalNW_1 } + VDU1_scale_out: + type: OS::Heat::ScalingPolicy + properties: + scaling_adjustment: 1 + auto_scaling_group_id: + get_resource: VDU1 + adjustment_type: change_in_capacity + VDU1_scale_in: + type: OS::Heat::ScalingPolicy + properties: + scaling_adjustment: -1 + auto_scaling_group_id: + get_resource: VDU1 + adjustment_type: change_in_capacity + VDU2: + type: OS::Heat::AutoScalingGroup + depends_on: VDU1 + properties: + min_size: 2 + max_size: 2 + desired_capacity: 2 + resource: + type: VDU2.yaml + properties: + flavor: { get_param: [ nfv, VDU, VDU2, flavor ] } + image: { get_param: [ nfv, VDU, VDU2, image ] } + zone: { get_param: [ nfv, vdu, VDU2, zone ] } + net1: { get_param: [ nfv, CP, VDU2_CP1, network ] } + net2: { get_param: [ nfv, CP, VDU2_CP2, network ] } + net3: { get_resource: extmanageNW_1 } + net4: { get_resource: extmanageNW_2 } + net5: { get_resource: internalNW_1 } + VDU2_scale_out: + type: OS::Heat::ScalingPolicy + properties: + scaling_adjustment: 1 + auto_scaling_group_id: + get_resource: VDU2 + adjustment_type: change_in_capacity + VDU2_scale_in: + type: OS::Heat::ScalingPolicy + properties: + scaling_adjustment: -1 + auto_scaling_group_id: + get_resource: VDU2 + adjustment_type: change_in_capacity + extmanageNW_1: + type: OS::Neutron::Net + extmanageNW_2: + type: OS::Neutron::Net + internalNW_1: + type: OS::Neutron::Net + extmanageNW_1_subnet: + type: OS::Neutron::Subnet + properties: + ip_version: 4 + network: + get_resource: extmanageNW_1 + cidr: 192.168.3.0/24 + extmanageNW_2_subnet: + type: OS::Neutron::Subnet + properties: + ip_version: 4 + network: + get_resource: extmanageNW_2 + cidr: 192.168.4.0/24 + internalNW_1_subnet: + type: OS::Neutron::Subnet + properties: + ip_version: 4 + network: + get_resource: internalNW_1 + cidr: 192.168.5.0/24 +outputs: {} + + diff --git a/tacker/tests/etc/samples/etsi/nfv/functional6/BaseHOT/simple/nested/VDU1.yaml b/tacker/tests/etc/samples/etsi/nfv/functional6/BaseHOT/simple/nested/VDU1.yaml new file mode 100644 index 000000000..b10f7375d --- /dev/null +++ b/tacker/tests/etc/samples/etsi/nfv/functional6/BaseHOT/simple/nested/VDU1.yaml @@ -0,0 +1,63 @@ +heat_template_version: 2013-05-23 +description: 'VDU1 HOT for Sample VNF' + +parameters: + flavor: + type: string + image: + type: string + zone: + type: string + net1: + type: string + net2: + type: string + net3: + type: string + net4: + type: string + net5: + type: string + +resources: + VDU1: + type: OS::Nova::Server + properties: + flavor: { get_param: flavor } + name: VDU1 + image: { get_param: image } + networks: + - port: + get_resource: VDU1_CP1 + - port: + get_resource: VDU1_CP2 + - port: + get_resource: VDU1_CP3 + - port: + get_resource: VDU1_CP4 + - port: + get_resource: VDU1_CP5 + availability_zone: { get_param: zone } + + VDU1_CP1: + type: OS::Neutron::Port + properties: + network: { get_param: net1 } + VDU1_CP2: + type: OS::Neutron::Port + properties: + network: { get_param: net2 } + VDU1_CP3: + type: OS::Neutron::Port + properties: + network: { get_param: net3 } + VDU1_CP4: + type: OS::Neutron::Port + properties: + network: { get_param: net4 } + VDU1_CP5: + type: OS::Neutron::Port + properties: + network: { get_param: net5 } + + diff --git a/tacker/tests/etc/samples/etsi/nfv/functional6/BaseHOT/simple/nested/VDU2.yaml b/tacker/tests/etc/samples/etsi/nfv/functional6/BaseHOT/simple/nested/VDU2.yaml new file mode 100644 index 000000000..c4772dad6 --- /dev/null +++ b/tacker/tests/etc/samples/etsi/nfv/functional6/BaseHOT/simple/nested/VDU2.yaml @@ -0,0 +1,61 @@ +heat_template_version: 2013-05-23 +description: 'VDU2 HOT for Sample VNF' + +parameters: + flavor: + type: string + image: + type: string + zone: + type: string + net1: + type: string + net2: + type: string + net3: + type: string + net4: + type: string + net5: + type: string + +resources: + VDU2: + type: OS::Nova::Server + properties: + flavor: { get_param: flavor } + name: VDU2 + image: { get_param: image } + networks: + - port: + get_resource: VDU2_CP1 + - port: + get_resource: VDU2_CP2 + - port: + get_resource: VDU2_CP3 + - port: + get_resource: VDU2_CP4 + - port: + get_resource: VDU2_CP5 + availability_zone: { get_param: zone } + + VDU2_CP1: + type: OS::Neutron::Port + properties: + network: { get_param: net1 } + VDU2_CP2: + type: OS::Neutron::Port + properties: + network: { get_param: net2 } + VDU2_CP3: + type: OS::Neutron::Port + properties: + network: { get_param: net3 } + VDU2_CP4: + type: OS::Neutron::Port + properties: + network: { get_param: net4 } + VDU2_CP5: + type: OS::Neutron::Port + properties: + network: { get_param: net5 } diff --git a/tacker/tests/etc/samples/etsi/nfv/functional6/Definitions/helloworld3_df_simple.yaml b/tacker/tests/etc/samples/etsi/nfv/functional6/Definitions/helloworld3_df_simple.yaml new file mode 100644 index 000000000..a53204c42 --- /dev/null +++ b/tacker/tests/etc/samples/etsi/nfv/functional6/Definitions/helloworld3_df_simple.yaml @@ -0,0 +1,396 @@ +tosca_definitions_version: tosca_simple_yaml_1_2 + +description: Simple deployment flavour for Sample VNF + +imports: + - etsi_nfv_sol001_common_types.yaml + - etsi_nfv_sol001_vnfd_types.yaml + - helloworld3_types.yaml + +topology_template: + inputs: + descriptor_id: + type: string + descriptor_version: + type: string + provider: + type: string + product_name: + type: string + software_version: + type: string + vnfm_info: + type: list + entry_schema: + type: string + flavour_id: + type: string + flavour_description: + type: string + + substitution_mappings: + node_type: company.provider.VNF + properties: + flavour_id: simple + requirements: + virtual_link_external1_1: [ VDU1_CP1, virtual_link ] + virtual_link_external1_2: [ VDU2_CP1, virtual_link ] + virtual_link_external2_1: [ VDU1_CP2, virtual_link ] + virtual_link_external2_2: [ VDU2_CP2, virtual_link ] + + node_templates: + VNF: + type: company.provider.VNF + properties: + flavour_description: A simple flavour + interfaces: + Vnflcm: + instantiate: [] + instantiate_start: [] + instantiate_end: [] + terminate: [] + terminate_start: [] + terminate_end: [] + modify_information: [] + modify_information_start: [] + modify_information_end: [] + + VDU1: + type: tosca.nodes.nfv.Vdu.Compute + properties: + name: VDU1 + description: VDU1 compute node + vdu_profile: + min_number_of_instances: 1 + max_number_of_instances: 3 + sw_image_data: + name: cirros-0.4.0-x86_64-disk + version: '0.4.0' + checksum: + algorithm: sha-256 + hash: a8dd75ecffd4cdd96072d60c2237b448e0c8b2bc94d57f10fdbc8c481d9005b8 + container_format: bare + disk_format: qcow2 + min_disk: 0 GB + min_ram: 256 MB + size: 12 GB + capabilities: + virtual_compute: + properties: + requested_additional_capabilities: + properties: + requested_additional_capability_name: m1.tiny + support_mandatory: true + target_performance_parameters: + entry_schema: test + virtual_memory: + virtual_mem_size: 512 MB + virtual_cpu: + num_virtual_cpu: 1 + virtual_local_storage: + - size_of_storage: 3 GB + + VDU2: + type: tosca.nodes.nfv.Vdu.Compute + properties: + name: VDU2 + description: VDU2 compute node + vdu_profile: + min_number_of_instances: 2 + max_number_of_instances: 2 + sw_image_data: + name: cirros-0.4.0-x86_64-disk + version: '0.4.0' + checksum: + algorithm: sha-256 + hash: a8dd75ecffd4cdd96072d60c2237b448e0c8b2bc94d57f10fdbc8c481d9005b8 + container_format: bare + disk_format: qcow2 + min_disk: 0 GB + min_ram: 256 MB + size: 12 GB + capabilities: + virtual_compute: + properties: + requested_additional_capabilities: + properties: + requested_additional_capability_name: m1.tiny + support_mandatory: true + target_performance_parameters: + entry_schema: test + virtual_memory: + virtual_mem_size: 512 MB + virtual_cpu: + num_virtual_cpu: 1 + virtual_local_storage: + - size_of_storage: 3 GB + + VDU1_CP1: + type: tosca.nodes.nfv.VduCp + properties: + layer_protocols: [ ipv4 ] + order: 0 + requirements: + - virtual_binding: VDU1 + + VDU1_CP2: + type: tosca.nodes.nfv.VduCp + properties: + layer_protocols: [ ipv4 ] + order: 1 + requirements: + - virtual_binding: VDU1 + + VDU1_CP3: + type: tosca.nodes.nfv.VduCp + properties: + layer_protocols: [ ipv4 ] + order: 2 + requirements: + - virtual_binding: VDU1 + - virtual_link: internalVL1 + + VDU1_CP4: + type: tosca.nodes.nfv.VduCp + properties: + layer_protocols: [ ipv4 ] + order: 3 + requirements: + - virtual_binding: VDU1 + - virtual_link: internalVL2 + + VDU1_CP5: + type: tosca.nodes.nfv.VduCp + properties: + layer_protocols: [ ipv4 ] + order: 4 + requirements: + - virtual_binding: VDU1 + - virtual_link: internalVL3 + + VDU2_CP1: + type: tosca.nodes.nfv.VduCp + properties: + layer_protocols: [ ipv4 ] + order: 0 + requirements: + - virtual_binding: VDU2 + + VDU2_CP2: + type: tosca.nodes.nfv.VduCp + properties: + layer_protocols: [ ipv4 ] + order: 1 + requirements: + - virtual_binding: VDU2 + + VDU2_CP3: + type: tosca.nodes.nfv.VduCp + properties: + layer_protocols: [ ipv4 ] + order: 2 + requirements: + - virtual_binding: VDU2 + - virtual_link: internalVL1 + + VDU2_CP4: + type: tosca.nodes.nfv.VduCp + properties: + layer_protocols: [ ipv4 ] + order: 3 + requirements: + - virtual_binding: VDU2 + - virtual_link: internalVL2 + + VDU2_CP5: + type: tosca.nodes.nfv.VduCp + properties: + layer_protocols: [ ipv4 ] + order: 4 + requirements: + - virtual_binding: VDU2 + - virtual_link: internalVL3 + + internalVL1: + type: tosca.nodes.nfv.VnfVirtualLink + properties: + connectivity_type: + layer_protocols: [ ipv4 ] + description: External Managed Virtual link in the VNF + vl_profile: + max_bitrate_requirements: + root: 1048576 + leaf: 1048576 + min_bitrate_requirements: + root: 1048576 + leaf: 1048576 + virtual_link_protocol_data: + - associated_layer_protocol: ipv4 + l3_protocol_data: + ip_version: ipv4 + cidr: 33.33.0.0/24 + + internalVL2: + type: tosca.nodes.nfv.VnfVirtualLink + properties: + connectivity_type: + layer_protocols: [ ipv4 ] + description: External Managed Virtual link in the VNF + vl_profile: + max_bitrate_requirements: + root: 1048576 + leaf: 1048576 + min_bitrate_requirements: + root: 1048576 + leaf: 1048576 + virtual_link_protocol_data: + - associated_layer_protocol: ipv4 + l3_protocol_data: + ip_version: ipv4 + cidr: 33.34.0.0/24 + + internalVL3: + type: tosca.nodes.nfv.VnfVirtualLink + properties: + connectivity_type: + layer_protocols: [ ipv4 ] + description: Internal Virtual link in the VNF + vl_profile: + max_bitrate_requirements: + root: 1048576 + leaf: 1048576 + min_bitrate_requirements: + root: 1048576 + leaf: 1048576 + virtual_link_protocol_data: + - associated_layer_protocol: ipv4 + l3_protocol_data: + ip_version: ipv4 + cidr: 33.35.0.0/24 + + policies: + - scaling_aspects: + type: tosca.policies.nfv.ScalingAspects + properties: + aspects: + worker_instance: + name: worker_instance_aspect + description: worker_instance scaling aspect + max_scale_level: 2 + step_deltas: + - delta_1 + + - VDU1_initial_delta: + type: tosca.policies.nfv.VduInitialDelta + properties: + initial_delta: + number_of_instances: 1 + targets: [ VDU1 ] + + - VDU2_initial_delta: + type: tosca.policies.nfv.VduInitialDelta + properties: + initial_delta: + number_of_instances: 2 + targets: [ VDU2 ] + + - VDU1_scaling_aspect_deltas: + type: tosca.policies.nfv.VduScalingAspectDeltas + properties: + aspect: worker_instance + deltas: + delta_1: + number_of_instances: 1 + targets: [ VDU1 ] + + - instantiation_levels: + type: tosca.policies.nfv.InstantiationLevels + properties: + levels: + instantiation_level_1: + description: Smallest size + scale_info: + worker_instance: + scale_level: 0 + instantiation_level_2: + description: Largest size + scale_info: + worker_instance: + scale_level: 2 + default_level: instantiation_level_1 + + - VDU1_instantiation_levels: + type: tosca.policies.nfv.VduInstantiationLevels + properties: + levels: + instantiation_level_1: + number_of_instances: 1 + instantiation_level_2: + number_of_instances: 3 + targets: [ VDU1 ] + + - VDU2_instantiation_levels: + type: tosca.policies.nfv.VduInstantiationLevels + properties: + levels: + instantiation_level_1: + number_of_instances: 2 + instantiation_level_2: + number_of_instances: 2 + targets: [ VDU2 ] + + - internalVL1_instantiation_levels: + type: tosca.policies.nfv.VirtualLinkInstantiationLevels + properties: + levels: + instantiation_level_1: + bitrate_requirements: + root: 1048576 + leaf: 1048576 + instantiation_level_2: + bitrate_requirements: + root: 1048576 + leaf: 1048576 + targets: [ internalVL1 ] + + - internalVL2_instantiation_levels: + type: tosca.policies.nfv.VirtualLinkInstantiationLevels + properties: + levels: + instantiation_level_1: + bitrate_requirements: + root: 1048576 + leaf: 1048576 + instantiation_level_2: + bitrate_requirements: + root: 1048576 + leaf: 1048576 + targets: [ internalVL2 ] + + - internalVL3_instantiation_levels: + type: tosca.policies.nfv.VirtualLinkInstantiationLevels + properties: + levels: + instantiation_level_1: + bitrate_requirements: + root: 1048576 + leaf: 1048576 + instantiation_level_2: + bitrate_requirements: + root: 1048576 + leaf: 1048576 + targets: [ internalVL3 ] + + - policy_antiaffinity_vdu1: + type: tosca.policies.nfv.AntiAffinityRule + targets: [ VDU1 ] + properties: + scope: zone + + - policy_antiaffinity_vdu2: + type: tosca.policies.nfv.AntiAffinityRule + targets: [ VDU2 ] + properties: + scope: zone + + diff --git a/tacker/tests/etc/samples/etsi/nfv/functional6/Definitions/helloworld3_top.vnfd.yaml b/tacker/tests/etc/samples/etsi/nfv/functional6/Definitions/helloworld3_top.vnfd.yaml new file mode 100644 index 000000000..0be18659b --- /dev/null +++ b/tacker/tests/etc/samples/etsi/nfv/functional6/Definitions/helloworld3_top.vnfd.yaml @@ -0,0 +1,31 @@ +tosca_definitions_version: tosca_simple_yaml_1_2 + +description: Sample VNF + +imports: + - etsi_nfv_sol001_common_types.yaml + - etsi_nfv_sol001_vnfd_types.yaml + - helloworld3_types.yaml + - helloworld3_df_simple.yaml + +topology_template: + inputs: + selected_flavour: + type: string + description: VNF deployment flavour selected by the consumer. It is provided in the API + + node_templates: + VNF: + type: company.provider.VNF + properties: + flavour_id: { get_input: selected_flavour } + descriptor_id: b1bb0ce7-ebca-4fa7-95ed-4840d7000000 + provider: Company + product_name: Sample VNF + software_version: '1.0' + descriptor_version: '1.0' + vnfm_info: + - Tacker + requirements: + #- virtual_link_external # mapped in lower-level templates + #- virtual_link_internal # mapped in lower-level templates \ No newline at end of file diff --git a/tacker/tests/etc/samples/etsi/nfv/functional6/Definitions/helloworld3_types.yaml b/tacker/tests/etc/samples/etsi/nfv/functional6/Definitions/helloworld3_types.yaml new file mode 100644 index 000000000..5c026d6a2 --- /dev/null +++ b/tacker/tests/etc/samples/etsi/nfv/functional6/Definitions/helloworld3_types.yaml @@ -0,0 +1,55 @@ +tosca_definitions_version: tosca_simple_yaml_1_2 + +description: VNF type definition + +imports: + - etsi_nfv_sol001_common_types.yaml + - etsi_nfv_sol001_vnfd_types.yaml + +node_types: + company.provider.VNF: + derived_from: tosca.nodes.nfv.VNF + properties: + descriptor_id: + type: string + constraints: [ valid_values: [ b1bb0ce7-ebca-4fa7-95ed-4840d7000000 ] ] + default: b1bb0ce7-ebca-4fa7-95ed-4840d7000000 + descriptor_version: + type: string + constraints: [ valid_values: [ '1.0' ] ] + default: '1.0' + provider: + type: string + constraints: [ valid_values: [ 'Company' ] ] + default: 'Company' + product_name: + type: string + constraints: [ valid_values: [ 'Sample VNF' ] ] + default: 'Sample VNF' + software_version: + type: string + constraints: [ valid_values: [ '1.0' ] ] + default: '1.0' + vnfm_info: + type: list + entry_schema: + type: string + constraints: [ valid_values: [ Tacker ] ] + default: [ Tacker ] + flavour_id: + type: string + constraints: [ valid_values: [ simple ] ] + default: simple + flavour_description: + type: string + default: "falvour" + requirements: + - virtual_link_external1: + capability: tosca.capabilities.nfv.VirtualLinkable + - virtual_link_external2: + capability: tosca.capabilities.nfv.VirtualLinkable + - virtual_link_internal: + capability: tosca.capabilities.nfv.VirtualLinkable + interfaces: + Vnflcm: + type: tosca.interfaces.nfv.Vnflcm \ No newline at end of file diff --git a/tacker/tests/etc/samples/etsi/nfv/functional6/TOSCA-Metadata/TOSCA.meta b/tacker/tests/etc/samples/etsi/nfv/functional6/TOSCA-Metadata/TOSCA.meta new file mode 100644 index 000000000..cfd7444ac --- /dev/null +++ b/tacker/tests/etc/samples/etsi/nfv/functional6/TOSCA-Metadata/TOSCA.meta @@ -0,0 +1,4 @@ +TOSCA-Meta-File-Version: 1.0 +CSAR-Version: 1.1 +Created-by: Onboarding portal +Entry-Definitions: Definitions/helloworld3_top.vnfd.yaml diff --git a/tacker/tests/functional/nfvo/__init__.py b/tacker/tests/etc/samples/etsi/nfv/functional6/UserData/__init__.py similarity index 100% rename from tacker/tests/functional/nfvo/__init__.py rename to tacker/tests/etc/samples/etsi/nfv/functional6/UserData/__init__.py diff --git a/tacker/tests/etc/samples/etsi/nfv/functional6/UserData/lcm_user_data.py b/tacker/tests/etc/samples/etsi/nfv/functional6/UserData/lcm_user_data.py new file mode 100644 index 000000000..725c5430a --- /dev/null +++ b/tacker/tests/etc/samples/etsi/nfv/functional6/UserData/lcm_user_data.py @@ -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. +from tacker.vnfm.lcm_user_data.abstract_user_data import AbstractUserData +import tacker.vnfm.lcm_user_data.utils as UserDataUtil + + +class SampleUserData(AbstractUserData): + @staticmethod + def instantiate(base_hot_dict=None, + vnfd_dict=None, + inst_req_info=None, + grant_info=None): + api_param = UserDataUtil.get_diff_base_hot_param_from_api( + base_hot_dict, inst_req_info) + initial_param_dict = \ + UserDataUtil.create_initial_param_server_port_dict( + base_hot_dict) + vdu_flavor_dict = \ + UserDataUtil.create_vdu_flavor_capability_name_dict(vnfd_dict) + vdu_image_dict = UserDataUtil.create_sw_image_dict(vnfd_dict) + cpd_vl_dict = UserDataUtil.create_network_dict( + inst_req_info, initial_param_dict) + final_param_dict = UserDataUtil.create_final_param_dict( + initial_param_dict, vdu_flavor_dict, vdu_image_dict, cpd_vl_dict) + return {**final_param_dict, **api_param} diff --git a/tacker/tests/functional/vnflcm/__init__.py b/tacker/tests/functional/legacy/__init__.py similarity index 100% rename from tacker/tests/functional/vnflcm/__init__.py rename to tacker/tests/functional/legacy/__init__.py diff --git a/tacker/tests/functional/vnfm/__init__.py b/tacker/tests/functional/legacy/nfvo/__init__.py similarity index 100% rename from tacker/tests/functional/vnfm/__init__.py rename to tacker/tests/functional/legacy/nfvo/__init__.py diff --git a/tacker/tests/functional/nfvo/test_nfvo.py b/tacker/tests/functional/legacy/nfvo/test_nfvo.py similarity index 100% rename from tacker/tests/functional/nfvo/test_nfvo.py rename to tacker/tests/functional/legacy/nfvo/test_nfvo.py diff --git a/tacker/tests/functional/nfvo/test_vim.py b/tacker/tests/functional/legacy/nfvo/test_vim.py similarity index 100% rename from tacker/tests/functional/nfvo/test_vim.py rename to tacker/tests/functional/legacy/nfvo/test_vim.py diff --git a/tacker/tests/functional/vnfpkgm/__init__.py b/tacker/tests/functional/legacy/vnfm/__init__.py similarity index 100% rename from tacker/tests/functional/vnfpkgm/__init__.py rename to tacker/tests/functional/legacy/vnfm/__init__.py diff --git a/tacker/tests/functional/vnfm/test_tosca_vnf.py b/tacker/tests/functional/legacy/vnfm/test_tosca_vnf.py similarity index 100% rename from tacker/tests/functional/vnfm/test_tosca_vnf.py rename to tacker/tests/functional/legacy/vnfm/test_tosca_vnf.py diff --git a/tacker/tests/functional/vnfm/test_tosca_vnf_alarm.py b/tacker/tests/functional/legacy/vnfm/test_tosca_vnf_alarm.py similarity index 100% rename from tacker/tests/functional/vnfm/test_tosca_vnf_alarm.py rename to tacker/tests/functional/legacy/vnfm/test_tosca_vnf_alarm.py diff --git a/tacker/tests/functional/vnfm/test_tosca_vnf_block_storage.py b/tacker/tests/functional/legacy/vnfm/test_tosca_vnf_block_storage.py similarity index 100% rename from tacker/tests/functional/vnfm/test_tosca_vnf_block_storage.py rename to tacker/tests/functional/legacy/vnfm/test_tosca_vnf_block_storage.py diff --git a/tacker/tests/functional/vnfm/test_tosca_vnf_floatingip.py b/tacker/tests/functional/legacy/vnfm/test_tosca_vnf_floatingip.py similarity index 100% rename from tacker/tests/functional/vnfm/test_tosca_vnf_floatingip.py rename to tacker/tests/functional/legacy/vnfm/test_tosca_vnf_floatingip.py diff --git a/tacker/tests/functional/vnfm/test_tosca_vnf_maintenance.py b/tacker/tests/functional/legacy/vnfm/test_tosca_vnf_maintenance.py similarity index 100% rename from tacker/tests/functional/vnfm/test_tosca_vnf_maintenance.py rename to tacker/tests/functional/legacy/vnfm/test_tosca_vnf_maintenance.py diff --git a/tacker/tests/functional/vnfm/test_tosca_vnf_multiple_vdu.py b/tacker/tests/functional/legacy/vnfm/test_tosca_vnf_multiple_vdu.py similarity index 100% rename from tacker/tests/functional/vnfm/test_tosca_vnf_multiple_vdu.py rename to tacker/tests/functional/legacy/vnfm/test_tosca_vnf_multiple_vdu.py diff --git a/tacker/tests/functional/vnfm/test_tosca_vnf_reservation.py b/tacker/tests/functional/legacy/vnfm/test_tosca_vnf_reservation.py similarity index 100% rename from tacker/tests/functional/vnfm/test_tosca_vnf_reservation.py rename to tacker/tests/functional/legacy/vnfm/test_tosca_vnf_reservation.py diff --git a/tacker/tests/functional/vnfm/test_tosca_vnf_scale.py b/tacker/tests/functional/legacy/vnfm/test_tosca_vnf_scale.py similarity index 100% rename from tacker/tests/functional/vnfm/test_tosca_vnf_scale.py rename to tacker/tests/functional/legacy/vnfm/test_tosca_vnf_scale.py diff --git a/tacker/tests/functional/vnfm/test_tosca_vnfc.py b/tacker/tests/functional/legacy/vnfm/test_tosca_vnfc.py similarity index 98% rename from tacker/tests/functional/vnfm/test_tosca_vnfc.py rename to tacker/tests/functional/legacy/vnfm/test_tosca_vnfc.py index 9c615b27a..51a04e8ea 100644 --- a/tacker/tests/functional/vnfm/test_tosca_vnfc.py +++ b/tacker/tests/functional/legacy/vnfm/test_tosca_vnfc.py @@ -36,7 +36,7 @@ class VnfTestToscaVNFC(base.BaseTackerTest): input_yaml = read_file('sample_tosca_vnfc.yaml') tosca_dict = yaml.safe_load(input_yaml) path = os.path.abspath(os.path.join( - os.path.dirname(__file__), "../../etc/samples")) + os.path.dirname(__file__), "../../../etc/samples")) vnfd_name = 'sample-tosca-vnfc' tosca_dict['topology_template']['node_templates' ]['firewall_vnfc' diff --git a/tacker/tests/functional/vnfm/test_tosca_vnfd.py b/tacker/tests/functional/legacy/vnfm/test_tosca_vnfd.py similarity index 100% rename from tacker/tests/functional/vnfm/test_tosca_vnfd.py rename to tacker/tests/functional/legacy/vnfm/test_tosca_vnfd.py diff --git a/tacker/tests/functional/vnfm/test_vnf.py b/tacker/tests/functional/legacy/vnfm/test_vnf.py similarity index 100% rename from tacker/tests/functional/vnfm/test_vnf.py rename to tacker/tests/functional/legacy/vnfm/test_vnf.py diff --git a/tacker/tests/functional/vnfm/test_vnf_monitoring.py b/tacker/tests/functional/legacy/vnfm/test_vnf_monitoring.py similarity index 100% rename from tacker/tests/functional/vnfm/test_vnf_monitoring.py rename to tacker/tests/functional/legacy/vnfm/test_vnf_monitoring.py diff --git a/tacker/tests/functional/vnfm/test_vnf_placement_policy.py b/tacker/tests/functional/legacy/vnfm/test_vnf_placement_policy.py similarity index 100% rename from tacker/tests/functional/vnfm/test_vnf_placement_policy.py rename to tacker/tests/functional/legacy/vnfm/test_vnf_placement_policy.py diff --git a/tacker/tests/functional/vnfm/test_vnfm_param.py b/tacker/tests/functional/legacy/vnfm/test_vnfm_param.py similarity index 100% rename from tacker/tests/functional/vnfm/test_vnfm_param.py rename to tacker/tests/functional/legacy/vnfm/test_vnfm_param.py diff --git a/tacker/tests/functional/sol/__init__.py b/tacker/tests/functional/sol/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/tacker/tests/functional/sol/vnflcm/__init__.py b/tacker/tests/functional/sol/vnflcm/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/tacker/tests/functional/vnflcm/base.py b/tacker/tests/functional/sol/vnflcm/base.py similarity index 99% rename from tacker/tests/functional/vnflcm/base.py rename to tacker/tests/functional/sol/vnflcm/base.py index f6a68d563..0452de037 100644 --- a/tacker/tests/functional/vnflcm/base.py +++ b/tacker/tests/functional/sol/vnflcm/base.py @@ -34,7 +34,7 @@ VNF_SUBSCRIPTION_TIMEOUT = 60 VNF_INSTANTIATE_ERROR_WAIT = 80 VNF_DELETE_COMPLETION_WAIT = 60 VNF_HEAL_TIMEOUT = 600 -VNF_LCM_DONE_TIMEOUT = 600 +VNF_LCM_DONE_TIMEOUT = 1200 RETRY_WAIT_TIME = 5 FAKE_SERVER_MANAGER = FakeServerManager.get_instance() MOCK_NOTIFY_CALLBACK_URL = '/notification/callback' diff --git a/tacker/tests/functional/vnflcm/fake_vnflcm.py b/tacker/tests/functional/sol/vnflcm/fake_vnflcm.py similarity index 100% rename from tacker/tests/functional/vnflcm/fake_vnflcm.py rename to tacker/tests/functional/sol/vnflcm/fake_vnflcm.py diff --git a/tacker/tests/functional/vnflcm/fake_vnfpkgm.py b/tacker/tests/functional/sol/vnflcm/fake_vnfpkgm.py similarity index 100% rename from tacker/tests/functional/vnflcm/fake_vnfpkgm.py rename to tacker/tests/functional/sol/vnflcm/fake_vnfpkgm.py diff --git a/tacker/tests/functional/vnflcm/test_kubernetes.py b/tacker/tests/functional/sol/vnflcm/test_kubernetes.py similarity index 99% rename from tacker/tests/functional/vnflcm/test_kubernetes.py rename to tacker/tests/functional/sol/vnflcm/test_kubernetes.py index 756f60ce7..7682519ba 100644 --- a/tacker/tests/functional/vnflcm/test_kubernetes.py +++ b/tacker/tests/functional/sol/vnflcm/test_kubernetes.py @@ -39,7 +39,7 @@ def _create_and_upload_vnf_package(tacker_client, csar_package_name, '/vnfpkgm/v1/vnf_packages', "POST", body=body) # upload vnf package - csar_package_path = "../../etc/samples/etsi/nfv/%s" % csar_package_name + csar_package_path = "../../../etc/samples/etsi/nfv/%s" % csar_package_name file_path = os.path.abspath(os.path.join(os.path.dirname(__file__), csar_package_path)) @@ -826,7 +826,7 @@ class VnfLcmTest(base.BaseTackerTest): self): instance_file_dir = os.path.join( os.path.dirname(os.path.abspath(__file__)), - '../../etc/samples/etsi/nfv/test_create_vnf_instance_' + '../../../etc/samples/etsi/nfv/test_create_vnf_instance_' 'and_instantiate_and_terminate_cnf_with_artifact_is_url/' ) artifact_file_dir = os.path.join( diff --git a/tacker/tests/functional/vnflcm/test_vnf_instance.py b/tacker/tests/functional/sol/vnflcm/test_vnf_instance.py similarity index 99% rename from tacker/tests/functional/vnflcm/test_vnf_instance.py rename to tacker/tests/functional/sol/vnflcm/test_vnf_instance.py index 44d309270..42d3ce989 100644 --- a/tacker/tests/functional/vnflcm/test_vnf_instance.py +++ b/tacker/tests/functional/sol/vnflcm/test_vnf_instance.py @@ -95,7 +95,7 @@ def _create_and_upload_vnf_package(tacker_client, csar_package_name, '/vnfpkgm/v1/vnf_packages', "POST", body=body) # upload vnf package - csar_package_path = "../../etc/samples/etsi/nfv/%s" % csar_package_name + csar_package_path = "../../../etc/samples/etsi/nfv/%s" % csar_package_name file_path = os.path.abspath(os.path.join(os.path.dirname(__file__), csar_package_path)) diff --git a/tacker/tests/functional/vnflcm/test_vnf_instance_with_user_data.py b/tacker/tests/functional/sol/vnflcm/test_vnf_instance_with_user_data.py similarity index 98% rename from tacker/tests/functional/vnflcm/test_vnf_instance_with_user_data.py rename to tacker/tests/functional/sol/vnflcm/test_vnf_instance_with_user_data.py index 23a987d4a..4d127d29a 100644 --- a/tacker/tests/functional/vnflcm/test_vnf_instance_with_user_data.py +++ b/tacker/tests/functional/sol/vnflcm/test_vnf_instance_with_user_data.py @@ -14,8 +14,8 @@ import os from oslo_utils import uuidutils from tacker.objects import fields -from tacker.tests.functional.vnflcm import base as vnflcm_base -from tacker.tests.functional.vnflcm import fake_vnflcm +from tacker.tests.functional.sol.vnflcm import base as vnflcm_base +from tacker.tests.functional.sol.vnflcm import fake_vnflcm import tempfile import time @@ -128,7 +128,7 @@ class VnfLcmWithUserDataTest(vnflcm_base.BaseVnfLcmTest): csar_package_path = os.path.abspath( os.path.join( os.path.dirname(__file__), - "../../etc/samples/etsi/nfv", + "../../../etc/samples/etsi/nfv", sample_name)) tempname, _ = vnflcm_base._create_csar_with_unique_vnfd_id( csar_package_path) @@ -260,7 +260,7 @@ class VnfLcmWithUserDataTest(vnflcm_base.BaseVnfLcmTest): csar_package_path = os.path.abspath( os.path.join( os.path.dirname(__file__), - "../../etc/samples/etsi/nfv", + "../../../etc/samples/etsi/nfv", sample_name)) tempname, _ = vnflcm_base._create_csar_with_unique_vnfd_id( csar_package_path) @@ -307,7 +307,7 @@ class VnfLcmWithUserDataTest(vnflcm_base.BaseVnfLcmTest): csar_package_path = os.path.abspath( os.path.join( os.path.dirname(__file__), - "../../etc/samples/etsi/nfv", + "../../../etc/samples/etsi/nfv", sample_name)) tempname, _ = vnflcm_base._create_csar_with_unique_vnfd_id( csar_package_path) @@ -403,7 +403,7 @@ class VnfLcmWithUserDataTest(vnflcm_base.BaseVnfLcmTest): csar_package_path = os.path.abspath( os.path.join( os.path.dirname(__file__), - "../../etc/samples/etsi/nfv", + "../../../etc/samples/etsi/nfv", sample_name)) tempname, _ = vnflcm_base._create_csar_with_unique_vnfd_id( csar_package_path) @@ -452,7 +452,7 @@ class VnfLcmWithUserDataTest(vnflcm_base.BaseVnfLcmTest): csar_package_path = os.path.abspath( os.path.join( os.path.dirname(__file__), - "../../etc/samples/etsi/nfv", + "../../../etc/samples/etsi/nfv", sample_name)) tempname, _ = vnflcm_base._create_csar_with_unique_vnfd_id( csar_package_path) @@ -512,7 +512,7 @@ class VnfLcmWithUserDataTest(vnflcm_base.BaseVnfLcmTest): csar_package_path = os.path.abspath( os.path.join( os.path.dirname(__file__), - "../../etc/samples/etsi/nfv", + "../../../etc/samples/etsi/nfv", sample_name)) tempname, _ = vnflcm_base._create_csar_user_data_common( csar_package_path) @@ -563,7 +563,7 @@ class VnfLcmWithUserDataTest(vnflcm_base.BaseVnfLcmTest): csar_package_path = os.path.abspath( os.path.join( os.path.dirname(__file__), - "../../etc/samples/etsi/nfv", + "../../../etc/samples/etsi/nfv", sample_name)) tempname, _ = vnflcm_base._create_csar_user_data_common( csar_package_path) @@ -616,7 +616,7 @@ class VnfLcmWithUserDataTest(vnflcm_base.BaseVnfLcmTest): csar_package_path = os.path.abspath( os.path.join( os.path.dirname(__file__), - "../../etc/samples/etsi/nfv", + "../../../etc/samples/etsi/nfv", sample_name)) tempname, _ = vnflcm_base._create_csar_user_data_common( csar_package_path) @@ -670,7 +670,7 @@ class VnfLcmWithUserDataTest(vnflcm_base.BaseVnfLcmTest): csar_package_path = os.path.abspath( os.path.join( os.path.dirname(__file__), - "../../etc/samples/etsi/nfv", + "../../../etc/samples/etsi/nfv", sample_name)) tempname, _ = vnflcm_base._create_csar_user_data_common( csar_package_path) @@ -725,7 +725,7 @@ class VnfLcmWithUserDataTest(vnflcm_base.BaseVnfLcmTest): csar_package_path = os.path.abspath( os.path.join( os.path.dirname(__file__), - "../../etc/samples/etsi/nfv", + "../../../etc/samples/etsi/nfv", sample_name)) tempname, _ = vnflcm_base._create_csar_user_data_common( csar_package_path) @@ -796,7 +796,7 @@ class VnfLcmWithUserDataTest(vnflcm_base.BaseVnfLcmTest): csar_package_path = os.path.abspath( os.path.join( os.path.dirname(__file__), - "../../etc/samples/etsi/nfv", + "../../../etc/samples/etsi/nfv", sample_name)) tempname, _ = vnflcm_base._create_csar_with_unique_vnfd_id( csar_package_path) @@ -891,7 +891,7 @@ class VnfLcmWithUserDataTest(vnflcm_base.BaseVnfLcmTest): csar_package_path = os.path.abspath( os.path.join( os.path.dirname(__file__), - "../../etc/samples/etsi/nfv", + "../../../etc/samples/etsi/nfv", sample_name)) tempname, _ = vnflcm_base._create_csar_with_unique_vnfd_id( csar_package_path) diff --git a/tacker/tests/functional/sol/vnfpkgm/__init__.py b/tacker/tests/functional/sol/vnfpkgm/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/tacker/tests/functional/vnfpkgm/test_vnf_package.py b/tacker/tests/functional/sol/vnfpkgm/test_vnf_package.py similarity index 99% rename from tacker/tests/functional/vnfpkgm/test_vnf_package.py rename to tacker/tests/functional/sol/vnfpkgm/test_vnf_package.py index 84e59d8b2..6963c8527 100644 --- a/tacker/tests/functional/vnfpkgm/test_vnf_package.py +++ b/tacker/tests/functional/sol/vnfpkgm/test_vnf_package.py @@ -159,7 +159,7 @@ class VnfPackageTest(base.BaseTackerTest): def _get_csar_dir_path(self, csar_name): csar_dir = os.path.abspath(os.path.join(os.path.dirname(__file__), - "../../etc/samples/etsi/nfv", csar_name)) + "../../../etc/samples/etsi/nfv", csar_name)) return csar_dir def _create_and_upload_vnf(self, sample_name): diff --git a/tacker/tests/functional/sol_separated_nfvo/__init__.py b/tacker/tests/functional/sol_separated_nfvo/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/tacker/tests/functional/sol_separated_nfvo/vnflcm/__init__.py b/tacker/tests/functional/sol_separated_nfvo/vnflcm/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/tacker/tests/functional/sol_separated_nfvo/vnflcm/fake_grant.py b/tacker/tests/functional/sol_separated_nfvo/vnflcm/fake_grant.py new file mode 100644 index 000000000..b390446b0 --- /dev/null +++ b/tacker/tests/functional/sol_separated_nfvo/vnflcm/fake_grant.py @@ -0,0 +1,205 @@ +# +# 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 oslo_serialization import jsonutils +from tacker.tests import uuidsentinel + + +class Grant: + GRANT_REQ_PATH = '/grant/v1/grants' + + ZONES = [ + { + "id": uuidsentinel.zone_id, + "zoneId": "nova", + "vimConnectionId": uuidsentinel.vim_connection_id + } + ] + + ADDITIONAL_PARAMS = { + "key": "value" + } + + @staticmethod + def _make_vim_connection_info(tenant_id): + access_info = { + "username": "nfv_user", + "region": "RegionOne", + "password": "devstack", + "tenant": tenant_id + } + + return [{ + "id": uuidsentinel.vim_connection_id, + "vimType": "ETSINFV.OPENSTACK_KEYSTONE.v_2", + "interfaceInfo": { + "endpoint": "http://127.0.0.1/identity" + }, + "accessInfo": access_info + }] + + @staticmethod + def _make_add_resources(req_add_resources): + add_resources = [] + for req_add_resource in req_add_resources: + res_add_resource = { + "resourceDefinitionId": req_add_resource['id'], + "vimConnectionId": uuidsentinel.vim_connection_id + } + + if req_add_resource['type'] == 'COMPUTE': + res_add_resource["zoneId"] = uuidsentinel.zone_id + + add_resources.append(res_add_resource) + + return add_resources + + @staticmethod + def _make_remove_resources(req_remove_resources): + res_remove_resources = [] + for req_remove_resource in req_remove_resources: + res_remove_resource = { + "resourceDefinitionId": req_remove_resource['id'] + } + + res_remove_resources.append(res_remove_resource) + + return res_remove_resources + + @staticmethod + def _make_vim_assets(image_id, flavour_id="1"): + # set m1.tiny="1" for flavour_id + vim_assets = { + "computeResourceFlavours": [ + { + "vimConnectionId": uuidsentinel.vim_connection_id, + "vnfdVirtualComputeDescId": "VDU1", + "vimFlavourId": flavour_id + }, + { + "vimConnectionId": uuidsentinel.vim_connection_id, + "vnfdVirtualComputeDescId": "VDU2", + "vimFlavourId": flavour_id + } + ], + "softwareImages": [ + { + "vimConnectionId": uuidsentinel.vim_connection_id, + "vnfdSoftwareImageId": "VDU1", + "vimSoftwareImageId": image_id + }, + { + "vimConnectionId": uuidsentinel.vim_connection_id, + "vnfdSoftwareImageId": "VDU2", + "vimSoftwareImageId": image_id + } + ] + } + + return vim_assets + + @staticmethod + def _make_response_template(request_body): + res = { + "id": uuidsentinel.__getattr__(request_body['vnfLcmOpOccId']), + "vnfInstanceId": request_body['vnfInstanceId'], + "vnfLcmOpOccId": request_body['vnfLcmOpOccId'], + } + res["_links"] = { + "self": { + # set fake server port. + "href": os.path.join( + 'http://localhost:9990', + Grant.GRANT_REQ_PATH)}, + "vnfLcmOpOcc": { + "href": os.path.join( + 'http://localhost:9890/vnflcm/v1/vnf_lcm_op_occs', + request_body['vnfLcmOpOccId'])}, + "vnfInstance": { + "href": os.path.join( + 'http://localhost:9890/vnflcm/v1/vnf_instances', + request_body['vnfInstanceId'])}} + + return res + + @staticmethod + def _convert_body_to_dict(body): + if isinstance(body, str): + return jsonutils.loads(body) + + return body + + @staticmethod + def make_inst_response_body(request_body, tenant_id, image_id): + request_body = Grant._convert_body_to_dict(request_body) + res = Grant._make_response_template(request_body) + res["vimConnections"] = Grant._make_vim_connection_info(tenant_id) + res["zones"] = Grant.ZONES + if 'addResources' in request_body.keys(): + res["addResources"] = Grant._make_add_resources( + request_body['addResources']) + res["vimAssets"] = Grant._make_vim_assets( + image_id) + res["additionalParams"] = Grant.ADDITIONAL_PARAMS + + return res + + @staticmethod + def make_heal_response_body(request_body, tenant_id, image_id): + request_body = Grant._convert_body_to_dict(request_body) + res = Grant._make_response_template(request_body) + res["vimConnections"] = Grant._make_vim_connection_info(tenant_id) + res["zones"] = Grant.ZONES + if 'addResources' in request_body.keys(): + res["addResources"] = Grant._make_add_resources( + request_body['addResources']) + if 'removeResources' in request_body.keys(): + res["removeResources"] = Grant._make_remove_resources( + request_body['removeResources']) + res["vimAssets"] = Grant._make_vim_assets(image_id) + + return res + + @staticmethod + def make_scaleout_response_body(request_body, tenant_id, image_id): + request_body = Grant._convert_body_to_dict(request_body) + res = Grant._make_response_template(request_body) + res["vimConnections"] = Grant._make_vim_connection_info(tenant_id) + res["zones"] = Grant.ZONES + if 'addResources' in request_body.keys(): + res["addResources"] = Grant._make_add_resources( + request_body['addResources']) + res["vimAssets"] = Grant._make_vim_assets( + image_id) + + return res + + @staticmethod + def make_scalein_response_body(request_body): + request_body = Grant._convert_body_to_dict(request_body) + res = Grant._make_response_template(request_body) + if 'removeResources' in request_body.keys(): + res["removeResources"] = Grant._make_remove_resources( + request_body['removeResources']) + + return res + + @staticmethod + def make_term_response_body(request_body): + request_body = Grant._convert_body_to_dict(request_body) + res = Grant._make_response_template(request_body) + if 'removeResources' in request_body.keys(): + res["removeResources"] = Grant._make_remove_resources( + request_body['removeResources']) + + return res diff --git a/tacker/tests/functional/sol_separated_nfvo/vnflcm/fake_vnfpkgm.py b/tacker/tests/functional/sol_separated_nfvo/vnflcm/fake_vnfpkgm.py new file mode 100644 index 000000000..6f94a8516 --- /dev/null +++ b/tacker/tests/functional/sol_separated_nfvo/vnflcm/fake_vnfpkgm.py @@ -0,0 +1,105 @@ +# +# 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 oslo_utils import uuidutils + + +class VnfPackage: + VNF_PACKAGE_REQ_PATH = "/vnfpkgm/v1/vnf_packages" + + @staticmethod + def make_list_response_body(): + return [VnfPackage.make_individual_response] + + @staticmethod + def make_individual_response_body(vnfd_id, vnf_package_hash): + add_artifact_hash = ( + "6513f21e44aa3da349f248188a44" + + "bc304a3653a04122d8fb4535423c8" + + "e1d14cd6a153f735bb0982e2" + + "161b5b5186106570c17a9" + + "e58b64dd39390617cd5a350f78") + + sw_image_hash = ( + "6513f21e44aa3da349" + + "f248188a44bc304a3653a04" + + "122d8fb4535423c8e1d14c" + + "d6a153f735bb0982e2161b5" + + "b5186106570c17a9e58b6" + + "4dd39390617cd5a350f78") + + data = { + "id": uuidutils.generate_uuid(), + "vnfdId": vnfd_id, + "vnfProvider": "Company", + "vnfProductName": "Sample VNF", + "vnfSoftwareVersion": "1.0", + "vnfdVersion": "1.0", + "checksum": { + "algorithm": "SHA-512", + "hash": vnf_package_hash + }, + "softwareImages": [ + { + "id": "sw_image", + "name": "cirros-0.4.0-x86_64-disk", + "provider": "Company", + "version": "0.4.0", + "checksum": { + "algorithm": "SHA-512", + "hash": sw_image_hash + }, + "containerFormat": "BARE", + "diskFormat": "QCOW2", + "createdAt": "2020-09-01T12:34:56Z", + "minDisk": "2147483648", + "minRam": "268435456", + "size": "1073741824", + "userMetadata": { + "key": "value" + }, + "imagePath": "Files/images/cirros-0.4.0-x86_64-disk.img" + } + ], + "additionalArtifacts": [ + { + "artifactPath": + "Files/images/cirros-0.4.0-x86_64-disk.img", + "checksum": { + "algorithm": "SHA-512", + "hash": add_artifact_hash + }, + "metadata": { + "key": "value" + } + } + ], + "onboardingState": "ONBOARDED", + "operationalState": "ENABLED", + "usageState": "NOT_IN_USE", + "userDefinedData": { + "key": "value" + }, + "_links": { + "self": { + "href": "GetPackage URI" + }, + "vnfd": { + "href": "GetVNFD URI" + }, + "packageContent": { + "href": "GetPackageContent URI" + } + } + } + + return data diff --git a/tacker/tests/functional/sol_separated_nfvo/vnflcm/test_vnf_instance_with_user_data_nfvo_separate.py b/tacker/tests/functional/sol_separated_nfvo/vnflcm/test_vnf_instance_with_user_data_nfvo_separate.py new file mode 100644 index 000000000..0bcafa2c4 --- /dev/null +++ b/tacker/tests/functional/sol_separated_nfvo/vnflcm/test_vnf_instance_with_user_data_nfvo_separate.py @@ -0,0 +1,316 @@ +# +# 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 hashlib +import os + +from tacker.tests.functional.sol.vnflcm import base as vnflcm_base +from tacker.tests.functional.sol.vnflcm import fake_vnflcm +from tacker.tests.functional.sol_separated_nfvo.vnflcm import fake_grant +from tacker.tests.functional.sol_separated_nfvo.vnflcm import fake_vnfpkgm + + +class VnfLcmWithNfvoSeparator(vnflcm_base.BaseVnfLcmTest): + + def _register_vnf_package_mock_response(self): + """Prepare VNF package for test. + + Register VNF package response to fake NFVO server and Cleanups. + + Returns: + Response: VNF Package information + """ + # Pre Setting: Create vnf package. + sample_name = "functional6" + csar_package_path = os.path.abspath( + os.path.join( + os.path.dirname(__file__), + "../../../etc/samples/etsi/nfv", + sample_name)) + + # Get VNFD id. + tempname, vnfd_id = vnflcm_base._create_csar_with_unique_vnfd_id( + csar_package_path) + with open(tempname, "rb") as f: + vnf_package_hash = hashlib.sha256(f.read()).hexdigest() + + vnf_package_info = \ + fake_vnfpkgm.VnfPackage.make_individual_response_body( + vnfd_id, vnf_package_hash) + vnf_package_id = vnf_package_info['id'] + + # Post Setting: Reserve deleting vnf package. + self.addCleanup(vnflcm_base._delete_vnf_package, self.tacker_client, + vnf_package_id) + + # Set "VNF Packages" response + vnflcm_base.FAKE_SERVER_MANAGER.set_callback('GET', + fake_vnfpkgm.VnfPackage.VNF_PACKAGE_REQ_PATH, status_code=200, + response_body=[vnf_package_info]) + + # Set "VNF Package content" response + vnflcm_base.FAKE_SERVER_MANAGER.set_callback('GET', + os.path.join( + fake_vnfpkgm.VnfPackage.VNF_PACKAGE_REQ_PATH, + vnf_package_id, + 'package_content'), + status_code=200, + response_headers={"Content-Type": "application/zip"}, + content=tempname) + + # Set "Individual VNF package artifact" response + vnflcm_base.FAKE_SERVER_MANAGER.set_callback('GET', + os.path.join( + fake_vnfpkgm.VnfPackage.VNF_PACKAGE_REQ_PATH, + vnf_package_id, + 'artifacts', + vnf_package_info['additionalArtifacts'][0]['artifactPath']), + status_code=200, + response_headers={"Content-Type": "application/zip"}, + content=tempname) + + # Set "VNFD of individual VNF package" response + vnflcm_base.FAKE_SERVER_MANAGER.set_callback('GET', + os.path.join( + fake_vnfpkgm.VnfPackage.VNF_PACKAGE_REQ_PATH, + vnf_package_id, + 'vnfd'), + status_code=200, + response_headers={"Content-Type": "application/zip"}, + content=tempname) + + return vnf_package_info + + def test_inst_heal_term(self): + """Test basic life cycle operations with sample VNFD with UserData. + + In this test case, we do following steps. + - Create subscription. + - Create VNF instance. + - Instantiate VNF. + - Heal VNF with all VNFc. + - Terminate VNF + - Delete VNF + - Delete subscription + """ + vnf_package_info = self._register_vnf_package_mock_response() + glance_image = self._list_glance_image()[0] + + # Create subscription and register it. + request_body = fake_vnflcm.Subscription.make_create_request_body( + 'http://localhost:{}{}'.format( + vnflcm_base.FAKE_SERVER_MANAGER.SERVER_PORT, + os.path.join( + vnflcm_base.MOCK_NOTIFY_CALLBACK_URL, + self._testMethodName))) + resp, response_body = self._register_subscription(request_body) + self.assertEqual(201, resp.status_code) + self.assert_http_header_location_for_subscription(resp.headers) + subscription_id = response_body.get('id') + self.addCleanup(self._delete_subscription, subscription_id) + + # Create vnf instance + resp, vnf_instance = self._create_vnf_instance_from_body( + fake_vnflcm.VnfInstances.make_create_request_body( + vnf_package_info['vnfdId'])) + vnf_instance_id = vnf_instance.get('id') + self._wait_lcm_done(vnf_instance_id=vnf_instance_id) + self._assert_create_vnf(resp, vnf_instance) + self.addCleanup(self._delete_vnf_instance, vnf_instance_id) + + # Set Fake server response for Grant-Req(Instantiate) + vnflcm_base.FAKE_SERVER_MANAGER.set_callback('POST', + fake_grant.Grant.GRANT_REQ_PATH, status_code=201, + callback=lambda req_headers, + req_body: fake_grant.Grant.make_inst_response_body(req_body, + self.vim['tenant_id'], glance_image.id)) + + # Instantiate vnf instance + request_body = fake_vnflcm.VnfInstances.make_inst_request_body( + self.vim['tenant_id'], self.ext_networks, self.ext_mngd_networks, + self.ext_link_ports, self.ext_subnets) + resp, _ = self._instantiate_vnf_instance(vnf_instance_id, request_body) + self._wait_lcm_done('COMPLETED', vnf_instance_id=vnf_instance_id) + self._assert_instantiate_vnf(resp, vnf_instance_id) + + # Show vnf instance + resp, vnf_instance = self._show_vnf_instance(vnf_instance_id) + self.assertEqual(200, resp.status_code) + + # Set Fake server response for Grant-Req(Heal) + vnflcm_base.FAKE_SERVER_MANAGER.set_callback('POST', + fake_grant.Grant.GRANT_REQ_PATH, status_code=201, + callback=lambda req_headers, + req_body: fake_grant.Grant.make_heal_response_body(req_body, + self.vim['tenant_id'], glance_image.id)) + + # Heal vnf (exists vnfc_instace_id) + vnfc_instance_id_list = [ + vnfc.get('id') for vnfc in vnf_instance.get( + 'instantiatedVnfInfo', {}).get( + 'vnfcResourceInfo', [])] + request_body = fake_vnflcm.VnfInstances.make_heal_request_body( + vnfc_instance_id_list) + resp, _ = self._heal_vnf_instance(vnf_instance_id, request_body) + self._wait_lcm_done('COMPLETED', vnf_instance_id=vnf_instance_id) + self._assert_heal_vnf(resp, vnf_instance_id) + + # Set Fake server response for Grant-Req(Terminate) + vnflcm_base.FAKE_SERVER_MANAGER.set_callback('POST', + fake_grant.Grant.GRANT_REQ_PATH, status_code=201, + callback=lambda req_headers, + req_body: fake_grant.Grant.make_term_response_body(req_body)) + + # Get stack informations to terminate. + stack = self._get_heat_stack(vnf_instance_id) + resources_list = self._get_heat_resource_list(stack.id) + resource_name_list = [r.resource_name for r in resources_list] + glance_image_id_list = self._get_glance_image_list_from_stack_resource( + stack.id, resource_name_list) + + # Terminate VNF + terminate_req_body = fake_vnflcm.VnfInstances.make_term_request_body() + resp, _ = self._terminate_vnf_instance(vnf_instance_id, + terminate_req_body) + self._wait_lcm_done('COMPLETED', vnf_instance_id=vnf_instance_id) + self._assert_terminate_vnf(resp, vnf_instance_id, stack.id, + resource_name_list, glance_image_id_list) + + # Delete VNF + resp, _ = self._delete_vnf_instance(vnf_instance_id) + self._wait_lcm_done(vnf_instance_id=vnf_instance_id) + self.assert_delete_vnf(resp, vnf_instance_id) + + # Delete Subscription + resp, response_body = self._delete_subscription(subscription_id) + self.assertEqual(204, resp.status_code) + + def _assert_create_vnf(self, resp, vnf_instance): + """Assert that VNF was created via fake server. + + Args: + resp (Response): HTTP response object. + vnf_instance (Dict): VNF instance information. + """ + super().assert_create_vnf(resp, vnf_instance) + + # FT-checkpoint: VnfPkgId + vnf_pkg_mock_responses = vnflcm_base.FAKE_SERVER_MANAGER.get_history( + fake_vnfpkgm.VnfPackage.VNF_PACKAGE_REQ_PATH) + vnflcm_base.FAKE_SERVER_MANAGER.clear_history( + fake_vnfpkgm.VnfPackage.VNF_PACKAGE_REQ_PATH) + + self.assertEqual(1, len(vnf_pkg_mock_responses)) + vnf_pkg_info_list = vnf_pkg_mock_responses[0] + self.assertEqual(vnf_instance['vnfPkgId'], + vnf_pkg_info_list.response_body[0]['id']) + + def _assert_instantiate_vnf(self, resp, vnf_instance_id): + """Assert that VNF was instantiated. + + This method calls same name method of super class and that + checks heat resource status 'CREATE_COMPLETE', then assert + notifications of instantiation. + Then, we check Grant response in this method. + + Args: + resp (Response): HTTP response object. + vnf_instance_id (str): VNF instance id. + """ + super().assert_instantiate_vnf(resp, vnf_instance_id) + + # FT-checkpoint: Grant Response + grant_mock_responses = vnflcm_base.FAKE_SERVER_MANAGER.get_history( + fake_grant.Grant.GRANT_REQ_PATH) + vnflcm_base.FAKE_SERVER_MANAGER.clear_history( + fake_grant.Grant.GRANT_REQ_PATH) + self.assertEqual(1, len(grant_mock_responses)) + self._assert_grant_mock_response(grant_mock_responses[0]) + + def _assert_heal_vnf(self, resp, vnf_instance_id, + expected_stack_status='UPDATE_COMPLETE'): + """Assert that VNF was healed. + + This method calls same name method of super class and that + checks heat resource status 'UPDATE_COMPLETE', then assert + notifications of healing. + Then, we check Grant response in this method. + + Args: + resp (Response): HTTP response object. + vnf_instance_id (str): VNF instance id. + expected_stack_status (str, optional): self explanatory :) + Defaults to 'UPDATE_COMPLETE'. + """ + super().assert_heal_vnf( + resp, vnf_instance_id, expected_stack_status=expected_stack_status) + + # FT-checkpoint: Grant Response + grant_mock_responses = vnflcm_base.FAKE_SERVER_MANAGER.get_history( + fake_grant.Grant.GRANT_REQ_PATH) + vnflcm_base.FAKE_SERVER_MANAGER.clear_history( + fake_grant.Grant.GRANT_REQ_PATH) + self.assertEqual(1, len(grant_mock_responses)) + self._assert_grant_mock_response(grant_mock_responses[0]) + + def _assert_terminate_vnf(self, resp, vnf_instance_id, stack_id, + resource_name_list, glance_image_id_list): + """Assert that VNF was terminated. + + This method calls same name method of super class to check specified + VNF instance is 'NOT_INSTANTIATED' + Then, we check Grant response in this method. + + Args: + resp (Response): HTTP response object. + vnf_instance_id (str): VNF instance id. + stack_id (str): Resource id of heat stack to check. + resource_name_list (list[str]): List of heat stack resources. + glance_image_id_list (list[str]): List of glance image ids. + """ + super().assert_terminate_vnf(resp, vnf_instance_id, stack_id, + resource_name_list, glance_image_id_list) + + # FT-checkpoint: Grant Response + grant_mock_responses = vnflcm_base.FAKE_SERVER_MANAGER.get_history( + fake_grant.Grant.GRANT_REQ_PATH) + vnflcm_base.FAKE_SERVER_MANAGER.clear_history( + fake_grant.Grant.GRANT_REQ_PATH) + self.assertEqual(1, len(grant_mock_responses)) + self._assert_grant_mock_response(grant_mock_responses[0]) + + def _assert_grant_mock_response(self, grant_mock_response, + expected_auth_type=None, expected_token_value=None): + """Assert that HTTP response code is equal to 201 or not. + + This method checks response code of grant request and + authorization result. + + Args: + grant_mock_response (Response): HTTP response object. + expected_auth_type (str, optional): Authentication type. + Defaults to None. + expected_token_value ([type], optional): Authentication token. + Defaults to None. + """ + self.assertEqual(201, grant_mock_response.status_code) + + actual_auth = grant_mock_response.request_headers.get("Authorization") + if expected_auth_type is None: + self.assertIsNone(actual_auth) + return + + self.assertEqual( + '{} {}'.format(expected_auth_type, expected_token_value), + actual_auth) diff --git a/tox.ini b/tox.ini index b5cf3c041..45f854e04 100644 --- a/tox.ini +++ b/tox.ini @@ -33,6 +33,24 @@ setenv = {[testenv]setenv} commands = stestr --test-path=./tacker/tests/functional run --slowest --concurrency 2 {posargs} +[testenv:dsvm-functional-legacy] +setenv = {[testenv]setenv} + +commands = + stestr --test-path=./tacker/tests/functional/legacy run --slowest --concurrency 1 {posargs} + +[testenv:dsvm-functional-sol] +setenv = {[testenv]setenv} + +commands = + stestr --test-path=./tacker/tests/functional/sol run --slowest --concurrency 1 {posargs} + +[testenv:dsvm-functional-sol-separated-nfvo] +setenv = {[testenv]setenv} + +commands = + stestr --test-path=./tacker/tests/functional/sol_separated_nfvo run --slowest --concurrency 1 {posargs} + [testenv:debug] commands = oslo_debug_helper {posargs}