1389 lines
53 KiB
Python
1389 lines
53 KiB
Python
# Copyright (C) 2020 NTT DATA
|
|
# All Rights Reserved.
|
|
#
|
|
# 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 copy
|
|
import os
|
|
import yaml
|
|
|
|
from oslo_config import cfg
|
|
from oslo_log import log as logging
|
|
from oslo_utils import uuidutils
|
|
from toscaparser import tosca_template
|
|
|
|
from tacker.common import exceptions
|
|
from tacker.common import utils
|
|
from tacker.extensions import nfvo
|
|
from tacker import objects
|
|
from tacker.objects import fields
|
|
from tacker.tosca import utils as toscautils
|
|
from tacker.vnfm.lcm_user_data import utils as userdata_utils
|
|
from tacker.vnfm import vim_client
|
|
|
|
LOG = logging.getLogger(__name__)
|
|
CONF = cfg.CONF
|
|
|
|
|
|
def _get_vim(context, vim_connection_info):
|
|
vim_client_obj = vim_client.VimClient()
|
|
|
|
if vim_connection_info:
|
|
vim_id = vim_connection_info[0].vim_id
|
|
access_info = vim_connection_info[0].access_info
|
|
if access_info:
|
|
region_name = access_info.get('region')
|
|
else:
|
|
region_name = None
|
|
extra = vim_connection_info[0].extra
|
|
else:
|
|
vim_id = None
|
|
region_name = None
|
|
extra = {}
|
|
|
|
try:
|
|
vim_res = vim_client_obj.get_vim(
|
|
context, vim_id, region_name=region_name)
|
|
except nfvo.VimNotFoundException:
|
|
raise exceptions.VimConnectionNotFound(vim_id=vim_id)
|
|
|
|
vim_res['vim_auth'].update({'region': region_name})
|
|
if extra:
|
|
for key, value in extra.items():
|
|
vim_res['extra'][key] = value
|
|
vim_info = {'id': vim_res['vim_id'], 'vim_id': vim_res['vim_id'],
|
|
'vim_type': vim_res['vim_type'],
|
|
'access_info': vim_res['vim_auth'],
|
|
'tenant_id': vim_res['tenant'],
|
|
'extra': vim_res.get('extra', {})}
|
|
|
|
return vim_info
|
|
|
|
|
|
def _get_vnfd_dict(context, vnfd_id, flavour_id):
|
|
vnfd_dict = _get_flavour_based_vnfd(
|
|
_get_vnf_package_path(context, vnfd_id), flavour_id)
|
|
|
|
# Remove requirements from substitution mapping
|
|
vnfd_dict.get('topology_template').get(
|
|
'substitution_mappings').pop('requirements')
|
|
return vnfd_dict
|
|
|
|
|
|
def get_vnfd_dict(context, vnfd_id, flavour_id):
|
|
return _get_vnfd_dict(context, vnfd_id, flavour_id)
|
|
|
|
|
|
def _get_vnflcm_interface(context, interface, vnf_instance, flavour_id):
|
|
'''Gets the interface found in vnfd
|
|
|
|
...
|
|
node_templates:
|
|
VNF:
|
|
interfaces:
|
|
Vnflcm:
|
|
<interface>
|
|
'''
|
|
interface_value = None
|
|
vnfd_dict = _get_vnfd_dict(context, vnf_instance.vnfd_id, flavour_id)
|
|
|
|
if not isinstance(vnfd_dict, dict):
|
|
raise exceptions.InvalidContentType(msg="VNFD not valid")
|
|
|
|
if vnfd_dict.get('topology_template'):
|
|
topology_template = vnfd_dict.get('topology_template')
|
|
if topology_template.get('node_templates'):
|
|
node_templates = topology_template.get('node_templates')
|
|
if node_templates.get('VNF'):
|
|
vnf = node_templates.get('VNF')
|
|
if vnf.get('interfaces'):
|
|
interfaces = vnf.get('interfaces')
|
|
if interfaces.get('Vnflcm'):
|
|
vnflcm = interfaces.get('Vnflcm')
|
|
if vnflcm:
|
|
interface_value = vnflcm.get(interface)
|
|
|
|
return interface_value
|
|
|
|
|
|
def _build_affected_resources(vnf_instance,
|
|
change_type=fields.ResourceChangeType.ADDED):
|
|
'''build affected resources from vnf_instance instantiated info '''
|
|
|
|
affected_resources = {}
|
|
instantiated_vnf_info = vnf_instance.instantiated_vnf_info
|
|
if hasattr(instantiated_vnf_info, 'instance_id'):
|
|
if instantiated_vnf_info.instance_id:
|
|
|
|
affected_resources['affectedVnfcs'] = []
|
|
affected_resources['affectedVirtualLinks'] = []
|
|
affected_resources['affectedVirtualStorages'] = []
|
|
|
|
# build AffectedVnfc
|
|
vnfc_resource_info = \
|
|
instantiated_vnf_info.vnfc_resource_info
|
|
for vnfc_resource in vnfc_resource_info:
|
|
data = {}
|
|
data['id'] = vnfc_resource.id
|
|
data['vduId'] = vnfc_resource.vdu_id
|
|
data['changeType'] = change_type
|
|
data['computeResource'] = \
|
|
vnfc_resource.compute_resource.to_dict()
|
|
data['metadata'] = vnfc_resource.metadata
|
|
affected_resources['affectedVnfcs'].append(data)
|
|
|
|
# build AffectedVirtualLink
|
|
vnf_virtual_link = \
|
|
instantiated_vnf_info.vnf_virtual_link_resource_info
|
|
for vnf_vl_info in vnf_virtual_link:
|
|
data = {}
|
|
data['id'] = vnf_vl_info.id
|
|
data['vnfVirtualLinkDescId'] = \
|
|
vnf_vl_info.vnf_virtual_link_desc_id
|
|
data['changeType'] = change_type
|
|
data['networkResource'] = \
|
|
vnf_vl_info.network_resource.to_dict()
|
|
data['metadata'] = {}
|
|
affected_resources['affectedVirtualLinks'].append(data)
|
|
|
|
# build affectedVirtualStorages
|
|
virtual_storage = \
|
|
instantiated_vnf_info.virtual_storage_resource_info
|
|
for vnf_storage_info in virtual_storage:
|
|
data = {}
|
|
data['id'] = vnf_storage_info.id
|
|
data['virtualStorageDescId'] = \
|
|
vnf_storage_info.virtual_storage_desc_id
|
|
data['changeType'] = change_type
|
|
data['storageResource'] = \
|
|
vnf_storage_info.storage_resource.to_dict()
|
|
data['metadata'] = {}
|
|
affected_resources['affectedVirtualStorages'].append(data)
|
|
|
|
return utils.convert_snakecase_to_camelcase(affected_resources)
|
|
|
|
|
|
def _get_affected_resources(old_vnf_instance=None,
|
|
new_vnf_instance=None, extra_list=None):
|
|
'''get_affected_resources
|
|
|
|
returns affected resources in new_vnf_instance not present
|
|
in old_vnf_instance.
|
|
if extra_list (list of physical resource ids) is present,
|
|
included to affected resources
|
|
'''
|
|
def _get_affected_cpids(affected_vnfc, vnf_instance):
|
|
affected_cpids = []
|
|
instantiated_vnf_info = vnf_instance.instantiated_vnf_info
|
|
for vnfc_resource in instantiated_vnf_info.vnfc_resource_info:
|
|
if vnfc_resource.id == affected_vnfc['id']:
|
|
for vnfc_cp in vnfc_resource.vnfc_cp_info:
|
|
if vnfc_cp.cpd_id:
|
|
affected_cpids.append(vnfc_cp.cpd_id)
|
|
if vnfc_cp.vnf_ext_cp_id:
|
|
affected_cpids.append(vnfc_cp.vnf_ext_cp_id)
|
|
return affected_cpids
|
|
|
|
def _get_added_storageids(affected_vnfc, vnf_instance):
|
|
affected_storage_ids = []
|
|
instantiated_vnf_info = vnf_instance.instantiated_vnf_info
|
|
for vnfc_resource in instantiated_vnf_info.vnfc_resource_info:
|
|
if vnfc_resource.id == affected_vnfc['id']:
|
|
for storage_resource_id in vnfc_resource.storage_resource_ids:
|
|
virtual_storage = \
|
|
instantiated_vnf_info.virtual_storage_resource_info
|
|
for virt_storage_res_info in virtual_storage:
|
|
if virt_storage_res_info.id == storage_resource_id:
|
|
affected_storage_ids.append(
|
|
virt_storage_res_info.virtual_storage_desc_id)
|
|
return affected_storage_ids
|
|
|
|
def diff_list(old_list, new_list):
|
|
diff = []
|
|
for item in new_list:
|
|
if item not in old_list:
|
|
diff.append(item)
|
|
return diff
|
|
|
|
affected_resources = {}
|
|
affected_resources['affectedVnfcs'] = []
|
|
affected_resources['affectedVirtualLinks'] = []
|
|
affected_resources['affectedVirtualStorages'] = []
|
|
|
|
if not old_vnf_instance:
|
|
affected_resources = _build_affected_resources(
|
|
new_vnf_instance, fields.ResourceChangeType.ADDED)
|
|
# add affected cpids and add added storageids
|
|
for affected_vnfc in affected_resources['affectedVnfcs']:
|
|
affected_vnfc['affectedVnfcCpIds'] = _get_affected_cpids(
|
|
affected_vnfc, new_vnf_instance)
|
|
affected_vnfc['addedStorageResourceIds'] = _get_added_storageids(
|
|
affected_vnfc, new_vnf_instance)
|
|
|
|
elif not new_vnf_instance:
|
|
affected_resources = _build_affected_resources(old_vnf_instance,
|
|
fields.ResourceChangeType.REMOVED)
|
|
# add affected cpids and add remove storageids
|
|
for affected_vnfc in affected_resources['affectedVnfcs']:
|
|
affected_vnfc['affectedVnfcCpIds'] = _get_affected_cpids(
|
|
affected_vnfc, old_vnf_instance)
|
|
affected_vnfc['removedStorageResourceIds'] = _get_added_storageids(
|
|
affected_vnfc, old_vnf_instance)
|
|
elif old_vnf_instance and new_vnf_instance:
|
|
old_affected_resources = _build_affected_resources(old_vnf_instance)
|
|
new_affected_resources = _build_affected_resources(new_vnf_instance,
|
|
fields.ResourceChangeType.MODIFIED)
|
|
|
|
# get resource_ids
|
|
old_vnfc_resource_ids = []
|
|
for vnfc_resource in old_affected_resources.get('affectedVnfcs', []):
|
|
old_vnfc_resource_ids.append(
|
|
vnfc_resource['computeResource']['resourceId'])
|
|
|
|
# remove extra_list items in old_vnfc_resource_ids
|
|
# so that this items will be considered new
|
|
if extra_list:
|
|
for item in extra_list:
|
|
if item in old_vnfc_resource_ids:
|
|
index = old_vnfc_resource_ids.index(item)
|
|
old_vnfc_resource_ids.pop(index)
|
|
|
|
new_vnfc_resource_ids = []
|
|
for vnfc_resource in new_affected_resources.get('affectedVnfcs', []):
|
|
resource_id = vnfc_resource['computeResource']['resourceId']
|
|
new_vnfc_resource_ids.append(resource_id)
|
|
|
|
old_vnf_vl_resource_ids = []
|
|
for vnf_vl_info in old_affected_resources.get(
|
|
'affectedVirtualLinks', []):
|
|
resource_id = vnf_vl_info['networkResource']['resourceId']
|
|
old_vnf_vl_resource_ids.append(resource_id)
|
|
|
|
new_vnf_vl_resource_ids = []
|
|
for vnf_vl_info in new_affected_resources.get(
|
|
'affectedVirtualLinks', []):
|
|
resource_id = vnf_vl_info['networkResource']['resourceId']
|
|
new_vnf_vl_resource_ids.append(resource_id)
|
|
|
|
old_vnf_storage_resource_ids = []
|
|
for vnf_storage_info in old_affected_resources.get(
|
|
'affectedVirtualStorages', []):
|
|
resource_id = vnf_storage_info['storageResource']['resourceId']
|
|
old_vnf_storage_resource_ids.append(resource_id)
|
|
|
|
new_vnf_storage_resource_ids = []
|
|
for vnf_storage_info in new_affected_resources.get(
|
|
'affectedVirtualStorages', []):
|
|
resource_id = vnf_storage_info['storageResource']['resourceId']
|
|
new_vnf_storage_resource_ids.append(resource_id)
|
|
|
|
# get difference between resource_ids
|
|
vnfc_resource_ids = diff_list(old_vnfc_resource_ids,
|
|
new_vnfc_resource_ids)
|
|
vnf_vl_resource_ids = diff_list(old_vnf_vl_resource_ids,
|
|
new_vnf_vl_resource_ids)
|
|
vnf_storage_resource_ids = diff_list(old_vnf_storage_resource_ids,
|
|
new_vnf_storage_resource_ids)
|
|
|
|
# return new affected resources
|
|
for affected_vls in new_affected_resources['affectedVirtualLinks']:
|
|
if (affected_vls['networkResource']
|
|
['resourceId'] in vnf_vl_resource_ids):
|
|
affected_resources['affectedVirtualLinks'].append(affected_vls)
|
|
|
|
affected_storages = new_affected_resources['affectedVirtualStorages']
|
|
for affected_storage in affected_storages:
|
|
if (affected_storage['storageResource']
|
|
['resourceId'] in vnf_storage_resource_ids):
|
|
affected_resources['affectedVirtualStorages'].append(
|
|
affected_storage)
|
|
|
|
for affected_vnfc in new_affected_resources['affectedVnfcs']:
|
|
if (affected_vnfc['computeResource']
|
|
['resourceId'] in vnfc_resource_ids):
|
|
|
|
# update affected affectedVnfcCpIds
|
|
affected_vnfc['affectedVnfcCpIds'] = _get_affected_cpids(
|
|
affected_vnfc, new_vnf_instance)
|
|
|
|
affected_resources['affectedVnfcs'].append(affected_vnfc)
|
|
|
|
return affected_resources
|
|
|
|
|
|
def _get_vnf_package_id(context, vnfd_id):
|
|
vnf_package = objects.VnfPackageVnfd.get_by_id(context, vnfd_id)
|
|
return vnf_package.package_uuid
|
|
|
|
|
|
def _create_grant_request(vnfd_dict, package_uuid):
|
|
node_templates = vnfd_dict.get('topology_template',
|
|
{}).get('node_templates', {})
|
|
vnf_software_images = {}
|
|
if not node_templates:
|
|
return vnf_software_images
|
|
|
|
def _build_vnf_software_image(sw_image_data, artifact_image_path):
|
|
vnf_sw_image = objects.VnfSoftwareImage()
|
|
vnf_sw_image.image_path = artifact_image_path
|
|
vnf_sw_image.name = sw_image_data.get('name')
|
|
vnf_sw_image.version = sw_image_data.get('version')
|
|
if sw_image_data.get('checksum'):
|
|
checksum = sw_image_data.get('checksum')
|
|
if checksum.get('algorithm'):
|
|
vnf_sw_image.algorithm = checksum.get('algorithm')
|
|
if checksum.get('hash'):
|
|
vnf_sw_image.hash = checksum.get('hash')
|
|
|
|
vnf_sw_image.container_format = sw_image_data.get(
|
|
'container_format')
|
|
vnf_sw_image.disk_format = sw_image_data.get('disk_format')
|
|
if sw_image_data.get('min_disk'):
|
|
min_disk = utils.MemoryUnit.convert_unit_size_to_num(
|
|
sw_image_data.get('min_disk'), 'GB')
|
|
vnf_sw_image.min_disk = min_disk
|
|
else:
|
|
vnf_sw_image.min_disk = 0
|
|
|
|
if sw_image_data.get('min_ram'):
|
|
min_ram = utils.MemoryUnit.convert_unit_size_to_num(
|
|
sw_image_data.get('min_ram'), 'MB')
|
|
vnf_sw_image.min_ram = min_ram
|
|
else:
|
|
vnf_sw_image.min_ram = 0
|
|
|
|
return vnf_sw_image
|
|
|
|
def _get_image_path(artifact_image_path, package_uuid):
|
|
vnf_package_path = CONF.vnf_package.vnf_package_csar_path
|
|
artifact_image_path = os.path.join(
|
|
vnf_package_path, package_uuid,
|
|
artifact_image_path.split('../')[-1])
|
|
return artifact_image_path
|
|
|
|
for node, value in node_templates.items():
|
|
if not value.get(
|
|
'type') in ['tosca.nodes.nfv.Vdu.Compute',
|
|
'tosca.nodes.nfv.Vdu.VirtualBlockStorage']:
|
|
continue
|
|
|
|
sw_image_data = value.get('properties', {}).get('sw_image_data')
|
|
artifacts = value.get('artifacts', {})
|
|
for artifact, sw_image in artifacts.items():
|
|
artifact_image_path = None
|
|
if isinstance(sw_image, str):
|
|
artifact_image_path = sw_image
|
|
elif sw_image.get('type') == 'tosca.artifacts.nfv.SwImage':
|
|
artifact_image_path = sw_image.get('file', {})
|
|
if sw_image_data and artifact_image_path:
|
|
is_url = utils.is_url(artifact_image_path)
|
|
if not is_url:
|
|
artifact_image_path = _get_image_path(artifact_image_path,
|
|
package_uuid)
|
|
|
|
vnf_software_image = _build_vnf_software_image(
|
|
sw_image_data, artifact_image_path)
|
|
vnf_software_images[node] = vnf_software_image
|
|
break
|
|
|
|
return vnf_software_images
|
|
|
|
|
|
def _make_final_vnf_dict(vnfd_dict, id, name, param_values, vnf_dict=None):
|
|
if vnf_dict:
|
|
final_vnf_dict = vnf_dict
|
|
final_vnf_dict['vnfd']['attributes'].\
|
|
update({'vnfd': str(vnfd_dict)})
|
|
final_vnf_dict['attributes'].\
|
|
update({'param_values': str(param_values)})
|
|
final_vnf_dict['attributes'].\
|
|
update({'stack_name': name or ("vnflcm_" + id)})
|
|
return final_vnf_dict
|
|
else:
|
|
return {'vnfd': {
|
|
'attributes': {
|
|
'vnfd': str(vnfd_dict)}},
|
|
'id': id,
|
|
'name': name,
|
|
'attributes': {
|
|
'param_values': str(param_values),
|
|
'stack_name': name or ("vnflcm_" + id)}}
|
|
|
|
|
|
def _get_flavour_based_vnfd(csar_path, flavour_id):
|
|
ext = (".yaml", ".yml")
|
|
file_path_and_data = {}
|
|
imp_list = []
|
|
for item in os.listdir(csar_path):
|
|
src_path = os.path.join(csar_path, item)
|
|
if os.path.isdir(src_path):
|
|
for file in os.listdir(src_path):
|
|
if file.endswith(ext):
|
|
source_file_path = os.path.join(src_path, file)
|
|
with open(source_file_path) as file_obj:
|
|
data = yaml.safe_load(file_obj)
|
|
substitution_map = data.get(
|
|
'topology_template',
|
|
{}).get('substitution_mappings', {})
|
|
if substitution_map.get(
|
|
'properties', {}).get('flavour_id') == flavour_id:
|
|
if data.get('imports'):
|
|
for imp in data.get('imports'):
|
|
imp_path = os.path.join(src_path, imp)
|
|
imp_list.append(imp_path)
|
|
data.update({'imports': imp_list})
|
|
|
|
return data
|
|
|
|
elif src_path.endswith(ext):
|
|
with open(src_path) as file_obj:
|
|
file_data = yaml.safe_load(file_obj)
|
|
substitution_map = file_data.get(
|
|
'topology_template', {}).get('substitution_mappings', {})
|
|
if substitution_map.get(
|
|
'properties', {}).get('flavour_id') == flavour_id:
|
|
if file_data.get('imports'):
|
|
for imp in file_data.get('imports'):
|
|
imp_list.append(os.path.join(src_path, imp))
|
|
file_data.update({'imports': imp_list})
|
|
return file_data
|
|
|
|
return file_path_and_data
|
|
|
|
|
|
def _get_param_data(vnfd_dict, instantiate_vnf_req):
|
|
param_value = {}
|
|
additional_param = instantiate_vnf_req.additional_params
|
|
if additional_param is None:
|
|
additional_param = {}
|
|
substitution_map = vnfd_dict.get('topology_template',
|
|
{}).get('substitution_mappings', {})
|
|
input_attributes = vnfd_dict.get('topology_template', {}).get('inputs')
|
|
if substitution_map is not None:
|
|
subs_map_node_type = substitution_map.get('node_type')
|
|
# Get properties in lower-level VNFD for top-level VNFD
|
|
node_templates = vnfd_dict.get('topology_template',
|
|
{}).get('node_templates', {})
|
|
for node in node_templates.values():
|
|
if node.get('type') == subs_map_node_type:
|
|
node_property = node.get('properties', {})
|
|
if node_property:
|
|
param_value.update(node_property)
|
|
# Import `_type.yaml` file and get default properties.
|
|
# If new value provided in additional_param, the property is updated.
|
|
import_paths = vnfd_dict.get('imports', {})
|
|
for imp_path in import_paths:
|
|
with open(imp_path) as file_obj:
|
|
import_data = yaml.safe_load(file_obj)
|
|
imp_node_type = import_data.get('node_types')
|
|
if imp_node_type:
|
|
for key, value in imp_node_type.items():
|
|
if key == subs_map_node_type:
|
|
properties = value.get('properties')
|
|
if properties:
|
|
for key, prop in properties.items():
|
|
if additional_param.get(key):
|
|
param_value.update({
|
|
key: additional_param.get(key)})
|
|
# If the parameter is provided in lower-level
|
|
# VNFD, use it. Otherwise use the default.
|
|
elif not param_value.get(key):
|
|
param_value.update(
|
|
{key: prop.get('default')})
|
|
|
|
for input_attr, value in input_attributes.items():
|
|
if additional_param.get(input_attr):
|
|
param_value.update({input_attr: additional_param.get(
|
|
input_attr)})
|
|
|
|
return param_value
|
|
|
|
|
|
def _get_vim_connection_info_from_vnf_req(vnf_instance, instantiate_vnf_req):
|
|
vim_connection_obj_list = []
|
|
|
|
if not instantiate_vnf_req.vim_connection_info:
|
|
# add default vim
|
|
if len(vnf_instance.vim_connection_info):
|
|
vim_connection_obj_list.append(vnf_instance.vim_connection_info[0])
|
|
|
|
return vim_connection_obj_list
|
|
|
|
for vim_connection in instantiate_vnf_req.vim_connection_info:
|
|
vim_conn = objects.VimConnectionInfo(id=vim_connection.id,
|
|
vim_id=vim_connection.vim_id, vim_type=vim_connection.vim_type,
|
|
access_info=vim_connection.access_info,
|
|
interface_info=vim_connection.interface_info)
|
|
|
|
vim_connection_obj_list.append(vim_conn)
|
|
|
|
# add default vim
|
|
if len(vnf_instance.vim_connection_info):
|
|
if vim_conn.id and vnf_instance.vim_connection_info[0].id:
|
|
is_default_vim_exist = [vim_conn for vim_conn
|
|
in vim_connection_obj_list
|
|
if vim_conn.id == vnf_instance.vim_connection_info[0].id]
|
|
if not len(is_default_vim_exist):
|
|
vim_connection_obj_list.append(vnf_instance.
|
|
vim_connection_info[0])
|
|
|
|
return vim_connection_obj_list
|
|
|
|
|
|
def _build_instantiated_vnf_info(vnfd_dict, instantiate_vnf_req,
|
|
vnf_instance, vim_id):
|
|
inst_vnf_info = vnf_instance.instantiated_vnf_info
|
|
inst_vnf_info.vnf_state = fields.VnfOperationalStateType.STARTED
|
|
|
|
node_templates = vnfd_dict.get(
|
|
'topology_template', {}).get('node_templates')
|
|
|
|
vnfc_resource_info, virtual_storage_resource_info = \
|
|
_get_vnfc_resource_info(vnfd_dict, instantiate_vnf_req, vim_id)
|
|
|
|
inst_vnf_info.vnfc_resource_info = vnfc_resource_info
|
|
|
|
tmp_insta_vnf_info = copy.deepcopy(inst_vnf_info)
|
|
inst_vnf_info.ext_cp_info = _set_ext_cp_info(instantiate_vnf_req,
|
|
inst_vnf_info=tmp_insta_vnf_info)
|
|
inst_vnf_info.ext_virtual_link_info = _set_ext_virtual_link_info(
|
|
instantiate_vnf_req, inst_vnf_info.ext_cp_info)
|
|
|
|
inst_vnf_info.virtual_storage_resource_info = \
|
|
virtual_storage_resource_info
|
|
inst_vnf_info.vnf_virtual_link_resource_info = \
|
|
_build_vnf_virtual_link_resource_info(
|
|
node_templates, instantiate_vnf_req,
|
|
inst_vnf_info.vnfc_resource_info, vim_id)
|
|
|
|
inst_vnf_info.ext_managed_virtual_link_info = \
|
|
_build_ext_managed_virtual_link_info(instantiate_vnf_req,
|
|
inst_vnf_info)
|
|
|
|
inst_vnf_info.additional_params = instantiate_vnf_req.additional_params
|
|
|
|
vnf_instance.instantiated_vnf_info = inst_vnf_info
|
|
|
|
|
|
def _update_instantiated_vnf_info(change_ext_conn_req, vnf_instance):
|
|
inst_vnf_info = vnf_instance.instantiated_vnf_info
|
|
tmp_insta_vnf_info = copy.deepcopy(inst_vnf_info)
|
|
|
|
inst_vnf_info.ext_cp_info = _update_ext_cp_info(change_ext_conn_req,
|
|
inst_vnf_info=tmp_insta_vnf_info)
|
|
inst_vnf_info.ext_virtual_link_info = _update_ext_virtual_link_info(
|
|
change_ext_conn_req, inst_vnf_info=tmp_insta_vnf_info)
|
|
|
|
inst_vnf_info.vnf_virtual_link_resource_info = \
|
|
_update_vnf_virtual_link_resource_info(change_ext_conn_req,
|
|
inst_vnf_info)
|
|
|
|
vnf_instance.instantiated_vnf_info = inst_vnf_info
|
|
|
|
|
|
def _get_compute_nodes(vnfd_dict, instantiate_vnf_req):
|
|
"""Read the node templates and prepare VDU data in below format
|
|
|
|
{
|
|
'VDU1': {
|
|
'CP': [CP1, CP2],
|
|
'VIRTUAL_STORAGE': [virtual_storage1]
|
|
},
|
|
}
|
|
"""
|
|
|
|
node_templates = vnfd_dict.get(
|
|
'topology_template', {}).get('node_templates')
|
|
|
|
vdu_resources = {}
|
|
for key, value in node_templates.items():
|
|
if value.get('type') != 'tosca.nodes.nfv.Vdu.Compute':
|
|
continue
|
|
|
|
desired_capacity = _convert_desired_capacity(
|
|
instantiate_vnf_req.instantiation_level_id, vnfd_dict, key)
|
|
|
|
cp_list = _get_cp_for_vdu(key, node_templates)
|
|
|
|
virtual_storages = []
|
|
requirements = value.get('requirements', [])
|
|
for requirement in requirements:
|
|
if requirement.get('virtual_storage'):
|
|
virtual_storages.append(
|
|
requirement.get('virtual_storage'))
|
|
|
|
vdu_resources[key] = {"CP": cp_list,
|
|
"VIRTUAL_STORAGE": virtual_storages,
|
|
"COUNT": desired_capacity}
|
|
|
|
return vdu_resources
|
|
|
|
|
|
def _get_virtual_link_nodes(node_templates):
|
|
virtual_link_nodes = {}
|
|
|
|
for key, value in node_templates.items():
|
|
if value.get('type') == 'tosca.nodes.nfv.VnfVirtualLink':
|
|
cp_list = _get_cp_for_vl(key, node_templates)
|
|
virtual_link_nodes[key] = cp_list
|
|
|
|
return virtual_link_nodes
|
|
|
|
|
|
def _get_cp_for_vdu(vdu, node_templates):
|
|
cp_list = []
|
|
for key, value in node_templates.items():
|
|
if value.get('type') != 'tosca.nodes.nfv.VduCp':
|
|
continue
|
|
|
|
requirements = value.get('requirements', [])
|
|
for requirement in requirements:
|
|
if requirement.get('virtual_binding') and vdu == \
|
|
requirement.get('virtual_binding'):
|
|
cp_list.append(key)
|
|
|
|
return cp_list
|
|
|
|
|
|
def _get_cp_for_vl(vl, node_templates):
|
|
cp_list = []
|
|
for key, value in node_templates.items():
|
|
if value.get('type') != 'tosca.nodes.nfv.VduCp':
|
|
continue
|
|
|
|
requirements = value.get('requirements', [])
|
|
for requirement in requirements:
|
|
if requirement.get('virtual_link') and vl == \
|
|
requirement.get('virtual_link'):
|
|
cp_list.append(key)
|
|
|
|
return cp_list
|
|
|
|
|
|
def _build_vnf_virtual_link_resource_info(node_templates, instantiate_vnf_req,
|
|
vnfc_resource_info, vim_id):
|
|
virtual_link_nodes_with_cp = _get_virtual_link_nodes(node_templates)
|
|
|
|
# Read the external networks and extcps from InstantiateVnfRequest
|
|
for ext_virt_link in instantiate_vnf_req.ext_virtual_links:
|
|
virtual_link_nodes_with_cp[ext_virt_link.id] = [extcp.cpd_id for extcp
|
|
in ext_virt_link.ext_cps]
|
|
|
|
virtual_link_resource_info_list = []
|
|
|
|
def _get_network_resource(vl_node):
|
|
resource_handle = objects.ResourceHandle()
|
|
found = False
|
|
for ext_mg_vl in instantiate_vnf_req.ext_managed_virtual_links:
|
|
if ext_mg_vl.vnf_virtual_link_desc_id == vl_node:
|
|
resource_handle.resource_id = ext_mg_vl.resource_id
|
|
resource_handle.vim_connection_id = \
|
|
ext_mg_vl.vim_connection_id
|
|
# TODO(tpatil): This cannot be set here.
|
|
resource_handle.vim_level_resource_type = \
|
|
'OS::Neutron::Net'
|
|
found = True
|
|
break
|
|
|
|
if not found:
|
|
# check if it exists in the ext_virtual_links
|
|
for ext_virt_link in instantiate_vnf_req.ext_virtual_links:
|
|
if ext_virt_link.id == vl_node:
|
|
resource_handle.resource_id = ext_virt_link.resource_id
|
|
resource_handle.vim_connection_id = \
|
|
ext_virt_link.vim_connection_id
|
|
# TODO(tpatil): This cannot be set here.
|
|
resource_handle.vim_level_resource_type = \
|
|
'OS::Neutron::Net'
|
|
found = True
|
|
break
|
|
|
|
return resource_handle
|
|
|
|
def _get_vnf_link_port_info(cp):
|
|
vnf_link_port_info = objects.VnfLinkPortInfo()
|
|
vnf_link_port_info.id = uuidutils.generate_uuid()
|
|
|
|
resource_handle = objects.ResourceHandle()
|
|
for ext_virt_link in instantiate_vnf_req.ext_virtual_links:
|
|
for extcp in ext_virt_link.ext_cps:
|
|
if extcp.cpd_id == cp:
|
|
for cpconfig in extcp.cp_config:
|
|
if cpconfig.link_port_id:
|
|
resource_handle.resource_id = \
|
|
cpconfig.link_port_id
|
|
resource_handle.vim_connection_id = \
|
|
ext_virt_link.vim_connection_id
|
|
# TODO(tpatil): This shouldn't be set here.
|
|
resource_handle.vim_level_resource_type = \
|
|
'OS::Neutron::Port'
|
|
break
|
|
|
|
vnf_link_port_info.resource_handle = resource_handle
|
|
|
|
return vnf_link_port_info
|
|
|
|
for node, cp_list in virtual_link_nodes_with_cp.items():
|
|
vnf_vl_resource_info = objects.VnfVirtualLinkResourceInfo()
|
|
vnf_vl_resource_info.id = uuidutils.generate_uuid()
|
|
vnf_vl_resource_info.vnf_virtual_link_desc_id = node
|
|
vnf_vl_resource_info.network_resource = _get_network_resource(node)
|
|
|
|
vnf_link_port_info_list = []
|
|
for cp in cp_list:
|
|
for vnfc_resource in vnfc_resource_info:
|
|
for vnfc_cp in vnfc_resource.vnfc_cp_info:
|
|
if vnfc_cp.cpd_id == cp:
|
|
vnf_link_port_info = _get_vnf_link_port_info(cp)
|
|
vnf_link_port_info.cp_instance_id = vnfc_cp.id
|
|
# Identifier of the "vnfLinkPorts" structure in the
|
|
# "vnfVirtualLinkResourceInfo" structure.
|
|
vnfc_cp.vnf_link_port_id = vnf_link_port_info.id
|
|
vnf_link_port_info_list.append(vnf_link_port_info)
|
|
|
|
vnf_vl_resource_info.vnf_link_ports = vnf_link_port_info_list
|
|
|
|
virtual_link_resource_info_list.append(vnf_vl_resource_info)
|
|
|
|
return virtual_link_resource_info_list
|
|
|
|
|
|
def _update_vnf_virtual_link_resource_info(change_ext_conn_req,
|
|
inst_vnf_info):
|
|
def _update(change_ext_conn_req, vnf_vl_resource_info):
|
|
for ext_virtual_link in change_ext_conn_req.ext_virtual_links:
|
|
if (ext_virtual_link.id ==
|
|
vnf_vl_resource_info.vnf_virtual_link_desc_id):
|
|
res_handle = objects.ResourceHandle()
|
|
res_handle.resource_id = ext_virtual_link.resource_id
|
|
nw_res = vnf_vl_resource_info.network_resource
|
|
res_handle.vim_connection_id = nw_res.vim_connection_id
|
|
res_handle.vim_level_resource_type = \
|
|
nw_res.vim_level_resource_type
|
|
new_vnf_vl_resource_info = \
|
|
objects.VnfVirtualLinkResourceInfo(
|
|
id=vnf_vl_resource_info.id,
|
|
vnf_virtual_link_desc_id=vnf_vl_resource_info.
|
|
vnf_virtual_link_desc_id,
|
|
network_resource=res_handle,
|
|
vnf_link_ports=vnf_vl_resource_info.vnf_link_ports)
|
|
return new_vnf_vl_resource_info
|
|
return None
|
|
|
|
vnf_virtual_link_resource_list = []
|
|
for vnf_vl_res_info in inst_vnf_info.vnf_virtual_link_resource_info:
|
|
updated_vnf_vl_res_info = \
|
|
_update(change_ext_conn_req, vnf_vl_res_info)
|
|
if updated_vnf_vl_res_info:
|
|
vnf_virtual_link_resource_list.append(updated_vnf_vl_res_info)
|
|
else:
|
|
vnf_virtual_link_resource_list.append(vnf_vl_res_info)
|
|
|
|
return vnf_virtual_link_resource_list
|
|
|
|
|
|
def _build_vnf_cp_info(instantiate_vnf_req, cp_list):
|
|
vnfc_cp_info_list = []
|
|
|
|
if not cp_list:
|
|
return vnfc_cp_info_list
|
|
|
|
def _set_vnf_exp_cp_id_protocol_data(vnfc_cp_info):
|
|
for ext_virt_link in instantiate_vnf_req.ext_virtual_links:
|
|
for extcp in ext_virt_link.ext_cps:
|
|
if extcp.cpd_id == cp:
|
|
vnfc_cp_info.cp_protocol_info = \
|
|
_set_cp_protocol_info(extcp)
|
|
for cpconfig in extcp.cp_config:
|
|
vnfc_cp_info.vnf_ext_cp_id = cpconfig.link_port_id
|
|
break
|
|
|
|
for cp in cp_list:
|
|
vnfc_cp_info = objects.VnfcCpInfo()
|
|
vnfc_cp_info.id = uuidutils.generate_uuid()
|
|
vnfc_cp_info.cpd_id = cp
|
|
_set_vnf_exp_cp_id_protocol_data(vnfc_cp_info)
|
|
vnfc_cp_info_list.append(vnfc_cp_info)
|
|
|
|
return vnfc_cp_info_list
|
|
|
|
|
|
def _build_virtual_storage_info(virtual_storages):
|
|
|
|
for storage_node in virtual_storages:
|
|
virtual_storage = objects.VirtualStorageResourceInfo()
|
|
virtual_storage.id = uuidutils.generate_uuid()
|
|
virtual_storage.virtual_storage_desc_id = storage_node
|
|
|
|
virtual_storage.storage_resource = objects.ResourceHandle()
|
|
|
|
yield virtual_storage
|
|
|
|
|
|
def _get_vnfc_resource_info(vnfd_dict, instantiate_vnf_req, vim_id):
|
|
vdu_resources = _get_compute_nodes(vnfd_dict, instantiate_vnf_req)
|
|
vnfc_resource_info_list = []
|
|
virtual_storage_resource_info_list = []
|
|
|
|
def _build_vnfc_resource_info(vdu, vdu_resource):
|
|
vnfc_resource_info = objects.VnfcResourceInfo()
|
|
vnfc_resource_info.id = uuidutils.generate_uuid()
|
|
vnfc_resource_info.vdu_id = vdu
|
|
|
|
vnfc_resource_info.compute_resource = objects.ResourceHandle()
|
|
|
|
vnfc_cp_info_list = _build_vnf_cp_info(instantiate_vnf_req,
|
|
vdu_resource.get("CP"))
|
|
vnfc_resource_info.vnfc_cp_info = vnfc_cp_info_list
|
|
|
|
virtual_storages = vdu_resource.get("VIRTUAL_STORAGE")
|
|
vdu_storages = []
|
|
for storage in _build_virtual_storage_info(virtual_storages):
|
|
vdu_storages.append(storage)
|
|
virtual_storage_resource_info_list.append(storage)
|
|
|
|
storage_resource_ids = [info.id for info in vdu_storages]
|
|
vnfc_resource_info.storage_resource_ids = storage_resource_ids
|
|
return vnfc_resource_info
|
|
|
|
for vdu, vdu_resource in vdu_resources.items():
|
|
count = vdu_resource.get('COUNT', 1)
|
|
for num_instance in range(count):
|
|
vnfc_resource_info = _build_vnfc_resource_info(vdu, vdu_resource)
|
|
vnfc_resource_info_list.append(vnfc_resource_info)
|
|
|
|
return vnfc_resource_info_list, virtual_storage_resource_info_list
|
|
|
|
|
|
def _set_ext_cp_info(instantiate_vnf_req, inst_vnf_info=None):
|
|
ext_cp_info_list = []
|
|
vnfc_info = []
|
|
|
|
if inst_vnf_info.vnfc_resource_info:
|
|
vnfc_info = inst_vnf_info.vnfc_resource_info
|
|
|
|
if not instantiate_vnf_req.ext_virtual_links:
|
|
return ext_cp_info_list
|
|
|
|
for ext_virt_link in instantiate_vnf_req.ext_virtual_links:
|
|
if not ext_virt_link.ext_cps:
|
|
continue
|
|
|
|
for ext_cp in ext_virt_link.ext_cps:
|
|
ext_cp_info = objects.VnfExtCpInfo(
|
|
id=uuidutils.generate_uuid(),
|
|
cpd_id=ext_cp.cpd_id,
|
|
cp_protocol_info=_set_cp_protocol_info(ext_cp),
|
|
ext_link_port_id=_get_ext_link_port_id(ext_virt_link,
|
|
ext_cp.cpd_id),
|
|
associated_vnfc_cp_id=_get_associated_vnfc_cp_id(vnfc_info,
|
|
ext_cp.cpd_id))
|
|
|
|
ext_cp_info_list.append(ext_cp_info)
|
|
|
|
return ext_cp_info_list
|
|
|
|
|
|
def _update_ext_cp_info(change_ext_conn_req, inst_vnf_info):
|
|
|
|
def _update(change_ext_conn_req, ext_cp_info):
|
|
for ext_virt_link in change_ext_conn_req.ext_virtual_links:
|
|
if not ext_virt_link.ext_cps:
|
|
continue
|
|
for ext_cp in ext_virt_link.ext_cps:
|
|
if ext_cp.cpd_id == ext_cp_info.cpd_id:
|
|
new_ext_cp_info = objects.VnfExtCpInfo(
|
|
id=ext_cp_info.id,
|
|
cpd_id=ext_cp.cpd_id,
|
|
cp_protocol_info=_set_cp_protocol_info(ext_cp),
|
|
associated_vnfc_cp_id=ext_cp_info.
|
|
associated_vnfc_cp_id)
|
|
return new_ext_cp_info
|
|
return None
|
|
|
|
ext_cp_info_list = []
|
|
for ext_cp_info in inst_vnf_info.ext_cp_info:
|
|
updated_ext_cp_info = _update(change_ext_conn_req, ext_cp_info)
|
|
if updated_ext_cp_info:
|
|
ext_cp_info_list.append(updated_ext_cp_info)
|
|
else:
|
|
ext_cp_info_list.append(ext_cp_info)
|
|
|
|
return ext_cp_info_list
|
|
|
|
|
|
def _get_ext_link_port_id(ext_virtual_link, cpd_id):
|
|
if not ext_virtual_link.ext_link_ports:
|
|
return
|
|
|
|
for ext_link in ext_virtual_link.ext_link_ports:
|
|
if ext_link.id == cpd_id:
|
|
return ext_link.id
|
|
|
|
|
|
def _get_associated_vnfc_cp_id(vnfc_info, cpd_id):
|
|
if not isinstance(vnfc_info, list):
|
|
return
|
|
|
|
for vnfc in vnfc_info:
|
|
if vnfc.vnfc_cp_info:
|
|
for cp_info in vnfc.vnfc_cp_info:
|
|
if cp_info.cpd_id == cpd_id:
|
|
return vnfc.id
|
|
|
|
|
|
def _build_ip_over_ethernet_address_info(cp_protocol_data):
|
|
"""Convert IpOverEthernetAddressData to IpOverEthernetAddressInfo"""
|
|
|
|
if not cp_protocol_data.ip_over_ethernet:
|
|
return
|
|
|
|
ip_over_ethernet_add_info = objects.IpOverEthernetAddressInfo()
|
|
ip_over_ethernet_add_info.mac_address = \
|
|
cp_protocol_data.ip_over_ethernet.mac_address
|
|
|
|
if not cp_protocol_data.ip_over_ethernet.ip_addresses:
|
|
return ip_over_ethernet_add_info
|
|
|
|
ip_address_list = []
|
|
for ip_address in cp_protocol_data.ip_over_ethernet.ip_addresses:
|
|
ip_address_info = objects.vnf_instantiated_info.IpAddress(
|
|
type=ip_address.type,
|
|
addresses=ip_address.fixed_addresses,
|
|
is_dynamic=True if ip_address.num_dynamic_addresses else False,
|
|
subnet_id=ip_address.subnet_id)
|
|
|
|
ip_address_list.append(ip_address_info)
|
|
|
|
ip_over_ethernet_add_info.ip_addresses = ip_address_list
|
|
|
|
return ip_over_ethernet_add_info
|
|
|
|
|
|
def _build_cp_protocol_info(cp_protocol_data):
|
|
ip_over_ethernet_add_info = _build_ip_over_ethernet_address_info(
|
|
cp_protocol_data)
|
|
cp_protocol_info = objects.CpProtocolInfo(
|
|
layer_protocol=cp_protocol_data.layer_protocol,
|
|
ip_over_ethernet=ip_over_ethernet_add_info)
|
|
|
|
return cp_protocol_info
|
|
|
|
|
|
def _set_cp_protocol_info(ext_cp):
|
|
"""Convert CpProtocolData to CpProtocolInfo"""
|
|
|
|
cp_protocol_info_list = []
|
|
if not ext_cp.cp_config:
|
|
return cp_protocol_info_list
|
|
|
|
for cp_config in ext_cp.cp_config:
|
|
for cp_protocol_data in cp_config.cp_protocol_data:
|
|
cp_protocol_info = _build_cp_protocol_info(cp_protocol_data)
|
|
cp_protocol_info_list.append(cp_protocol_info)
|
|
|
|
return cp_protocol_info_list
|
|
|
|
|
|
def _set_ext_virtual_link_info(instantiate_vnf_req, ext_cp_info):
|
|
ext_virtual_link_list = []
|
|
|
|
if not instantiate_vnf_req.ext_virtual_links:
|
|
return ext_virtual_link_list
|
|
|
|
for ext_virtual_link in instantiate_vnf_req.ext_virtual_links:
|
|
res_handle = objects.ResourceHandle()
|
|
res_handle.resource_id = ext_virtual_link.resource_id
|
|
res_handle.vim_connection_id = ext_virtual_link.vim_connection_id
|
|
|
|
ext_virtual_link_info = objects.ExtVirtualLinkInfo(
|
|
id=ext_virtual_link.id,
|
|
resource_handle=res_handle,
|
|
ext_link_ports=_set_ext_link_port(ext_virtual_link,
|
|
ext_cp_info))
|
|
|
|
ext_virtual_link_list.append(ext_virtual_link_info)
|
|
|
|
return ext_virtual_link_list
|
|
|
|
|
|
def _update_ext_virtual_link_info(change_ext_conn_req, inst_vnf_info):
|
|
|
|
def _update(change_ext_conn_req, ext_virtual_link_info):
|
|
for ext_virtual_link in change_ext_conn_req.ext_virtual_links:
|
|
if ext_virtual_link.id == ext_virtual_link_info.id:
|
|
res_handle = objects.ResourceHandle()
|
|
res_handle.resource_id = ext_virtual_link.resource_id
|
|
new_ext_virtual_link_info = objects.ExtVirtualLinkInfo(
|
|
id=ext_virtual_link_info.id,
|
|
resource_handle=res_handle,
|
|
ext_link_ports=ext_virtual_link_info.ext_link_ports)
|
|
res_handle.vim_connection_id = \
|
|
ext_virtual_link_info.resource_handle.vim_connection_id
|
|
new_ext_virtual_link_info = objects.ExtVirtualLinkInfo(
|
|
id=ext_virtual_link_info.id,
|
|
resource_handle=res_handle,
|
|
ext_link_ports=ext_virtual_link_info.ext_link_ports)
|
|
return new_ext_virtual_link_info
|
|
return None
|
|
|
|
ext_virtual_link_list = []
|
|
for ext_virtual_link_info in inst_vnf_info.ext_virtual_link_info:
|
|
updated_ext_virtual_link_info = \
|
|
_update(change_ext_conn_req, ext_virtual_link_info)
|
|
if updated_ext_virtual_link_info:
|
|
ext_virtual_link_list.append(updated_ext_virtual_link_info)
|
|
else:
|
|
ext_virtual_link_list.append(ext_virtual_link_info)
|
|
|
|
return ext_virtual_link_list
|
|
|
|
|
|
def _set_ext_link_port(ext_virtual_links, ext_cp_info):
|
|
ext_link_port_list = []
|
|
|
|
if not ext_virtual_links.ext_link_ports:
|
|
return ext_link_port_list
|
|
|
|
for ext_link_port in ext_virtual_links.ext_link_ports:
|
|
resource_handle = ext_link_port.resource_handle.obj_clone()
|
|
cp_instance_id = None
|
|
if ext_virtual_links.ext_cps:
|
|
for ext_cp in ext_cp_info:
|
|
cp_instance_id = ext_cp.id
|
|
|
|
ext_link_port_info = objects.ExtLinkPortInfo(id=ext_link_port.id,
|
|
resource_handle=resource_handle, cp_instance_id=cp_instance_id)
|
|
|
|
ext_link_port_list.append(ext_link_port_info)
|
|
|
|
return ext_link_port_list
|
|
|
|
|
|
def _build_ext_managed_virtual_link_info(instantiate_vnf_req, inst_vnf_info):
|
|
|
|
def _network_resource(ext_managed_vl):
|
|
resource_handle = objects.ResourceHandle(
|
|
resource_id=ext_managed_vl.resource_id)
|
|
# TODO(tpatil): Remove hard coding of resource type as
|
|
# OS::Neutron::Net resource type is specific to OpenStack infra
|
|
# driver. It could be different for other infra drivers like
|
|
# Kubernetes.
|
|
resource_handle.vim_level_resource_type = 'OS::Neutron::Net'
|
|
resource_handle.vim_connection_id = \
|
|
ext_managed_vl.vim_connection_id
|
|
|
|
return resource_handle
|
|
|
|
ext_managed_virtual_link_info = []
|
|
ext_managed_virt_link_from_req = \
|
|
instantiate_vnf_req.ext_managed_virtual_links
|
|
for ext_managed_vl in ext_managed_virt_link_from_req:
|
|
ext_managed_virt_info = objects.ExtManagedVirtualLinkInfo()
|
|
ext_managed_virt_info.id = ext_managed_vl.id
|
|
ext_managed_virt_info.vnf_virtual_link_desc_id =\
|
|
ext_managed_vl.vnf_virtual_link_desc_id
|
|
|
|
ext_managed_virt_info.network_resource =\
|
|
_network_resource(ext_managed_vl)
|
|
|
|
# Populate the vnf_link_ports from vnf_virtual_link_resource_info
|
|
# of instantiated_vnf_info.
|
|
for vnf_vl_res_info in inst_vnf_info.vnf_virtual_link_resource_info:
|
|
if ext_managed_vl.vnf_virtual_link_desc_id ==\
|
|
vnf_vl_res_info.vnf_virtual_link_desc_id:
|
|
vnf_link_ports = []
|
|
for vnf_lp in vnf_vl_res_info.vnf_link_ports:
|
|
vnf_link_ports.append(vnf_lp.obj_clone())
|
|
ext_managed_virt_info.vnf_link_ports = vnf_link_ports
|
|
|
|
ext_managed_virtual_link_info.append(ext_managed_virt_info)
|
|
return ext_managed_virtual_link_info
|
|
|
|
|
|
def _convert_desired_capacity(inst_level_id, vnfd_dict, vdu):
|
|
aspect_delta_dict = {}
|
|
aspect_vdu_dict = {}
|
|
inst_level_dict = {}
|
|
aspect_id_dict = {}
|
|
vdu_delta_dict = {}
|
|
aspect_max_level_dict = {}
|
|
desired_capacity = 1
|
|
|
|
tosca = tosca_template.ToscaTemplate(parsed_params={}, a_file=False,
|
|
yaml_dict_tpl=vnfd_dict)
|
|
tosca_policies = tosca.topology_template.policies
|
|
default_inst_level_id = toscautils._extract_policy_info(
|
|
tosca_policies, inst_level_dict,
|
|
aspect_delta_dict, aspect_id_dict,
|
|
aspect_vdu_dict, vdu_delta_dict,
|
|
aspect_max_level_dict)
|
|
|
|
if vdu_delta_dict.get(vdu) is None:
|
|
return desired_capacity
|
|
|
|
if inst_level_id:
|
|
instantiation_level = inst_level_id
|
|
elif default_inst_level_id:
|
|
instantiation_level = default_inst_level_id
|
|
else:
|
|
return desired_capacity
|
|
|
|
al_dict = inst_level_dict.get(instantiation_level)
|
|
|
|
if not al_dict:
|
|
return desired_capacity
|
|
|
|
for aspect_id, level_num in al_dict.items():
|
|
delta_id = aspect_id_dict.get(aspect_id)
|
|
|
|
if delta_id is not None:
|
|
delta_num = \
|
|
aspect_delta_dict.get(aspect_id).get(delta_id)
|
|
|
|
vdus = aspect_vdu_dict.get(aspect_id)
|
|
initial_delta = None
|
|
if vdu in vdus:
|
|
initial_delta = vdu_delta_dict.get(vdu)
|
|
|
|
if initial_delta is not None:
|
|
desired_capacity = initial_delta + delta_num * level_num
|
|
|
|
return desired_capacity
|
|
|
|
|
|
def _get_vnf_package_path(context, vnfd_id):
|
|
return os.path.join(CONF.vnf_package.vnf_package_csar_path,
|
|
_get_vnf_package_id(context, vnfd_id))
|
|
|
|
|
|
def get_base_nest_hot_dict(context, flavour_id, vnfd_id):
|
|
base_hot_path = os.path.join(_get_vnf_package_path(context, vnfd_id),
|
|
'BaseHOT', flavour_id)
|
|
nested_hot_path = os.path.join(base_hot_path, 'nested')
|
|
ext = (".yaml", ".yml")
|
|
|
|
base_hot_dict = None
|
|
nested_hot_dict = {}
|
|
if os.path.exists(base_hot_path):
|
|
for file in os.listdir(base_hot_path):
|
|
if file.endswith(ext):
|
|
with open(os.path.join(base_hot_path, file)) as file_obj:
|
|
base_hot_dict = yaml.safe_load(file_obj)
|
|
if os.path.exists(nested_hot_path):
|
|
for file in os.listdir(nested_hot_path):
|
|
if file.endswith(ext):
|
|
with open(os.path.join(nested_hot_path, file)) as file_obj:
|
|
nested_hot = yaml.safe_load(file_obj)
|
|
nested_hot_dict[file] = nested_hot
|
|
LOG.debug("Loaded base hot: %s", base_hot_dict)
|
|
LOG.debug("Loaded nested_hot_dict: %s", nested_hot_dict)
|
|
return base_hot_dict, nested_hot_dict
|
|
|
|
|
|
def get_extract_policy_infos(tosca):
|
|
aspect_delta_dict = {}
|
|
aspect_vdu_dict = {}
|
|
inst_level_dict = {}
|
|
aspect_id_dict = {}
|
|
vdu_delta_dict = {}
|
|
aspect_max_level_dict = {}
|
|
|
|
tosca_policies = tosca.topology_template.policies
|
|
default_inst_level_id = toscautils._extract_policy_info(
|
|
tosca_policies, inst_level_dict,
|
|
aspect_delta_dict, aspect_id_dict,
|
|
aspect_vdu_dict, vdu_delta_dict,
|
|
aspect_max_level_dict)
|
|
|
|
extract_policy_infos = dict()
|
|
extract_policy_infos['inst_level_dict'] = inst_level_dict
|
|
extract_policy_infos['aspect_delta_dict'] = aspect_delta_dict
|
|
extract_policy_infos['aspect_id_dict'] = aspect_id_dict
|
|
extract_policy_infos['aspect_vdu_dict'] = aspect_vdu_dict
|
|
extract_policy_infos['vdu_delta_dict'] = vdu_delta_dict
|
|
extract_policy_infos['aspect_max_level_dict'] = aspect_max_level_dict
|
|
extract_policy_infos['default_inst_level_id'] = default_inst_level_id
|
|
|
|
return extract_policy_infos
|
|
|
|
|
|
def get_scale_delta_num(extract_policy_infos, aspect_id):
|
|
delta_num = 1
|
|
|
|
if extract_policy_infos['aspect_id_dict'] is None:
|
|
return delta_num
|
|
delta_id = extract_policy_infos['aspect_id_dict'].get(aspect_id)
|
|
if delta_id is None:
|
|
return delta_num
|
|
delta_num = \
|
|
extract_policy_infos['aspect_delta_dict'].get(aspect_id).get(delta_id)
|
|
|
|
return delta_num
|
|
|
|
|
|
def get_default_scale_status(context, vnf_instance, vnfd_dict):
|
|
default_scale_status = None
|
|
|
|
vnfd_dict = _get_vnfd_dict(context,
|
|
vnf_instance.vnfd_id,
|
|
vnf_instance.instantiated_vnf_info.flavour_id)
|
|
tosca = tosca_template.ToscaTemplate(parsed_params={}, a_file=False,
|
|
yaml_dict_tpl=vnfd_dict)
|
|
extract_policy_infos = get_extract_policy_infos(tosca)
|
|
|
|
if extract_policy_infos['inst_level_dict'] is None:
|
|
return default_scale_status
|
|
default_inst_level_id = extract_policy_infos['default_inst_level_id']
|
|
default_al_dict = \
|
|
extract_policy_infos['inst_level_dict'].get(default_inst_level_id)
|
|
if default_al_dict is None:
|
|
return default_scale_status
|
|
default_scale_status = []
|
|
for aspect_id, level_num in default_al_dict.items():
|
|
default_scale_status.append(
|
|
objects.ScaleInfo(
|
|
aspect_id=aspect_id,
|
|
scale_level=level_num))
|
|
|
|
return default_scale_status
|
|
|
|
|
|
def get_target_vdu_def_dict(extract_policy_infos, aspect_id, tosca):
|
|
vdu_def_dict = {}
|
|
|
|
tosca_node_tpls = tosca.topology_template.nodetemplates
|
|
|
|
if extract_policy_infos['aspect_vdu_dict'] is None:
|
|
return vdu_def_dict
|
|
vdus = extract_policy_infos['aspect_vdu_dict'].get(aspect_id)
|
|
if vdus is None:
|
|
return vdu_def_dict
|
|
for nt in tosca_node_tpls:
|
|
for node_name, node_value in nt.templates.items():
|
|
if node_name in vdus:
|
|
vdu_def_dict[node_name] = node_value
|
|
|
|
return vdu_def_dict
|
|
|
|
|
|
def _get_changed_ext_connectivity(
|
|
old_vnf_instance=None, new_vnf_instance=None):
|
|
|
|
changed_ext_connectivities = []
|
|
if not old_vnf_instance or not new_vnf_instance:
|
|
return changed_ext_connectivities
|
|
|
|
old_vnf_vl_res_info = \
|
|
old_vnf_instance.instantiated_vnf_info.\
|
|
vnf_virtual_link_resource_info
|
|
new_vnf_vl_res_info = \
|
|
new_vnf_instance.instantiated_vnf_info.\
|
|
vnf_virtual_link_resource_info
|
|
|
|
def _compare_vnf_link_ports(old_vnf_link_ports,
|
|
new_vnf_link_ports):
|
|
differed_vnf_link_ports = []
|
|
for old_vnf_link_port in old_vnf_link_ports:
|
|
for new_vnf_link_port in new_vnf_link_ports:
|
|
if old_vnf_link_port.id == new_vnf_link_port.id:
|
|
if (old_vnf_link_port.resource_handle.resource_id !=
|
|
new_vnf_link_port.resource_handle.resource_id):
|
|
differed_vnf_link_ports.append(new_vnf_link_port)
|
|
return differed_vnf_link_ports
|
|
|
|
for old_vl_res in old_vnf_vl_res_info:
|
|
for new_vl_res in new_vnf_vl_res_info:
|
|
if old_vl_res.id == new_vl_res.id:
|
|
changed_ext_connectivity = objects.ExtVirtualLinkInfo(
|
|
id=new_vl_res.id,
|
|
resource_handle=new_vl_res.network_resource,
|
|
ext_link_ports=[])
|
|
differed_vnf_link_ports = _compare_vnf_link_ports(
|
|
old_vl_res.vnf_link_ports,
|
|
new_vl_res.vnf_link_ports)
|
|
for link_port in differed_vnf_link_ports:
|
|
changed_ext_link_port = objects.ExtLinkPortInfo(
|
|
id=link_port.id,
|
|
resource_handle=link_port.resource_handle,
|
|
cp_instance_id=link_port.cp_instance_id)
|
|
changed_ext_connectivity.ext_link_ports.\
|
|
append(changed_ext_link_port)
|
|
if changed_ext_connectivity.ext_link_ports:
|
|
changed_ext_connectivities.append(
|
|
changed_ext_connectivity)
|
|
|
|
LOG.debug('changed_ext_connectivities: {}'.format(
|
|
changed_ext_connectivities))
|
|
return changed_ext_connectivities
|
|
|
|
|
|
def get_stack_param(context, vnf_dict, heal_vnf_request, inst_vnf_info):
|
|
stack_param = {}
|
|
vnfc_resources = []
|
|
|
|
# get vnfc resources
|
|
if not heal_vnf_request.vnfc_instance_id:
|
|
# include all vnfc resources
|
|
vnfc_resources = [
|
|
resource for resource in inst_vnf_info.vnfc_resource_info]
|
|
else:
|
|
for vnfc_resource in inst_vnf_info.vnfc_resource_info:
|
|
if vnfc_resource.id in heal_vnf_request.vnfc_instance_id:
|
|
vnfc_resources.append(vnfc_resource)
|
|
|
|
def _update_stack_params(
|
|
context, base_hot_dict, nested_hot_dict, vnfd_dict):
|
|
param_base_hot_dict = copy.deepcopy(nested_hot_dict)
|
|
param_base_hot_dict['heat_template'] = base_hot_dict
|
|
|
|
initial_param_dict = (
|
|
userdata_utils.create_initial_param_server_port_dict(
|
|
param_base_hot_dict)
|
|
)
|
|
del initial_param_dict['nfv']['CP']
|
|
|
|
vdu_flavor_dict = (
|
|
userdata_utils.create_vdu_flavor_capability_name_dict(vnfd_dict)
|
|
)
|
|
vdu_image_dict = userdata_utils.create_sw_image_dict(vnfd_dict)
|
|
|
|
final_param_dict = userdata_utils.create_final_param_dict(
|
|
initial_param_dict, vdu_flavor_dict, vdu_image_dict, {})
|
|
|
|
return final_param_dict['nfv']['VDU']
|
|
|
|
# get HOT dict
|
|
base_hot_dict, nested_hot_dict = get_base_nest_hot_dict(
|
|
context, inst_vnf_info.flavour_id, vnf_dict['vnfd_id'])
|
|
|
|
vnfd_dict = yaml.safe_load(
|
|
vnf_dict['vnfd']['attributes']['vnfd_' + inst_vnf_info.flavour_id])
|
|
|
|
if 'stack_param' in vnf_dict['attributes'].keys():
|
|
stack_param = yaml.safe_load(
|
|
vnf_dict['attributes']['stack_param'])
|
|
|
|
updated_vdu_params = _update_stack_params(
|
|
context, base_hot_dict, nested_hot_dict, vnfd_dict)
|
|
|
|
for vnfc_resource in vnfc_resources:
|
|
vdu_id = vnfc_resource.vdu_id
|
|
if (updated_vdu_params.get(vdu_id) and
|
|
stack_param['nfv']['VDU'].get(vdu_id)):
|
|
stack_param['nfv']['VDU'].update({
|
|
vdu_id: updated_vdu_params.get(vdu_id)
|
|
})
|
|
|
|
return stack_param
|