Modify processing of _heal_grant and _scale_grant

In NFV-SOL003 V2.6.1, the add_resources'id in grant should be
same as the vnfc_resource_info'id. However, at present, if
you execute heal_grant and scale_grant request, the add_resources's
resource_definition_id in grantResponse cannot match the
vnfc_resource_info.id.

In _scale_grant, to fix this bug, we changed the processing
of _scale_grant in openstack._get_grant_resource_scale_out method.
Firstly initialize the data of vnfc_resource_info according
to the input parameters and the vnfd file, then initialize
the add_resources data of grant according to the
vnfc_resource_info data. After scaling out, store the data
in the stack into vnfc_resource_info in the
openstack.scale_resource_update method.

In addition, in openstack._get_grant_resource_scale_out, there is
also a problem with the placement_constraint rule setting, which
is also corrected in this patch.

In _heal_grant, if heal entire vnf_instance, we initialize
remove_resources used old vnf_instance's info, and then
reinitialize vnf_instance's info and use them to initialize
add_resources. If heal partial vnf_instance, we just use
update_resources in grant.

For instantiate, if you need to use the data obtained by
instantiate_grant in instantiate_end, the process should
execute the post_instantiate_vnf method before instantiate_end,
so the vnflcm_driver._instantiate_vnf method has also been
modified.

Closes-Bug: #1930782
Change-Id: I1008472f5a7104324b61a413052dc44bc84c7ade
This commit is contained in:
Yi Feng 2021-06-07 12:31:17 +09:00
parent a3e31aa14e
commit 9e13a55aba
27 changed files with 1919 additions and 150 deletions

View File

@ -1226,6 +1226,159 @@ class Conductor(manager.Manager):
vnf_dict['grant'] = self._grant(context, grant_request)
def _init_remove_resources(self, vnf_inf, rm_resources):
for vnfc_resource in vnf_inf.vnfc_resource_info:
resource = objects.ResourceDefinition()
resource.id = vnfc_resource.id
resource.type = constants.TYPE_COMPUTE
resource.vdu_id = vnfc_resource.vdu_id
resource.resource_template_id = vnfc_resource.vdu_id
vim_id = vnfc_resource.compute_resource.vim_connection_id
rsc_id = vnfc_resource.compute_resource.resource_id
vnfc_rh = objects.ResourceHandle(
vim_connection_id=vim_id,
resource_id=rsc_id)
resource.resource = vnfc_rh
rm_resources.append(resource)
for vl_resource in vnf_inf.vnf_virtual_link_resource_info:
resource = objects.ResourceDefinition()
resource.id = vl_resource.id
resource.type = constants.TYPE_VL
resource.resource_template_id = \
vl_resource.vnf_virtual_link_desc_id
vim_id = vl_resource.network_resource.vim_connection_id
rsc_id = vl_resource.network_resource.resource_id
vl_rh = objects.ResourceHandle(
vim_connection_id=vim_id,
resource_id=rsc_id)
resource.resource = vl_rh
rm_resources.append(resource)
for cp_resource in vl_resource.vnf_link_ports:
for vnfc_resource in vnf_inf.vnfc_resource_info:
for vnfc_cp_resource in vnfc_resource.vnfc_cp_info:
if cp_resource.cp_instance_id == \
vnfc_cp_resource.id:
resource = objects.ResourceDefinition()
resource.id = cp_resource.id
resource.type = constants.TYPE_LINKPORT
resource.vdu_id = vnfc_resource.vdu_id
resource.resource_template_id = \
vnfc_cp_resource.cpd_id
vim_id = \
cp_resource.resource_handle. \
vim_connection_id
rsc_id = cp_resource.resource_handle. \
resource_id
cp_rh = objects.ResourceHandle(
vim_connection_id=vim_id,
resource_id=rsc_id)
resource.resource = cp_rh
rm_resources.append(resource)
for storage_resource in vnf_inf.virtual_storage_resource_info:
for vnfc_resource in vnf_inf.vnfc_resource_info:
if storage_resource.id in \
vnfc_resource.storage_resource_ids:
resource = objects.ResourceDefinition()
resource.id = storage_resource.id
resource.type = constants.TYPE_STORAGE
resource.vdu_id = vnfc_resource.vdu_id
resource.resource_template_id = \
storage_resource.virtual_storage_desc_id
vim_id = \
storage_resource.storage_resource. \
vim_connection_id
rsc_id = storage_resource.storage_resource.resource_id
st_rh = objects.ResourceHandle(
vim_connection_id=vim_id,
resource_id=rsc_id)
resource.resource = st_rh
rm_resources.append(resource)
def _init_add_resources(self, context, vnf_instance, vim_connection_info,
add_resources, vnf_inf, placement_obj_list,
affinity_list, vnf_dict):
instantiate_vnf_request = objects.InstantiateVnfRequest. \
from_vnf_instance(vnf_instance)
vnfd_dict = vnflcm_utils._get_vnfd_dict(
context, vnf_instance.vnfd_id,
instantiate_vnf_request.flavour_id)
vnf_instance_after = copy.deepcopy(vnf_instance)
vnf_instance_after.instantiated_vnf_info.reinitialize()
vnflcm_utils._build_instantiated_vnf_info(
vnfd_dict, instantiate_vnf_request,
vnf_instance_after,
vim_connection_info.vim_id)
vnf_inf_after = vnf_instance_after.instantiated_vnf_info
vnfc_rs_ids_list_before = []
for vnfc_resource in vnf_inf_after.vnfc_resource_info:
resource = objects.ResourceDefinition()
resource.id = vnfc_resource.id
resource.type = constants.TYPE_COMPUTE
resource.vdu_id = vnfc_resource.vdu_id
resource.resource_template_id = vnfc_resource.vdu_id
add_resources.append(resource)
for vnfc_resource_before in vnf_inf.vnfc_resource_info:
if vnfc_resource_before.vdu_id == \
vnfc_resource.vdu_id and vnfc_resource_before.id \
not in vnfc_rs_ids_list_before:
key_id = vnfc_resource_before.id
vnfc_rs_ids_list_before.append(key_id)
break
for placement_obj in placement_obj_list:
resource_dict = jsonutils.loads(placement_obj.resource)
set_flg = False
for resource in resource_dict:
if resource.get('resource_id') == key_id:
resource['id_type'] = 'GRANT'
resource['resource_id'] = vnfc_resource.id
g_name = placement_obj.server_group_name
affinity_list.append(g_name)
set_flg = True
res_json = jsonutils.dump_as_bytes(resource_dict)
placement_obj.resource = res_json
break
if set_flg:
break
for vl_resource in vnf_inf_after.vnf_virtual_link_resource_info:
resource = objects.ResourceDefinition()
resource.id = vl_resource.id
resource.type = constants.TYPE_VL
resource.resource_template_id = \
vl_resource.vnf_virtual_link_desc_id
add_resources.append(resource)
for cp_resource in vl_resource.vnf_link_ports:
for vnfc_resource in vnf_inf_after.vnfc_resource_info:
for vnfc_cp_resource in vnfc_resource.vnfc_cp_info:
if cp_resource.cp_instance_id == \
vnfc_cp_resource.id:
resource = objects.ResourceDefinition()
resource.id = cp_resource.id
resource.type = constants.TYPE_LINKPORT
resource.vdu_id = vnfc_resource.vdu_id
resource.resource_template_id = \
vnfc_cp_resource.cpd_id
add_resources.append(resource)
for storage_resource in vnf_inf_after. \
virtual_storage_resource_info:
for vnfc_resource in vnf_inf_after.vnfc_resource_info:
if storage_resource.id in \
vnfc_resource.storage_resource_ids:
resource = objects.ResourceDefinition()
resource.id = storage_resource.id
resource.type = constants.TYPE_STORAGE
resource.vdu_id = vnfc_resource.vdu_id
resource.resource_template_id = \
storage_resource.virtual_storage_desc_id
add_resources.append(resource)
vnf_dict['vnf_instance_after'] = vnf_instance_after
@grant_error_common
def _heal_grant(self,
context,
@ -1247,19 +1400,21 @@ class Conductor(manager.Manager):
'get_cinder_list',
vnf_info=vnf_dict)
vnf_instantiated_info_after = copy.deepcopy(vnf_inf)
del_cre_vdu_list = []
add_resources = []
rm_resources = []
affinity_list = []
for vnfc_resource in vnf_instantiated_info_after.vnfc_resource_info:
vnfc_key = vnfc_resource.compute_resource.resource_id
if not heal_vnf_request.vnfc_instance_id or \
vnfc_key in heal_vnf_request.vnfc_instance_id:
if vnfc_resource.vdu_id not in del_cre_vdu_list:
del_cre_vdu_list.append(vnfc_resource.vdu_id)
for vnfc_resource in vnf_instantiated_info_after.vnfc_resource_info:
if vnfc_resource.vdu_id in del_cre_vdu_list:
rm_resources = []
add_resources = []
update_resources = []
if not heal_vnf_request.vnfc_instance_id:
# init remove_resources
self._init_remove_resources(vnf_inf, rm_resources)
# init add_resources
self._init_add_resources(
context, vnf_instance, vim_connection_info, add_resources,
vnf_inf, placement_obj_list, affinity_list, vnf_dict)
else:
for vnfc_resource in vnf_inf.vnfc_resource_info:
vnfc_key = vnfc_resource.id
if vnfc_key in heal_vnf_request.vnfc_instance_id:
resource = objects.ResourceDefinition()
resource.id = vnfc_resource.id
resource.type = constants.TYPE_COMPUTE
@ -1271,14 +1426,7 @@ class Conductor(manager.Manager):
vim_connection_id=vim_id,
resource_id=rsc_id)
resource.resource = vnfc_rh
rm_resources.append(resource)
add_uuid = uuidutils.generate_uuid()
resource = objects.ResourceDefinition()
resource.id = add_uuid
resource.type = constants.TYPE_COMPUTE
resource.vdu_id = vnfc_resource.vdu_id
resource.resource_template_id = vnfc_resource.vdu_id
add_resources.append(resource)
update_resources.append(resource)
key_id = vnfc_resource.compute_resource.resource_id
for placement_obj in placement_obj_list:
@ -1287,19 +1435,18 @@ class Conductor(manager.Manager):
for resource in resource_dict:
if resource.get('resource_id') == key_id:
resource['id_type'] = 'GRANT'
resource['resource_id'] = add_uuid
resource['resource_id'] = vnfc_resource.id
g_name = placement_obj.server_group_name
affinity_list.append(g_name)
set_flg = True
res_json = jsonutils.dump_as_bytes(resource_dict)
res_json = \
jsonutils.dump_as_bytes(resource_dict)
placement_obj.resource = res_json
break
if set_flg:
break
vnfc_resource.id = add_uuid
vnfc_resource.compute_resource = objects.ResourceHandle()
st_info = vnf_instantiated_info_after.virtual_storage_resource_info
st_info = vnf_inf.virtual_storage_resource_info
for storage_resource in st_info:
if storage_resource.virtual_storage_desc_id in cinder_list:
for vnfc_resource in vnf_inf.vnfc_resource_info:
@ -1313,24 +1460,12 @@ class Conductor(manager.Manager):
storage_resource.virtual_storage_desc_id
st_rh = objects.ResourceHandle()
st_rh.vim_connection_id = \
storage_resource.storage_resource.vim_connection_id
storage_resource.storage_resource.\
vim_connection_id
st_rh.resource_id = \
storage_resource.storage_resource.resource_id
resource.resource = st_rh
rm_resources.append(resource)
add_uuid = uuidutils.generate_uuid()
resource = objects.ResourceDefinition()
resource = objects.ResourceDefinition()
resource.id = add_uuid
resource.type = constants.TYPE_STORAGE
resource.vdu_id = vnfc_resource.vdu_id
resource.resource_template_id = \
storage_resource.virtual_storage_desc_id
add_resources.append(resource)
storage_resource.id = add_uuid
storage_resource.storage_resource = \
objects.ResourceHandle()
update_resources.append(resource)
p_c_list = []
for placement_obj in placement_obj_list:
@ -1355,11 +1490,11 @@ class Conductor(manager.Manager):
False,
add_resources=add_resources,
remove_resources=rm_resources,
update_resources=update_resources,
placement_constraints=p_c_list)
vnf_dict['placement_obj_list'] = placement_obj_list
vnf_dict['grant'] = self._grant(context, g_request)
vnf_dict['vnf_instantiated_info_after'] = vnf_instantiated_info_after
@grant_error_common
def _terminate_grant(self, context, vnf_instance, vnf_lcm_op_occ_id):

