Add new FT set for tests with separated NFVO
This patch adds new test with separated NFVO such as Grant API. The test requires additinal config of Tacker, and we cannot use Tacker with such config for other tests. So we add new FT set for separated NFVO environment. Change-Id: I9fb5ef027b9010becc088ca0b66138bcf52512c2
This commit is contained in:
parent
9e0eccac8b
commit
0d412ba7cb
19
.zuul.yaml
19
.zuul.yaml
@ -214,6 +214,24 @@
|
||||
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
|
||||
tox_envlist: dsvm-functional-sol-separated-nfvo
|
||||
|
||||
- project:
|
||||
templates:
|
||||
- check-requirements
|
||||
@ -226,3 +244,4 @@
|
||||
jobs:
|
||||
- tacker-functional-devstack-multinode-legacy
|
||||
- tacker-functional-devstack-multinode-sol
|
||||
- tacker-functional-devstack-multinode-sol-separated-nfvo
|
||||
|
@ -63,6 +63,14 @@ if [ "${TACKER_MODE}" == "all" ]; then
|
||||
done
|
||||
fi
|
||||
elif [ "${TACKER_MODE}" == "standalone" ]; then
|
||||
# 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
|
||||
|
@ -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}
|
205
tacker/tests/functional/sol_separated_nfvo/vnflcm/fake_grant.py
Normal file
205
tacker/tests/functional/sol_separated_nfvo/vnflcm/fake_grant.py
Normal file
@ -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)
|
6
tox.ini
6
tox.ini
@ -52,6 +52,12 @@ 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
Block a user