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
This commit is contained in:
parent
deb6c2d4b8
commit
308ed21a13
75
.zuul.yaml
75
.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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
- hosts: all
|
||||
roles:
|
||||
- orchestrate-devstack
|
||||
- modify-heat-policy
|
||||
- setup-default-vim
|
||||
- role: bindep
|
||||
bindep_profile: test
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
- hosts: controller
|
||||
- hosts: controller-tacker
|
||||
roles:
|
||||
- tox
|
||||
|
|
|
@ -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)
|
|
@ -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'
|
||||
|
|
|
@ -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: {}
|
||||
|
||||
|
|
@ -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 }
|
||||
|
||||
|
|
@ -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 }
|
|
@ -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
|
||||
|
||||
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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}
|
|
@ -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'
|
|
@ -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'
|
|
@ -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(
|
|
@ -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))
|
||||
|
|
@ -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)
|
|
@ -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):
|
|
@ -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
|
|
@ -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
|
|
@ -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)
|
18
tox.ini
18
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}
|
||||
|
||||
|
|
Loading…
Reference in New Issue