View File

@ -0,0 +1,100 @@
heat_template_version: 2013-05-23
description: 'Simple Base HOT for Sample VNF'
parameters:
nfv:
type: json
resources:
VDU1_scale:
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 }
subnet: { get_param: [nfv, CP, VDU1_CP2, fixed_ips, 0, subnet]}
VDU1_scale_scale_out:
type: OS::Heat::ScalingPolicy
properties:
scaling_adjustment: 1
auto_scaling_group_id:
get_resource: VDU1_scale
adjustment_type: change_in_capacity
VDU1_scale_scale_in:
type: OS::Heat::ScalingPolicy
properties:
scaling_adjustment: -1
auto_scaling_group_id:
get_resource: VDU1_scale
adjustment_type: change_in_capacity
VDU2_scale:
type: OS::Heat::AutoScalingGroup
properties:
min_size: 1
max_size: 1
desired_capacity: 1
resource:
type: VDU2.yaml
properties:
flavor: { get_param: [ nfv, VDU, VDU2, flavor ] }
image: { get_param: [ nfv, VDU, VDU2, image ] }
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 }
ip1: { get_param: [nfv, CP, VDU2_CP2, fixed_ips, 0, ip_address]}
subnet: { get_param: [nfv, CP, VDU2_CP2, fixed_ips, 0, subnet]}
VDU2_scale_scale_out:
type: OS::Heat::ScalingPolicy
properties:
scaling_adjustment: 1
auto_scaling_group_id:
get_resource: VDU2_scale
adjustment_type: change_in_capacity
VDU2_scale_scale_in:
type: OS::Heat::ScalingPolicy
properties:
scaling_adjustment: -1
auto_scaling_group_id:
get_resource: VDU2_scale
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: {}

View File

@ -0,0 +1,65 @@
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
subnet:
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 }
fixed_ips:
- subnet: { get_param: subnet}
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 }

View File

@ -0,0 +1,65 @@
heat_template_version: 2013-05-23
description: 'VDU2 HOT for Sample VNF'
parameters:
flavor:
type: string
image:
type: string
net1:
type: string
net2:
type: string
net3:
type: string
net4:
type: string
net5:
type: string
ip1:
type: string
subnet:
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
VDU2_CP1:
type: OS::Neutron::Port
properties:
network: { get_param: net1 }
VDU2_CP2:
type: OS::Neutron::Port
properties:
network: { get_param: net2 }
fixed_ips:
- ip_address: { get_param: ip1}
subnet: { get_param: subnet}
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 }

View File

@ -0,0 +1,413 @@
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.5.2-x86_64-disk
version: '0.5.2'
checksum:
algorithm: sha-256
hash: 932fcae93574e242dc3d772d5235061747dfe537668443a1f0567d893614b464
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: 1
max_number_of_instances: 1
sw_image_data:
name: cirros-0.5.2-x86_64-disk
version: '0.5.2'
checksum:
algorithm: sha-256
hash: 932fcae93574e242dc3d772d5235061747dfe537668443a1f0567d893614b464
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:
VDU1_scale:
name: VDU1_scale
description: VDU1 scaling aspect
max_scale_level: 2
step_deltas:
- delta_1
VDU2_scale:
name: VDU2_scale
description: VDU2 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: 1
targets: [ VDU2 ]
- VDU1_scaling_aspect_deltas:
type: tosca.policies.nfv.VduScalingAspectDeltas
properties:
aspect: VDU1_scale
deltas:
delta_1:
number_of_instances: 1
targets: [ VDU1 ]
- VDU2_scaling_aspect_deltas:
type: tosca.policies.nfv.VduScalingAspectDeltas
properties:
aspect: VDU2_scale
deltas:
delta_1:
number_of_instances: 1
targets: [ VDU2 ]
- instantiation_levels:
type: tosca.policies.nfv.InstantiationLevels
properties:
levels:
instantiation_level_1:
description: Smallest size
scale_info:
VDU1_scale:
scale_level: 0
VDU2_scale:
scale_level: 0
instantiation_level_2:
description: Largest size
scale_info:
VDU1_scale:
scale_level: 2
VDU2_scale:
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: 1
instantiation_level_2:
number_of_instances: 1
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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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}

View File

@ -0,0 +1,59 @@
tosca_definitions_version: tosca_simple_yaml_1_2
description: VNF type definition
node_types:
company.provider.VNF:
derived_from: tosca.nodes.nfv.VNF
properties:
id:
type: string
description: ID of this VNF
default: vnf_id
vendor:
type: string
description: name of the vendor who generate this VNF
default: vendor
version:
type: version
description: version of the software for this VNF
default: 1.0
descriptor_id:
type: string
constraints: [ valid_values: [ b1db0ce7-ebca-1fb7-95ed-4840d70a1163 ] ]
default: b1db0ce7-ebca-1fb7-95ed-4840d70a1163
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: "This is the default flavour description"
requirements:
- virtual_link_internal:
capability: tosca.capabilities.nfv.VirtualLinkable
interfaces:
Vnflcm:
type: tosca.interfaces.nfv.Vnflcm

View File

@ -0,0 +1,144 @@
tosca_definitions_version: tosca_simple_yaml_1_2
topology_template:
inputs:
id:
type: string
vendor:
type: string
version:
type: version
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 ]
node_templates:
VNF:
type: company.provider.VNF
properties:
flavour_description: A simple flavour
interfaces:
Vnflcm:
instantiate_end: []
VDU1:
type: tosca.nodes.nfv.Vdu.Compute
properties:
name: VDU1
description: VDU1 compute node
vdu_profile:
min_number_of_instances: 2
max_number_of_instances: 4
sw_image_data:
name: ubuntu-20.04-server-cloudimg-amd64
version: '20.04'
checksum:
algorithm: sha-512
hash: fb1a1e50f9af2df6ab18a69b6bc5df07ebe8ef962b37e556ce95350ffc8f4a1118617d486e2018d1b3586aceaeda799e6cc073f330a7ad8f0ec0416cbd825452
container_format: bare
disk_format: qcow2
min_disk: 0 GB
size: 2 GB
capabilities:
virtual_compute:
properties:
requested_additional_capabilities:
properties:
requested_additional_capability_name: m1.medium
support_mandatory: true
target_performance_parameters:
entry_schema: test
virtual_memory:
virtual_mem_size: 4 GB
virtual_cpu:
num_virtual_cpu: 2
virtual_local_storage:
- size_of_storage: 45 GB
PORT1:
type: tosca.nodes.nfv.VduCp
properties:
layer_protocols: [ ipv4 ]
order: 0
requirements:
- virtual_binding: VDU1
policies:
- scaling_aspects:
type: tosca.policies.nfv.ScalingAspects
properties:
aspects:
master_instance:
name: master_instance
description: master_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: 2
targets: [ VDU1 ]
- VDU1_scaling_deltas:
type: tosca.policies.nfv.VduScalingAspectDeltas
properties:
aspect: master_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:
master_instance:
scale_level: 0
instantiation_level_2:
description: Largest size
scale_info:
master_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: 2
instantiation_level_2:
number_of_instances: 4
targets: [ VDU1 ]

View File

@ -81,8 +81,12 @@ class Grant:
res_update_resources = []
for req_update_resource in req_update_resources:
res_update_resource = {
"resourceDefinitionId": req_update_resource['id']
"resourceDefinitionId": req_update_resource['id'],
"vimConnectionId": uuidsentinel.vim_connection_id
}
if req_update_resource['type'] == 'COMPUTE':
res_update_resource["zoneId"] = uuidsentinel.zone_id
res_update_resources.append(res_update_resource)
return res_update_resources
@ -177,6 +181,9 @@ class Grant:
if 'removeResources' in request_body.keys():
res["removeResources"] = Grant._make_remove_resources(
request_body['removeResources'])
if 'updateResources' in request_body.keys():
res["updateResources"] = Grant._make_update_resources(
request_body['updateResources'])
res["vimAssets"] = Grant._make_vim_assets(image_id)
return res

View File

@ -353,6 +353,140 @@ class VnfLcmWithNfvoSeparator(vnflcm_base.BaseVnfLcmTest):
resp, response_body = self._delete_subscription(subscription_id)
self.assertEqual(204, resp.status_code)
def test_inst_scale_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.
- Get VNF informations.
- Scale-Out VNF
- Scale-In VNF
- Terminate VNF
- Delete VNF
- Delete subscription
"""
vnf_package_info = self._register_vnf_package_mock_response(
package_dir='functional7')
glance_image = self._list_glance_image()[0]
# Create subscription and register it.
callback_url = os.path.join(vnflcm_base.MOCK_NOTIFY_CALLBACK_URL,
self._testMethodName)
request_body = fake_vnflcm.Subscription.make_create_request_body(
'http://localhost:{}{}'.format(
vnflcm_base.FAKE_SERVER_MANAGER.SERVER_PORT,
callback_url))
resp, response_body = self._register_subscription(request_body)
self.assertEqual(201, resp.status_code)
self.assert_http_header_location_for_subscription(resp.headers)
self.assert_notification_get(callback_url)
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_include_num_dynamic(
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)
self._assert_stack_template_scale(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(Scale-out)
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_scaleout_response_body(req_body,
self.vim['tenant_id'], glance_image.id))
# Scale-out vnf instance
stack = self._get_heat_stack(vnf_instance_id)
pre_stack_resource_list = self._get_heat_resource_list(stack.id, 2)
request_body = fake_vnflcm.VnfInstances.\
make_scale_request_body('SCALE_OUT')
resp, _ = self._scale_vnf_instance(vnf_instance_id, request_body)
self._wait_lcm_done('COMPLETED', vnf_instance_id=vnf_instance_id)
post_stack_resource_list = self._get_heat_resource_list(stack.id, 2)
self._assert_scale_vnf(resp, vnf_instance_id,
pre_stack_resource_list,
post_stack_resource_list,
scale_type='SCALE_OUT')
# Set Fake server response for Grant-Req(Scale-in)
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_scalein_response_body(req_body))
# Scale-in vnf instance
stack = self._get_heat_stack(vnf_instance_id)
pre_stack_resource_list = self._get_heat_resource_list(stack.id, 2)
request_body = fake_vnflcm.VnfInstances.make_scale_request_body(
'SCALE_IN')
resp, _ = self._scale_vnf_instance(vnf_instance_id, request_body)
self._wait_lcm_done('COMPLETED', vnf_instance_id=vnf_instance_id)
post_stack_resource_list = self._get_heat_resource_list(stack.id, 2)
self._assert_scale_vnf(resp, vnf_instance_id,
pre_stack_resource_list,
post_stack_resource_list,
scale_type='SCALE_IN')
# 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.
@ -421,6 +555,27 @@ class VnfLcmWithNfvoSeparator(vnflcm_base.BaseVnfLcmTest):
self.assertEqual(1, len(grant_mock_responses))
self._assert_grant_mock_response(grant_mock_responses[0])
def _assert_scale_vnf(self,
resp,
vnf_instance_id,
pre_stack_resource_list,
post_stack_resource_list,
scale_type):
super().assert_scale_vnf(
resp,
vnf_instance_id,
pre_stack_resource_list,
post_stack_resource_list,
scale_type=scale_type)
# 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.
@ -543,3 +698,14 @@ class VnfLcmWithNfvoSeparator(vnflcm_base.BaseVnfLcmTest):
template = self._get_heat_stack_template(physical_resource_id[0])
template_count = str(template).count("flavor")
self.assertEqual(template_count, 3)
def _assert_stack_template_scale(self, vnf_instance_id):
stack = self._get_heat_stack(vnf_instance_id)
resources_list\
= self._get_heat_resource_list(stack.id, nested_depth=2)
stack_name_wd = vnf_instance_id + "-VDU1"
physical_resource_id = [r.physical_resource_id for r
in resources_list if stack_name_wd in r.stack_name]
template = self._get_heat_stack_template(physical_resource_id[0])
template_count = str(template).count("zone")
self.assertEqual(template_count, 3)

View File

@ -1608,6 +1608,9 @@ class TestConductor(SqlTestCase, unit_base.FixturedTestCase):
@mock.patch('tacker.conductor.conductor_server.Conductor.'
'_update_vnf_attributes_stack_param')
@mock.patch('tacker.vnflcm.utils'
'._build_instantiated_vnf_info')
@mock.patch('tacker.vnflcm.utils._get_vnfd_dict')
@mock.patch('tacker.conductor.conductor_server.Conductor'
'._change_vnf_status')
@mock.patch('tacker.conductor.conductor_server.Conductor'
@ -1641,6 +1644,8 @@ class TestConductor(SqlTestCase, unit_base.FixturedTestCase):
mock_add_vnf_info,
mock_update_vnf_info,
mock_change_status,
mock_vnfd_dict,
mock_build_info,
mock_update_vnf_attributes_stack_param):
vnf_package_vnfd = self._create_and_upload_vnf_package()
vnf_instance_data = fake_obj.get_vnf_instance_data(
@ -1660,6 +1665,9 @@ class TestConductor(SqlTestCase, unit_base.FixturedTestCase):
vnf_lcm_op_occs_id = 'a9c36d21-21aa-4692-8922-7999bbcae08c'
mock_exec.return_value = True
mock_act.return_value = None
vnfd_key = 'vnfd_' + vnf_instance.instantiated_vnf_info.flavour_id
vnfd_yaml = vnf_dict['vnfd']['attributes'].get(vnfd_key, '')
mock_vnfd_dict.return_value = yaml.safe_load(vnfd_yaml)
vim_obj = {'vim_id': uuidsentinel.vim_id,
'vim_name': 'fake_vim',
'vim_type': 'openstack',
@ -1700,6 +1708,7 @@ class TestConductor(SqlTestCase, unit_base.FixturedTestCase):
@mock.patch('tacker.conductor.conductor_server.Conductor.'
'_update_vnf_attributes_stack_param')
@mock.patch('tacker.vnflcm.utils._get_vnfd_dict')
@mock.patch('tacker.conductor.conductor_server.Conductor'
'._change_vnf_status')
@mock.patch('tacker.conductor.conductor_server.Conductor'
@ -1736,6 +1745,7 @@ class TestConductor(SqlTestCase, unit_base.FixturedTestCase):
mock_add_vnf_info,
mock_update_vnf_info,
mock_change_status,
mock_vnfd_dict,
mock_update_vnf_attribute_stack_param):
vnf_package_vnfd = self._create_and_upload_vnf_package()
vnf_instance_data = fake_obj.get_vnf_instance_data(
@ -1795,6 +1805,50 @@ class TestConductor(SqlTestCase, unit_base.FixturedTestCase):
vnf_dict = db_utils.get_dummy_vnf_etsi(instance_id=self.instance_uuid,
flavour='simple')
vnf_dict['before_error_point'] = fields.ErrorPoint.INITIAL
vnfd_yaml = os.path.abspath(os.path.join(os.path.dirname(__file__),
'../../etc/samples/etsi/nfv/'
'test_heal_grant_unit/'
'sample_vnfd.yaml'))
with open(vnfd_yaml) as f:
mock_vnfd_dict.return_value = yaml.safe_load(f)
mock_vnfd_dict.return_value['imports'] = []
etsi_common_file_path = os.path.abspath(
os.path.join(os.path.dirname(__file__),
'../../etc/samples/etsi/nfv/common/Definitions/'
'etsi_nfv_sol001_common_types.yaml'))
etsi_vnfd_file_path = os.path.abspath(
os.path.join(os.path.dirname(__file__),
'../../etc/samples/etsi/nfv/common/Definitions/'
'etsi_nfv_sol001_vnfd_types.yaml'))
etsi_vnfd_file_path_tmp = os.path.abspath(
os.path.join(os.path.dirname(__file__),
'../../etc/samples/etsi/nfv/common/Definitions/'
'etsi_nfv_sol001_vnfd_types_tmp.yaml'))
with open(etsi_vnfd_file_path) as f:
data = yaml.safe_load(f)
del data['imports']
data['imports'] = []
data['imports'].append(etsi_common_file_path)
with open(etsi_vnfd_file_path_tmp, "w", encoding="utf-8") as f:
yaml.dump(data, f)
types_file_path = os.path.abspath(
os.path.join(os.path.dirname(__file__),
'../../etc/samples/etsi/nfv/test_heal_grant_unit/'
'helloworld3_types.yaml'))
types_file_tmp_path = os.path.abspath(
os.path.join(os.path.dirname(__file__),
'../../etc/samples/etsi/nfv/test_heal_grant_unit/'
'helloworld3_types_tmp.yaml'))
with open(types_file_path) as f:
data = yaml.safe_load(f)
data['imports'] = []
data['imports'].append(etsi_common_file_path)
data['imports'].append(etsi_vnfd_file_path_tmp)
with open(types_file_tmp_path, "w", encoding="utf-8") as f:
yaml.dump(data, f)
mock_vnfd_dict.return_value['imports'].append(etsi_common_file_path)
mock_vnfd_dict.return_value['imports'].append(etsi_vnfd_file_path_tmp)
mock_vnfd_dict.return_value['imports'].append(types_file_tmp_path)
vnf_lcm_op_occs_id = 'a9c36d21-21aa-4692-8922-7999bbcae08c'
mock_exec.return_value = True
mock_act.return_value = None
@ -1822,6 +1876,12 @@ class TestConductor(SqlTestCase, unit_base.FixturedTestCase):
resource = {
'resourceDefinitionId': 'faf14707-da7c-4eec-be99-8099fa1e9fa0'}
resRemResource.append(resource)
resource = {
'resourceDefinitionId': 'c91e0e86-e555-71fc-0f6b-e3d2945f2fd6'}
resRemResource.append(resource)
resource = {
'resourceDefinitionId': '5d84a03c-07e9-4978-b0cd-6450482189b7'}
resRemResource.append(resource)
resource = {
'resourceDefinitionId': '2c6e5cc7-240d-4458-a683-1fe648351281',
'vimConnectionId': uuidsentinel.vim_id,
@ -1866,7 +1926,12 @@ class TestConductor(SqlTestCase, unit_base.FixturedTestCase):
mock_update_vnf_attribute_stack_param.assert_called_once()
self.vnflcm_driver.heal_vnf.assert_called_once_with(
self.context, mock.ANY, vnf_dict, heal_vnf_req)
os.remove(types_file_tmp_path)
os.remove(etsi_vnfd_file_path_tmp)
@mock.patch('tacker.vnflcm.utils'
'._build_instantiated_vnf_info')
@mock.patch('tacker.vnflcm.utils._get_vnfd_dict')
@mock.patch('tacker.conductor.conductor_server.Conductor'
'.send_notification')
@mock.patch('tacker.conductor.conductor_server.Conductor'
@ -1899,7 +1964,9 @@ class TestConductor(SqlTestCase, unit_base.FixturedTestCase):
mock_save,
mock_add_vnf_info,
mock_update_vnf_info,
mock_send):
mock_send,
mock_vnfd_dict,
mock_build_info):
vnf_package_vnfd = self._create_and_upload_vnf_package()
vnf_instance_data = fake_obj.get_vnf_instance_data(
vnf_package_vnfd.vnfd_id)
@ -1915,6 +1982,9 @@ class TestConductor(SqlTestCase, unit_base.FixturedTestCase):
vnf_dict = db_utils.get_dummy_vnf_etsi(instance_id=self.instance_uuid,
flavour='simple')
vnf_dict['before_error_point'] = fields.ErrorPoint.INITIAL
vnfd_key = 'vnfd_' + vnf_instance.instantiated_vnf_info.flavour_id
vnfd_yaml = vnf_dict['vnfd']['attributes'].get(vnfd_key, '')
mock_vnfd_dict.return_value = yaml.safe_load(vnfd_yaml)
vnf_lcm_op_occs_id = 'a9c36d21-21aa-4692-8922-7999bbcae08c'
mock_exec.return_value = True
mock_act.return_value = None
@ -1961,6 +2031,9 @@ class TestConductor(SqlTestCase, unit_base.FixturedTestCase):
mock_send.call_args[0][1].get('operationState'),
'ROLLED_BACK')
@mock.patch('tacker.vnflcm.utils'
'._build_instantiated_vnf_info')
@mock.patch('tacker.vnflcm.utils._get_vnfd_dict')
@mock.patch('tacker.conductor.conductor_server.Conductor'
'.send_notification')
@mock.patch('tacker.conductor.conductor_server.Conductor'
@ -1993,7 +2066,9 @@ class TestConductor(SqlTestCase, unit_base.FixturedTestCase):
mock_save,
mock_add_vnf_info,
mock_update_vnf_info,
mock_send):
mock_send,
mock_vnfd_dict,
mock_build_info):
vnf_package_vnfd = self._create_and_upload_vnf_package()
vnf_instance_data = fake_obj.get_vnf_instance_data(
vnf_package_vnfd.vnfd_id)
@ -2009,6 +2084,9 @@ class TestConductor(SqlTestCase, unit_base.FixturedTestCase):
vnf_dict = db_utils.get_dummy_vnf_etsi(instance_id=self.instance_uuid,
flavour='simple')
vnf_dict['before_error_point'] = fields.ErrorPoint.INITIAL
vnfd_key = 'vnfd_' + vnf_instance.instantiated_vnf_info.flavour_id
vnfd_yaml = vnf_dict['vnfd']['attributes'].get(vnfd_key, '')
mock_vnfd_dict.return_value = yaml.safe_load(vnfd_yaml)
vnf_lcm_op_occs_id = 'a9c36d21-21aa-4692-8922-7999bbcae08c'
mock_exec.return_value = True
mock_act.return_value = None

View File

@ -165,6 +165,15 @@ def return_vnf_instance_model(
return model_obj
def return_vnf_instance_delete(
instantiated_state=fields.VnfInstanceState.NOT_INSTANTIATED,
**updates):
data = _model_non_instantiated_vnf_instance(**updates)
data['instantiation_state'] = instantiated_state
vnf_instance_obj = objects.VnfInstance(**data)
return vnf_instance_obj
def return_vnf_instance(
instantiated_state=fields.VnfInstanceState.NOT_INSTANTIATED,
scale_status=None,
@ -173,7 +182,15 @@ def return_vnf_instance(
if instantiated_state == fields.VnfInstanceState.NOT_INSTANTIATED:
data = _model_non_instantiated_vnf_instance(**updates)
data['instantiation_state'] = instantiated_state
get_instantiated_vnf_info = {
'flavour_id': uuidsentinel.flavour_id,
'vnf_state': 'STARTED',
'instance_id': ''
}
instantiated_vnf_info = get_instantiated_vnf_info
info_data = objects.InstantiatedVnfInfo(**instantiated_vnf_info)
vnf_instance_obj = objects.VnfInstance(**data)
vnf_instance_obj.instantiated_vnf_info = info_data
elif scale_status:
data = _model_non_instantiated_vnf_instance(**updates)

View File

@ -1729,7 +1729,7 @@ class TestController(base.TestCase):
req = fake_request.HTTPRequest.blank(
'/vnf_instances/%s' % uuidsentinel.vnf_instance_id)
req.method = 'DELETE'
mock_vnf_by_id.return_value = fakes.return_vnf_instance()
mock_vnf_by_id.return_value = fakes.return_vnf_instance_delete()
req.headers['Content-Type'] = 'application/json'
# Call delete API

View File

@ -136,6 +136,7 @@ class MgmtVnfLcmDriverTest(db_base.SqlTestCase):
'test_project'}, 'vim_type': 'openstack'}
self.vim_client.get_vim.return_value = vim_obj
@mock.patch('tacker.vnflcm.utils.get_default_scale_status')
@mock.patch('tacker.vnflcm.utils._make_final_vnf_dict')
@mock.patch.object(VnfLcmDriver, '_init_mgmt_driver_hash')
@mock.patch.object(TackerManager, 'get_service_plugins',
@ -146,7 +147,7 @@ class MgmtVnfLcmDriverTest(db_base.SqlTestCase):
def test_instantiate_vnf(self, mock_vnf_instance_save,
mock_vnf_package_vnfd, mock_create,
mock_get_service_plugins, mock_init_hash,
mock_final_vnf_dict):
mock_final_vnf_dict, mock_default_status):
mock_init_hash.return_value = {
"vnflcm_noop": "ffea638bfdbde3fb01f191bbe75b031859"
"b18d663b127100eb72b19eecd7ed51"
@ -159,6 +160,7 @@ class MgmtVnfLcmDriverTest(db_base.SqlTestCase):
objects.InstantiateVnfRequest.obj_from_primitive(
instantiate_vnf_req_dict, self.context)
vnf_instance_obj = fakes.return_vnf_instance()
mock_default_status.return_value = None
fake_csar = os.path.join(self.temp_dir, vnf_package_id)
cfg.CONF.set_override('vnf_package_csar_path', self.temp_dir,
@ -173,7 +175,7 @@ class MgmtVnfLcmDriverTest(db_base.SqlTestCase):
instantiate_vnf_req_obj)
self.assertEqual(1, mock_vnf_instance_save.call_count)
self.assertEqual(5, self._vnf_manager.invoke.call_count)
self.assertEqual(6, self._vnf_manager.invoke.call_count)
shutil.rmtree(fake_csar)
@mock.patch('tacker.vnflcm.utils._make_final_vnf_dict')

View File

@ -190,6 +190,7 @@ class TestVnflcmDriver(db_base.SqlTestCase):
'test_project'}, 'vim_type': 'openstack'}
self.vim_client.get_vim.return_value = vim_obj
@mock.patch('tacker.vnflcm.utils.get_default_scale_status')
@mock.patch('tacker.vnflcm.utils._make_final_vnf_dict')
@mock.patch.object(VnfLcmDriver,
'_init_mgmt_driver_hash')
@ -204,7 +205,8 @@ class TestVnflcmDriver(db_base.SqlTestCase):
def test_instantiate_vnf(
self, mock_vnf_interfaces, mock_vnfd_dict,
mock_vnf_instance_save, mock_vnf_package_vnfd, mock_create,
mock_get_service_plugins, mock_init_hash, mock_final_vnf_dict):
mock_get_service_plugins, mock_init_hash, mock_final_vnf_dict,
mock_default_status):
mock_init_hash.return_value = {
"vnflcm_noop": "ffea638bfdbde3fb01f191bbe75b031859"
"b18d663b127100eb72b19eecd7ed51"
@ -218,6 +220,7 @@ class TestVnflcmDriver(db_base.SqlTestCase):
objects.InstantiateVnfRequest.obj_from_primitive(
instantiate_vnf_req_dict, self.context)
vnf_instance_obj = fakes.return_vnf_instance()
mock_default_status.return_value = None
fake_csar = os.path.join(self.temp_dir, vnf_package_id)
cfg.CONF.set_override('vnf_package_csar_path', self.temp_dir,
@ -232,9 +235,10 @@ class TestVnflcmDriver(db_base.SqlTestCase):
instantiate_vnf_req_obj)
self.assertEqual(1, mock_vnf_instance_save.call_count)
self.assertEqual(5, self._vnf_manager.invoke.call_count)
self.assertEqual(6, self._vnf_manager.invoke.call_count)
shutil.rmtree(fake_csar)
@mock.patch('tacker.vnflcm.utils.get_default_scale_status')
@mock.patch('tacker.vnflcm.utils._make_final_vnf_dict')
@mock.patch.object(VnfLcmDriver,
'_init_mgmt_driver_hash')
@ -249,7 +253,8 @@ class TestVnflcmDriver(db_base.SqlTestCase):
def test_instantiate_vnf_with_error_point_vnf_config_start(
self, mock_vnf_interfaces, mock_vnfd_dict,
mock_vnf_instance_save, mock_vnf_package_vnfd, mock_create,
mock_get_service_plugins, mock_init_hash, mock_final_vnf_dict):
mock_get_service_plugins, mock_init_hash, mock_final_vnf_dict,
mock_default_status):
mock_init_hash.return_value = {
"vnflcm_noop": "ffea638bfdbde3fb01f191bbe75b031859"
"b18d663b127100eb72b19eecd7ed51"
@ -263,6 +268,7 @@ class TestVnflcmDriver(db_base.SqlTestCase):
objects.InstantiateVnfRequest.obj_from_primitive(
instantiate_vnf_req_dict, self.context)
vnf_instance_obj = fakes.return_vnf_instance()
mock_default_status.return_value = None
fake_csar = os.path.join(self.temp_dir, vnf_package_id)
cfg.CONF.set_override('vnf_package_csar_path', self.temp_dir,
@ -277,9 +283,10 @@ class TestVnflcmDriver(db_base.SqlTestCase):
instantiate_vnf_req_obj)
self.assertEqual(1, mock_vnf_instance_save.call_count)
self.assertEqual(5, self._vnf_manager.invoke.call_count)
self.assertEqual(6, self._vnf_manager.invoke.call_count)
shutil.rmtree(fake_csar)
@mock.patch('tacker.vnflcm.utils.get_default_scale_status')
@mock.patch('tacker.vnflcm.utils._make_final_vnf_dict')
@mock.patch.object(VnfLcmDriver,
'_init_mgmt_driver_hash')
@ -294,7 +301,8 @@ class TestVnflcmDriver(db_base.SqlTestCase):
def test_instantiate_vnf_with_error_point_pre_vim_control(
self, mock_vnf_interfaces, mock_vnfd_dict,
mock_vnf_instance_save, mock_vnf_package_vnfd, mock_create,
mock_get_service_plugins, mock_init_hash, mock_final_vnf_dict):
mock_get_service_plugins, mock_init_hash, mock_final_vnf_dict,
mock_default_status):
mock_init_hash.return_value = {
"vnflcm_noop": "ffea638bfdbde3fb01f191bbe75b031859"
"b18d663b127100eb72b19eecd7ed51"
@ -308,6 +316,7 @@ class TestVnflcmDriver(db_base.SqlTestCase):
objects.InstantiateVnfRequest.obj_from_primitive(
instantiate_vnf_req_dict, self.context)
vnf_instance_obj = fakes.return_vnf_instance()
mock_default_status.return_value = None
fake_csar = os.path.join(self.temp_dir, vnf_package_id)
cfg.CONF.set_override('vnf_package_csar_path', self.temp_dir,
@ -322,9 +331,10 @@ class TestVnflcmDriver(db_base.SqlTestCase):
instantiate_vnf_req_obj)
self.assertEqual(1, mock_vnf_instance_save.call_count)
self.assertEqual(4, self._vnf_manager.invoke.call_count)
self.assertEqual(5, self._vnf_manager.invoke.call_count)
shutil.rmtree(fake_csar)
@mock.patch('tacker.vnflcm.utils.get_default_scale_status')
@mock.patch('tacker.vnflcm.utils._make_final_vnf_dict')
@mock.patch.object(VnfLcmDriver,
'_init_mgmt_driver_hash')
@ -339,7 +349,8 @@ class TestVnflcmDriver(db_base.SqlTestCase):
def test_instantiate_vnf_with_error_point_post_vim_control(
self, mock_vnf_interfaces, mock_vnfd_dict,
mock_vnf_instance_save, mock_vnf_package_vnfd, mock_create,
mock_get_service_plugins, mock_init_hash, mock_final_vnf_dict):
mock_get_service_plugins, mock_init_hash, mock_final_vnf_dict,
mock_default_status):
mock_init_hash.return_value = {
"vnflcm_noop": "ffea638bfdbde3fb01f191bbe75b031859"
"b18d663b127100eb72b19eecd7ed51"
@ -353,6 +364,7 @@ class TestVnflcmDriver(db_base.SqlTestCase):
objects.InstantiateVnfRequest.obj_from_primitive(
instantiate_vnf_req_dict, self.context)
vnf_instance_obj = fakes.return_vnf_instance()
mock_default_status.return_value = None
fake_csar = os.path.join(self.temp_dir, vnf_package_id)
cfg.CONF.set_override('vnf_package_csar_path', self.temp_dir,
@ -367,9 +379,10 @@ class TestVnflcmDriver(db_base.SqlTestCase):
instantiate_vnf_req_obj)
self.assertEqual(1, mock_vnf_instance_save.call_count)
self.assertEqual(4, self._vnf_manager.invoke.call_count)
self.assertEqual(5, self._vnf_manager.invoke.call_count)
shutil.rmtree(fake_csar)
@mock.patch('tacker.vnflcm.utils.get_default_scale_status')
@mock.patch('tacker.vnflcm.utils._make_final_vnf_dict')
@mock.patch.object(VnfLcmDriver,
'_init_mgmt_driver_hash')
@ -384,7 +397,8 @@ class TestVnflcmDriver(db_base.SqlTestCase):
def test_instantiate_vnf_with_error_point_internal_processing(
self, mock_vnf_interfaces, mock_vnfd_dict,
mock_vnf_instance_save, mock_vnf_package_vnfd, mock_create,
mock_get_service_plugins, mock_init_hash, mock_final_vnf_dict):
mock_get_service_plugins, mock_init_hash, mock_final_vnf_dict,
mock_default_status):
mock_init_hash.return_value = {
"vnflcm_noop": "ffea638bfdbde3fb01f191bbe75b031859"
"b18d663b127100eb72b19eecd7ed51"
@ -398,6 +412,7 @@ class TestVnflcmDriver(db_base.SqlTestCase):
objects.InstantiateVnfRequest.obj_from_primitive(
instantiate_vnf_req_dict, self.context)
vnf_instance_obj = fakes.return_vnf_instance()
mock_default_status.return_value = None
fake_csar = os.path.join(self.temp_dir, vnf_package_id)
cfg.CONF.set_override('vnf_package_csar_path', self.temp_dir,
@ -415,6 +430,7 @@ class TestVnflcmDriver(db_base.SqlTestCase):
self.assertEqual(1, self._vnf_manager.invoke.call_count)
shutil.rmtree(fake_csar)
@mock.patch('tacker.vnflcm.utils.get_default_scale_status')
@mock.patch('tacker.vnflcm.utils._make_final_vnf_dict')
@mock.patch.object(VnfLcmDriver,
'_init_mgmt_driver_hash')
@ -429,7 +445,8 @@ class TestVnflcmDriver(db_base.SqlTestCase):
def test_instantiate_vnf_with_error_point_vnf_config_end(
self, mock_vnf_interfaces, mock_vnfd_dict,
mock_vnf_instance_save, mock_vnf_package_vnfd, mock_create,
mock_get_service_plugins, mock_init_hash, mock_final_vnf_dict):
mock_get_service_plugins, mock_init_hash, mock_final_vnf_dict,
mock_default_status):
mock_init_hash.return_value = {
"vnflcm_noop": "ffea638bfdbde3fb01f191bbe75b031859"
"b18d663b127100eb72b19eecd7ed51"
@ -443,6 +460,7 @@ class TestVnflcmDriver(db_base.SqlTestCase):
objects.InstantiateVnfRequest.obj_from_primitive(
instantiate_vnf_req_dict, self.context)
vnf_instance_obj = fakes.return_vnf_instance()
mock_default_status.return_value = None
fake_csar = os.path.join(self.temp_dir, vnf_package_id)
cfg.CONF.set_override('vnf_package_csar_path', self.temp_dir,
@ -460,6 +478,7 @@ class TestVnflcmDriver(db_base.SqlTestCase):
self.assertEqual(1, self._vnf_manager.invoke.call_count)
shutil.rmtree(fake_csar)
@mock.patch('tacker.vnflcm.utils.get_default_scale_status')
@mock.patch('tacker.vnflcm.utils._make_final_vnf_dict')
@mock.patch.object(VnfLcmDriver,
'_init_mgmt_driver_hash')
@ -474,7 +493,8 @@ class TestVnflcmDriver(db_base.SqlTestCase):
def test_instantiate_vnf_with_ext_virtual_links(
self, mock_vnf_interfaces, mock_vnfd_dict,
mock_vnf_instance_save, mock_vnf_package_vnfd, mock_create,
mock_get_service_plugins, mock_init_hash, mock_final_vnf_dict):
mock_get_service_plugins, mock_init_hash, mock_final_vnf_dict,
mock_default_status):
mock_init_hash.return_value = {
"vnflcm_noop": "ffea638bfdbde3fb01f191bbe75b031859"
"b18d663b127100eb72b19eecd7ed51"
@ -490,6 +510,7 @@ class TestVnflcmDriver(db_base.SqlTestCase):
objects.InstantiateVnfRequest.obj_from_primitive(
instantiate_vnf_req_dict, self.context)
vnf_instance_obj = fakes.return_vnf_instance()
mock_default_status.return_value = None
fake_csar = os.path.join(self.temp_dir, vnf_package_id)
cfg.CONF.set_override('vnf_package_csar_path', self.temp_dir,
@ -504,9 +525,10 @@ class TestVnflcmDriver(db_base.SqlTestCase):
instantiate_vnf_req_obj)
self.assertEqual(1, mock_vnf_instance_save.call_count)
self.assertEqual(5, self._vnf_manager.invoke.call_count)
self.assertEqual(6, self._vnf_manager.invoke.call_count)
shutil.rmtree(fake_csar)
@mock.patch('tacker.vnflcm.utils.get_default_scale_status')
@mock.patch('tacker.vnflcm.utils._make_final_vnf_dict')
@mock.patch.object(VnfLcmDriver,
'_init_mgmt_driver_hash')
@ -521,7 +543,8 @@ class TestVnflcmDriver(db_base.SqlTestCase):
def test_instantiate_vnf_vim_connection_info(
self, mock_vnf_interfaces, mock_vnfd_dict,
mock_vnf_instance_save, mock_vnf_package_vnfd, mock_create,
mock_get_service_plugins, mock_init_hash, mock_final_vnf_dict):
mock_get_service_plugins, mock_init_hash, mock_final_vnf_dict,
mock_default_status):
mock_init_hash.return_value = {
"vnflcm_noop": "ffea638bfdbde3fb01f191bbe75b031859"
"b18d663b127100eb72b19eecd7ed51"
@ -537,6 +560,7 @@ class TestVnflcmDriver(db_base.SqlTestCase):
objects.InstantiateVnfRequest.obj_from_primitive(
instantiate_vnf_req_dict, self.context)
vnf_instance_obj = fakes.return_vnf_instance()
mock_default_status.return_value = None
fake_csar = os.path.join(self.temp_dir, vnf_package_id)
cfg.CONF.set_override('vnf_package_csar_path', self.temp_dir,
@ -551,9 +575,10 @@ class TestVnflcmDriver(db_base.SqlTestCase):
instantiate_vnf_req_obj)
self.assertEqual(1, mock_vnf_instance_save.call_count)
self.assertEqual(5, self._vnf_manager.invoke.call_count)
self.assertEqual(6, self._vnf_manager.invoke.call_count)
shutil.rmtree(fake_csar)
@mock.patch('tacker.vnflcm.utils.get_default_scale_status')
@mock.patch('tacker.vnflcm.utils._make_final_vnf_dict')
@mock.patch.object(VnfLcmDriver,
'_init_mgmt_driver_hash')
@ -568,7 +593,8 @@ class TestVnflcmDriver(db_base.SqlTestCase):
def test_instantiate_vnf_infra_fails_to_instantiate(
self, mock_vnf_interfaces, mock_vnfd_dict,
mock_vnf_instance_save, mock_vnf_package_vnfd, mock_create,
mock_get_service_plugins, mock_init_hash, mock_final_vnf_dict):
mock_get_service_plugins, mock_init_hash, mock_final_vnf_dict,
mock_default_status):
mock_init_hash.return_value = {
"vnflcm_noop": "ffea638bfdbde3fb01f191bbe75b031859"
"b18d663b127100eb72b19eecd7ed51"
@ -584,6 +610,7 @@ class TestVnflcmDriver(db_base.SqlTestCase):
objects.InstantiateVnfRequest.obj_from_primitive(
instantiate_vnf_req_dict, self.context)
vnf_instance_obj = fakes.return_vnf_instance()
mock_default_status.return_value = None
fake_csar = os.path.join(self.temp_dir, vnf_package_id)
cfg.CONF.set_override('vnf_package_csar_path', self.temp_dir,
@ -610,6 +637,7 @@ class TestVnflcmDriver(db_base.SqlTestCase):
shutil.rmtree(fake_csar)
@mock.patch('tacker.vnflcm.utils.get_default_scale_status')
@mock.patch('tacker.vnflcm.utils._make_final_vnf_dict')
@mock.patch.object(VnfLcmDriver,
'_init_mgmt_driver_hash')
@ -624,7 +652,8 @@ class TestVnflcmDriver(db_base.SqlTestCase):
def test_instantiate_vnf_infra_fails_to_wait_after_instantiate(
self, mock_vnf_interfaces, mock_vnfd_dict,
mock_vnf_instance_save, mock_vnf_package_vnfd, mock_create,
mock_get_service_plugins, mock_init_hash, mock_final_vnf_dict):
mock_get_service_plugins, mock_init_hash, mock_final_vnf_dict,
mock_default_status):
mock_init_hash.return_value = {
"vnflcm_noop": "ffea638bfdbde3fb01f191bbe75b031859"
"b18d663b127100eb72b19eecd7ed51"
@ -640,6 +669,7 @@ class TestVnflcmDriver(db_base.SqlTestCase):
objects.InstantiateVnfRequest.obj_from_primitive(
instantiate_vnf_req_dict, self.context)
vnf_instance_obj = fakes.return_vnf_instance()
mock_default_status.return_value = None
level = instantiate_vnf_req_obj.instantiation_level_id
vnf_instance_obj.instantiated_vnf_info = objects.InstantiatedVnfInfo(
flavour_id=instantiate_vnf_req_obj.flavour_id,
@ -674,6 +704,7 @@ class TestVnflcmDriver(db_base.SqlTestCase):
shutil.rmtree(fake_csar)
@mock.patch('tacker.vnflcm.utils.get_default_scale_status')
@mock.patch('tacker.vnflcm.utils._make_final_vnf_dict')
@mock.patch.object(VnfLcmDriver,
'_init_mgmt_driver_hash')
@ -689,7 +720,7 @@ class TestVnflcmDriver(db_base.SqlTestCase):
self, mock_vnf_interfaces, mock_vnfd_dict,
mock_vnf_instance_save, mock_vnf_package_vnfd,
mock_create, mock_get_service_plugins, mock_init_hash,
mock_final_vnf_dict):
mock_final_vnf_dict, mock_default_status):
mock_init_hash.return_value = {
"vnflcm_noop": "ffea638bfdbde3fb01f191bbe75b031859"
"b18d663b127100eb72b19eecd7ed51"
@ -703,6 +734,7 @@ class TestVnflcmDriver(db_base.SqlTestCase):
objects.InstantiateVnfRequest.obj_from_primitive(
instantiate_vnf_req_dict, self.context)
vnf_instance_obj = fakes.return_vnf_instance()
mock_default_status.return_value = None
fake_csar = os.path.join(self.temp_dir, vnf_package_id)
cfg.CONF.set_override('vnf_package_csar_path', self.temp_dir,
@ -722,6 +754,7 @@ class TestVnflcmDriver(db_base.SqlTestCase):
mock_final_vnf_dict.assert_called_once()
shutil.rmtree(fake_csar)
@mock.patch('tacker.vnflcm.utils.get_default_scale_status')
@mock.patch('tacker.vnflcm.utils._make_final_vnf_dict')
@mock.patch.object(VnfLcmDriver,
'_init_mgmt_driver_hash')
@ -737,7 +770,7 @@ class TestVnflcmDriver(db_base.SqlTestCase):
self, mock_vnf_interfaces, mock_vnfd_dict,
mock_vnf_instance_save, mock_vnf_package_vnfd,
mock_create, mock_get_service_plugins, mock_init_hash,
mock_final_vnf_dict):
mock_final_vnf_dict, mock_default_status):
mock_init_hash.return_value = {
"vnflcm_noop": "ffea638bfdbde3fb01f191bbe75b031859"
"b18d663b127100eb72b19eecd7ed51"
@ -751,6 +784,7 @@ class TestVnflcmDriver(db_base.SqlTestCase):
objects.InstantiateVnfRequest.obj_from_primitive(
instantiate_vnf_req_dict, self.context)
vnf_instance_obj = fakes.return_vnf_instance()
mock_default_status.return_value = None
fake_csar = os.path.join(self.temp_dir, vnf_package_id)
cfg.CONF.set_override('vnf_package_csar_path', self.temp_dir,
@ -1227,7 +1261,7 @@ class TestVnflcmDriver(db_base.SqlTestCase):
self.assertEqual(1, mock_resource_create.call_count)
# Invoke will be called 7 times, 3 for deleting the vnf
# resources and 4 during instantiation.
self.assertEqual(8, self._vnf_manager.invoke.call_count)
self.assertEqual(9, self._vnf_manager.invoke.call_count)
expected_msg = ("Request received for healing vnf '%s' "
"is completed successfully")
mock_log.info.assert_called_with(expected_msg,

View File

@ -2745,7 +2745,8 @@ class TestKubernetes(base.TestCase):
context=self.context,
vnf_instance=self.vnf_instance,
scale_vnf_request=scale_vnf_req,
vim_connection_info=fakes.fake_vim_connection_info())
vim_connection_info=fakes.fake_vim_connection_info(),
vnf_info=None)
self.assertEqual(mock_list_namespaced_pod.call_count, 1)
# validate added VnfcResourceInfo
vnfc_resource_info_after = \
@ -2798,7 +2799,8 @@ class TestKubernetes(base.TestCase):
context=self.context,
vnf_instance=self.vnf_instance,
scale_vnf_request=scale_vnf_req,
vim_connection_info=fakes.fake_vim_connection_info())
vim_connection_info=fakes.fake_vim_connection_info(),
vnf_info=None)
self.assertEqual(mock_list_namespaced_pod.call_count, 1)
# validate VnfcResourceInfo
vnfc_resource_info_after = \
@ -2844,7 +2846,7 @@ class TestKubernetes(base.TestCase):
self.assertRaises(client.rest.ApiException,
self.kubernetes.scale_resource_update,
self.context, self.vnf_instance,
scale_vnf_req,
scale_vnf_req, None,
fakes.fake_vim_connection_info())
@mock.patch.object(client.CoreV1Api, 'list_namespaced_pod')

View File

@ -12,7 +12,7 @@ resources:
auto_scaling_group_id: {get_resource: SP1_group}
adjustment_type: change_in_capacity
scaling_adjustment: 1
SP1_group:
SP1:
type: OS::Heat::AutoScalingGroup
properties:
min_size: 0
@ -25,7 +25,7 @@ resources:
SP1_scale_in:
type: OS::Heat::ScalingPolicy
properties:
auto_scaling_group_id: {get_resource: SP1_group}
auto_scaling_group_id: {get_resource: SP1}
adjustment_type: change_in_capacity
scaling_adjustment: -1
outputs: {}

View File

@ -572,3 +572,50 @@ def get_lcm_op_occs_object(operation="INSTANTIATE",
error_point=error_point)
return vnf_lcm_op_occs
def get_vnfc_resource_info_with_vnf_info(vdu_id="workerNode",
storage_resource_ids=None):
storage_resource_ids = storage_resource_ids or []
vnfc_cp_info = _get_vnfc_cp_info_with_vnf_info(cpd_id='workerNode_CP2')
vnfc_resource_info = objects.VnfcResourceInfo(
id=uuidsentinel.vnfc_resource_id, vdu_id=vdu_id,
vnfc_cp_info=[vnfc_cp_info],
storage_resource_ids=storage_resource_ids)
return vnfc_resource_info
def _get_vnfc_cp_info_with_vnf_info(cpd_id="CP1"):
vnfc_cp_info = objects.VnfcCpInfo(
id=uuidsentinel.vnfc_cp_info_id,
cpd_id=cpd_id)
return vnfc_cp_info
def get_virtual_storage_resource_info_for_grant(desc_id="VirtualStorage"):
storage_resource_info = objects.VirtualStorageResourceInfo(
id=uuidsentinel.storage_id_1,
virtual_storage_desc_id=desc_id)
return storage_resource_info
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

View File

@ -2472,6 +2472,7 @@ class TestOpenStack(base.FixturedTestCase):
vnf_info['attributes']['SP1_res.yaml'] = utils.\
get_dummy_scale_nest_grant_hot()
self.openstack.get_grant_resource(
self,
vnf_instance,
vnf_info,
scale_vnf_request,
@ -2547,6 +2548,7 @@ class TestOpenStack(base.FixturedTestCase):
res_list.append(resource4)
mock_list.return_value = res_list
self.openstack.get_grant_resource(
self,
vnf_instance,
vnf_info,
scale_vnf_request,
@ -3031,3 +3033,221 @@ class TestOpenStack(base.FixturedTestCase):
vnf_instance.instantiated_vnf_info.
vnf_virtual_link_resource_info[0].vnf_link_ports[0].
resource_handle.resource_id)
@mock.patch.object(hc.HeatClient, "resource_get")
@mock.patch.object(hc.HeatClient, "resource_get_list")
def test_scale_resource_update_scale_out_with_grant(
self, mock_list, mock_resource):
inst_vnf_info = fd_utils.get_vnf_instantiated_info()
vnf_instance = fd_utils.get_vnf_instance_object(
instantiated_vnf_info=inst_vnf_info)
scale_vnf_request = objects.ScaleVnfRequest(type='SCALE_OUT',
aspect_id='worker_instance',
number_of_steps=1)
vim_connection_info = fd_utils.get_vim_connection_info_object()
vnf_info = {}
v_s_resource_info = fd_utils.\
get_virtual_storage_resource_info_for_grant(desc_id="storage1")
storage_resource_ids = [v_s_resource_info.id]
vnfc_resource_info = fd_utils.get_vnfc_resource_info_with_vnf_info(
vdu_id="workerNode", storage_resource_ids=storage_resource_ids)
vnfc_resource_info_list = []
vnfc_resource_info_list.append(vnfc_resource_info)
virtual_st_rsc_list = []
virtual_st_rsc_list.append(v_s_resource_info)
vnf_info['scale_out_vnfc_res_info_list'] = vnfc_resource_info_list
vnf_info['scale_out_virtual_st_rsc_list'] = virtual_st_rsc_list
resource = resources.Resource(None, {
'resource_name': 'worker_instance',
'creation_time': '2020-01-01T00:00:00',
'resource_status': 'CREATE_COMPLETE',
'physical_resource_id': '30435eb8-1472-4cbc-abbe-00b395165ce7',
'id': '1111'
})
resource1 = resources.Resource(None, {
'resource_name': 'workerNode',
'creation_time': '2020-01-01T00:00:00',
'resource_status': 'CREATE_COMPLETE',
'physical_resource_id': '30435eb8-1472-4cbc-abbe-00b395165ce7',
'id': '1111',
'attributes': {'key': 'value'}
})
resource_cp = resources.Resource(None, {
'resource_name': 'workerNode_CP2',
'creation_time': '2020-01-01T00:00:00',
'resource_status': 'CREATE_COMPLETE',
'physical_resource_id': '30435eb8-1472-4cbc-abbe-00b395165ce7',
'id': '1111',
'required_by': 'workerNode',
'attributes': {'fixed_ips': [{'ip_address': '10.10.0.2'}]}
})
resource_st = resources.Resource(None, {
'resource_name': 'storage1',
'creation_time': '2020-01-01T00:00:00',
'resource_status': 'CREATE_COMPLETE',
'physical_resource_id': '30435eb8-1472-4cbc-abbe-00b395165ce7',
'id': '1111',
'required_by': 'workerNode'
})
mock_resource.side_effect = [resource, resource1, resource_cp,
resource_st]
res_list1 = []
res_list2 = []
resource2 = resources.Resource(None, {
'resource_name': 'aaaaaaaa',
'creation_time': '2020-01-01T00:00:00',
'resource_status': 'CREATE_COMPLETE',
'physical_resource_id': '89bd4a61-d33c-cbdd-0329-6429a6083139',
'id': '1111'
})
res_list1.append(resource2)
resource3 = resources.Resource(None, {
'resource_name': 'workerNode',
'creation_time': '2020-01-01T00:00:00',
'resource_type': 'OS::Nova::Server',
'resource_status': 'CREATE_COMPLETE',
'physical_resource_id': '5a169308-7865-9296-5a4b-a39c743dbe6e',
'id': '1111'
})
res_list2.append(resource3)
resource4 = resources.Resource(None, {
'resource_name': 'workerNode_CP2',
'creation_time': '2020-01-01T00:00:00',
'resource_type': 'OS::Neutron::Port',
'resource_status': 'CREATE_COMPLETE',
'physical_resource_id': '5a169308-7865-9296-5a4b-a39c743dbe6e',
'id': '1111'
})
res_list2.append(resource4)
resource5 = resources.Resource(None, {
'resource_name': 'storage1',
'creation_time': '2020-01-01T00:00:00',
'resource_type': 'OS::Cinder::Volume',
'resource_status': 'CREATE_COMPLETE',
'physical_resource_id': '5a169308-7865-9296-5a4b-a39c743dbe6e',
'id': '1111'
})
res_list2.append(resource5)
mock_list.side_effect = [res_list1, res_list2]
self.openstack.scale_resource_update(
context, vnf_instance,
scale_vnf_request, vnf_info,
vim_connection_info)
self.assertEqual(
vnf_instance.instantiated_vnf_info.vnfc_resource_info[0].id,
uuidsentinel.vnfc_resource_id)
return_vnfc_res = \
vnf_instance.instantiated_vnf_info.vnfc_resource_info[0]
self.assertEqual(return_vnfc_res.vnfc_cp_info[0].id,
uuidsentinel.vnfc_cp_info_id)
self.assertEqual(uuidsentinel.storage_id_1,
vnf_instance.instantiated_vnf_info.
virtual_storage_resource_info[0].id)
@mock.patch.object(hc.HeatClient, "resource_get")
@mock.patch.object(hc.HeatClient, "resource_get_list")
def test_scale_resource_update_scale_out(self, mock_list, mock_resource):
inst_vnf_info = fd_utils.get_vnf_instantiated_info()
vnf_instance = fd_utils.get_vnf_instance_object(
instantiated_vnf_info=inst_vnf_info)
scale_vnf_request = objects.ScaleVnfRequest(type='SCALE_OUT',
aspect_id='worker_instance',
number_of_steps=1)
vim_connection_info = fd_utils.get_vim_connection_info_object()
v_s_resource_info = fd_utils. \
get_virtual_storage_resource_info(desc_id="storage1")
storage_resource_ids = [v_s_resource_info.id]
vnfc_resource_info = fd_utils.get_vnfc_resource_info_with_vnf_info(
vdu_id="workerNode", storage_resource_ids=storage_resource_ids)
vnfc_resource_info_list = []
vnfc_resource_info_list.append(vnfc_resource_info)
virtual_st_rsc_list = []
virtual_st_rsc_list.append(v_s_resource_info)
vnf_info = {'grant': 'test'}
resource = resources.Resource(None, {
'resource_name': 'worker_instance',
'creation_time': '2020-01-01T00:00:00',
'resource_status': 'CREATE_COMPLETE',
'physical_resource_id': '30435eb8-1472-4cbc-abbe-00b395165ce7',
'id': '1111'
})
resource1 = resources.Resource(None, {
'resource_name': 'workerNode',
'creation_time': '2020-01-01T00:00:00',
'resource_status': 'CREATE_COMPLETE',
'physical_resource_id': '30435eb8-1472-4cbc-abbe-00b395165ce7',
'id': '1111',
'attributes': {'key': 'value'}
})
resource_cp = resources.Resource(None, {
'resource_name': 'workerNode_CP2',
'creation_time': '2020-01-01T00:00:00',
'resource_status': 'CREATE_COMPLETE',
'physical_resource_id': '30435eb8-1472-4cbc-abbe-00b395165ce7',
'id': '1111',
'required_by': 'workerNode',
'attributes': {'fixed_ips': [{'ip_address': '10.10.0.2'}]}
})
resource_st = resources.Resource(None, {
'resource_name': 'storage1',
'creation_time': '2020-01-01T00:00:00',
'resource_status': 'CREATE_COMPLETE',
'physical_resource_id': '30435eb8-1472-4cbc-abbe-00b395165ce7',
'id': '1111',
'required_by': 'workerNode'
})
mock_resource.side_effect = [resource, resource1, resource_cp,
resource_st]
res_list1 = []
res_list2 = []
resource2 = resources.Resource(None, {
'resource_name': 'aaaaaaaa',
'creation_time': '2020-01-01T00:00:00',
'resource_status': 'CREATE_COMPLETE',
'physical_resource_id': '89bd4a61-d33c-cbdd-0329-6429a6083139',
'id': '1111'
})
res_list1.append(resource2)
resource3 = resources.Resource(None, {
'resource_name': 'workerNode',
'creation_time': '2020-01-01T00:00:00',
'resource_type': 'OS::Nova::Server',
'resource_status': 'CREATE_COMPLETE',
'physical_resource_id': '5a169308-7865-9296-5a4b-a39c743dbe6e',
'id': '1111'
})
res_list2.append(resource3)
resource4 = resources.Resource(None, {
'resource_name': 'workerNode_CP2',
'creation_time': '2020-01-01T00:00:00',
'resource_type': 'OS::Neutron::Port',
'resource_status': 'CREATE_COMPLETE',
'physical_resource_id': '5a169308-7865-9296-5a4b-a39c743dbe6e',
'id': '1111'
})
res_list2.append(resource4)
resource5 = resources.Resource(None, {
'resource_name': 'storage1',
'creation_time': '2020-01-01T00:00:00',
'resource_type': 'OS::Cinder::Volume',
'resource_status': 'CREATE_COMPLETE',
'physical_resource_id': '5a169308-7865-9296-5a4b-a39c743dbe6e',
'id': '1111'
})
res_list2.append(resource5)
mock_list.side_effect = [res_list1, res_list2]
self.openstack.scale_resource_update(
context, vnf_instance,
scale_vnf_request, vnf_info,
vim_connection_info)
self.assertNotEqual(
vnf_instance.instantiated_vnf_info.vnfc_resource_info[0].id,
uuidsentinel.vnfc_resource_id)
return_vnfc_res = \
vnf_instance.instantiated_vnf_info.vnfc_resource_info[0]
self.assertNotEqual(return_vnfc_res.vnfc_cp_info[0].id,
uuidsentinel.vnfc_cp_info_id)
self.assertNotEqual(uuidsentinel.storage_id,
vnf_instance.instantiated_vnf_info.
virtual_storage_resource_info[0].id)

View File

@ -443,6 +443,13 @@ class VnfLcmDriver(abstract_driver.VnfInstanceAbstractDriver):
id=vnf_instance.id,
error=encodeutils.exception_to_unicode(exp))
if vnf_instance.instantiated_vnf_info.instance_id:
self._vnf_manager.invoke(vim_connection_info.vim_type,
'post_vnf_instantiation', context=context,
vnf_instance=vnf_instance,
vim_connection_info=vim_connection_info,
instantiate_vnf_req=instantiate_vnf_req)
def _get_file_hash(self, path):
hash_obj = hashlib.sha256()
with open(path) as f:
@ -746,6 +753,10 @@ class VnfLcmDriver(abstract_driver.VnfInstanceAbstractDriver):
vnf_instance.task_state = fields.VnfInstanceTaskState.INSTANTIATING
vnfd_dict = vnflcm_utils._get_vnfd_dict(
context, vnf_instance.vnfd_id, instantiate_vnf_request.flavour_id)
if vnf_dict.get('vnf_instance_after'):
vnf_instance.instantiated_vnf_info = \
vnf_dict.get('vnf_instance_after').instantiated_vnf_info
else:
vnflcm_utils._build_instantiated_vnf_info(
vnfd_dict, instantiate_vnf_request, vnf_instance,
vim_connection_info.vim_id)
@ -1022,6 +1033,7 @@ class VnfLcmDriver(abstract_driver.VnfInstanceAbstractDriver):
'scale_resource_update',
context=context,
vnf_instance=vnf_instance,
vnf_info=vnf_info,
scale_vnf_request=scale_vnf_request,
vim_connection_info=vim_connection_info
)

View File

@ -2069,7 +2069,7 @@ class Kubernetes(abstract_driver.VnfAbstractDriver,
return return_id_list, return_name_list, return_grp_id, return_res_num
def scale_resource_update(self, context, vnf_instance,
scale_vnf_request,
scale_vnf_request, vnf_info,
vim_connection_info):
"""Update VnfcResourceInfo after scaling"""
auth_attr = vim_connection_info.access_info
@ -2238,6 +2238,7 @@ class Kubernetes(abstract_driver.VnfAbstractDriver,
pass
def get_grant_resource(self,
plugin,
vnf_instance,
vnf_info,
scale_vnf_request,

View File

@ -1577,13 +1577,37 @@ class OpenStack(abstract_driver.VnfAbstractDriver,
return return_list, return_rs_list, grp.physical_resource_id, cap_size
def _get_resource_info_from_grant(self, grant_res_info_list, rsc,
vnfc_resource=None):
for i in range(len(grant_res_info_list) - 1, -1, -1):
if rsc.resource_type == 'OS::Nova::Server':
if grant_res_info_list[i].vdu_id == rsc.resource_name:
instantiated_info = grant_res_info_list.pop(i)
break
elif rsc.resource_type == 'OS::Neutron::Port':
if grant_res_info_list[i].cpd_id == rsc.resource_name:
instantiated_info = \
vnfc_resource.vnfc_cp_info.pop(i)
break
elif rsc.resource_type == 'OS::Cinder::Volume':
if grant_res_info_list[i].virtual_storage_desc_id ==\
rsc.resource_name:
instantiated_info = grant_res_info_list.pop(i)
break
return instantiated_info
@log.log
def scale_resource_update(self, context, vnf_instance,
scale_vnf_request,
scale_vnf_request, vnf_info,
vim_connection_info):
inst_vnf_info = vnf_instance.instantiated_vnf_info
vnfc_rsc_list = []
st_rsc_list = []
grant_vnfc_res_info_list = \
vnf_info.get('scale_out_vnfc_res_info_list', {})
grant_st_rsc_list = vnf_info.get(
'scale_out_virtual_st_rsc_list', {})
for vnfc in vnf_instance.instantiated_vnf_info.vnfc_resource_info:
vnfc_rsc_list.append(vnfc.compute_resource.resource_id)
for st in vnf_instance.instantiated_vnf_info.\
@ -1613,10 +1637,20 @@ class OpenStack(abstract_driver.VnfAbstractDriver,
LOG.debug("rsc %s", rsc_info)
if 'COMPLETE' in rsc.resource_status and '\
INIT_COMPLETE' != rsc.resource_status:
vnfc_resource_info = objects.VnfcResourceInfo()
if grant_vnfc_res_info_list:
vnfc_resource_info = \
self._get_resource_info_from_grant(
grant_vnfc_res_info_list, rsc)
else:
vnfc_resource_info = \
objects.VnfcResourceInfo()
vnfc_resource_info.id =\
uuidutils.generate_uuid()
vnfc_resource_info.vdu_id = rsc.resource_name
vnfc_resource_info.vdu_id = \
rsc.resource_name
vnfc_resource_info.vnfc_cp_info = []
vnfc_resource_info.\
storage_resource_ids = []
resource = objects.ResourceHandle()
resource.vim_connection_id =\
vim_connection_info.id
@ -1628,12 +1662,10 @@ class OpenStack(abstract_driver.VnfAbstractDriver,
vnfc_resource_info.metadata.update(
{"stack_id":
scale_rsc.physical_resource_id})
vnfc_resource_info.vnfc_cp_info = []
volumes_attached = rsc_info.attributes.get(
'os-extended-volumes:volumes_attached')
if not volumes_attached:
volumes_attached = []
vnfc_resource_info.storage_resource_ids = []
for vol in volumes_attached:
vnfc_resource_info.\
storage_resource_ids.\
@ -1652,6 +1684,13 @@ class OpenStack(abstract_driver.VnfAbstractDriver,
LOG.debug("rsc %s", rsc_info)
for vnfc_rsc in vnfc_rscs:
if vnfc_rsc.vdu_id in rsc_info.required_by:
if vnfc_rsc.vnfc_cp_info and \
grant_vnfc_res_info_list:
vnfc_cp = self.\
_get_resource_info_from_grant(
vnfc_rsc.vnfc_cp_info,
rsc, vnfc_rsc)
else:
vnfc_cp = objects.VnfcCpInfo()
vnfc_cp.id = uuidutils.generate_uuid()
vnfc_cp.cpd_id = rsc.resource_name
@ -1722,12 +1761,18 @@ class OpenStack(abstract_driver.VnfAbstractDriver,
vnfc_rsc.vnfc_cp_info.append(vnfc_cp)
if rsc.resource_type == 'OS::Cinder::Volume':
if rsc.physical_resource_id not in st_rsc_list:
if grant_st_rsc_list:
virtual_storage_resource_info = \
self._get_resource_info_from_grant(
grant_st_rsc_list, rsc)
else:
virtual_storage_resource_info =\
objects.VirtualStorageResourceInfo()
virtual_storage_resource_info.id =\
uuidutils.generate_uuid()
virtual_storage_resource_info.\
virtual_storage_desc_id = rsc.resource_name
virtual_storage_desc_id = \
rsc.resource_name
resource = objects.ResourceHandle()
resource.vim_connection_id =\
vim_connection_info.id
@ -1902,6 +1947,7 @@ class OpenStack(abstract_driver.VnfAbstractDriver,
def get_grant_resource(
self,
plugin,
vnf_instance,
vnf_info,
scale_vnf_request,
@ -1927,23 +1973,34 @@ class OpenStack(abstract_driver.VnfAbstractDriver,
affinity_list = []
placement_constraint_list = []
uuid_list = []
port_uuid_list = []
storage_uuid_list = []
vnfc_res_info_list = []
virtual_st_rsc_list = []
heat_template = vnf_info['attributes']['heat_template']
heat_resource = yaml.safe_load(heat_template)
key_vnfd = scale_vnf_request.aspect_id + '_scale_out'
ajust_prop = heat_resource['resources'][key_vnfd]['properties']
ajust = ajust_prop['scaling_adjustment']
size = ajust * scale_vnf_request.number_of_steps
yaml_name = scale_vnf_request.aspect_id + '_res.yaml'
if not vnf_info['attributes'].get(yaml_name):
yaml_name = scale_vnf_request.aspect_id + '.hot.yaml'
scale_resource_name = scale_vnf_request.aspect_id
scale_resource = heat_resource['resources'].\
get(scale_resource_name, {})
if not scale_resource:
scale_resource_name = scale_vnf_request.aspect_id
scale_resource = heat_resource['resources'].\
get(scale_resource_name)
yaml_name = scale_resource['properties']['resource']['type']
nested_hot = yaml.safe_load(
vnf_info['attributes'][yaml_name])
for resource_name, resource in nested_hot['resources'].items():
if resource['type'] == NOVA_SERVER_RESOURCE:
for i in range(size):
add_uuid = uuidutils.generate_uuid()
vnfc_resource_info = objects.VnfcResourceInfo()
vnfc_resource_info.id = uuidutils.generate_uuid()
vnfc_resource_info.vdu_id = resource_name
vnfc_resource_info.vnfc_cp_info = []
vnfc_resource_info.storage_resource_ids = []
add_uuid = vnfc_resource_info.id
rsc = objects.ResourceDefinition(
id=add_uuid,
type=constants.TYPE_COMPUTE,
@ -1951,8 +2008,14 @@ class OpenStack(abstract_driver.VnfAbstractDriver,
resource_template_id=resource_name)
add_resources.append(rsc)
uuid_list.append(add_uuid)
for net in resource.get('networks', []):
add_uuid = uuidutils.generate_uuid()
for net in resource['properties'].get('networks', []):
vnfc_cp = objects.VnfcCpInfo()
vnfc_cp.id = uuidutils.generate_uuid()
vnfc_cp.cpd_id = net['port']['get_resource']
vnfc_resource_info.vnfc_cp_info.append(vnfc_cp)
add_uuid = vnfc_cp.id
port_rsc = net['port']['get_resource']
rsc = objects.ResourceDefinition(
id=add_uuid,
@ -1960,12 +2023,24 @@ class OpenStack(abstract_driver.VnfAbstractDriver,
vdu_id=resource_name,
resource_template_id=port_rsc)
add_resources.append(rsc)
port_uuid_list.append(add_uuid)
if resource['properties'].get('block_device_mapping_v2'):
for i in range(size):
for cinder in resource['properties'].get(
'block_device_mapping_v2', []):
add_uuid = uuidutils.generate_uuid()
virtual_storage_resource_info = \
objects.VirtualStorageResourceInfo()
virtual_storage_resource_info.id = \
uuidutils.generate_uuid()
virtual_storage_resource_info.\
virtual_storage_desc_id = \
cinder['volume_id']['get_resource']
virtual_st_rsc_list = \
virtual_st_rsc_list.append(
virtual_storage_resource_info)
vnfc_resource_info.storage_resource_ids.\
append(virtual_storage_resource_info.id)
add_uuid = virtual_storage_resource_info.id
vol_rsc = cinder['volume_id']['get_resource']
rsc = objects.ResourceDefinition(
id=add_uuid,
@ -1973,7 +2048,8 @@ class OpenStack(abstract_driver.VnfAbstractDriver,
vdu_id=resource_name,
resource_template_id=vol_rsc)
add_resources.append(rsc)
storage_uuid_list.append(add_uuid)
vnfc_res_info_list.append(vnfc_resource_info)
if resource['properties'].get('scheduler_hints'):
sch_hint = resource['properties']['scheduler_hints']
if sch_hint['group'].get('get_param'):
@ -2000,10 +2076,8 @@ class OpenStack(abstract_driver.VnfAbstractDriver,
vdu_id=vol_rsc['get_resource'],
resource_template_id=resource_name)
add_resources.append(rsc)
storage_uuid_list.append(add_uuid)
vnf_info['uuid_list'] = uuid_list
vnf_info['port_uuid_list'] = port_uuid_list
vnf_info['storage_uuid_list'] = storage_uuid_list
vnf_info['scale_out_vnfc_res_info_list'] = vnfc_res_info_list
vnf_info['scale_out_virtual_st_rsc_list'] = virtual_st_rsc_list
for placement in placement_obj_list:
if placement.server_group_name in affinity_list:
plm = jsonutils.loads(placement.resource)
@ -2015,8 +2089,10 @@ class OpenStack(abstract_driver.VnfAbstractDriver,
id_type=pl['id_type'],
resource_id=pl['resource_id'],
vim_connection_id=vim_id))
affinity_or_anti_affinity = \
placement.affinity_or_anti_affinity
placement_constraint = objects.PlacementConstraint(
affinity_or_anti_affinity='ANTI_AFFINITY',
affinity_or_anti_affinity=affinity_or_anti_affinity,
scope='ZONE',
resource=addRsc,
fallback_best_effort=True)

View File

@ -61,7 +61,7 @@ class VnfScaleAbstractDriver(extensions.PluginInterface,
@abc.abstractmethod
def scale_resource_update(self, context, vnf_instance,
scale_vnf_request,
scale_vnf_request, vnf_info,
vim_connection_info):
pass
@ -103,6 +103,7 @@ class VnfScaleAbstractDriver(extensions.PluginInterface,
@abc.abstractmethod
def get_grant_resource(self,
plugin,
vnf_instance,
vnf_info,
scale_vnf_request,