2274c780be
"flavour_description" and other properties for top-level VNFD should be updated in instantiation. Otherwise, it may fail with the default of "" (empty string). This patch fixes the issue for updating the properties in instantiation and adds a UT case for vnflcm.utils. Change-Id: I7f2a36cd67eeea5497adc4d38efffd0230e90ec9 Closes-Bug: #1882869
771 lines
28 KiB
Python
771 lines
28 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 io
|
|
import os
|
|
import six
|
|
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 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
|
|
else:
|
|
vim_id = None
|
|
region_name = None
|
|
|
|
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})
|
|
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']}
|
|
|
|
return vim_info
|
|
|
|
|
|
def _get_vnfd_dict(context, vnfd_id, flavour_id):
|
|
vnf_package_id = _get_vnf_package_id(context, vnfd_id)
|
|
vnf_package_base_path = cfg.CONF.vnf_package.vnf_package_csar_path
|
|
vnf_package_csar_path = vnf_package_base_path + '/' + vnf_package_id
|
|
vnfd_dict = _get_flavour_based_vnfd(vnf_package_csar_path, flavour_id)
|
|
|
|
# Remove requirements from substitution mapping
|
|
vnfd_dict.get('topology_template').get(
|
|
'substitution_mappings').pop('requirements')
|
|
return vnfd_dict
|
|
|
|
|
|
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 = cfg.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, six.string_types):
|
|
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):
|
|
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(tuple(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(tuple(ext)):
|
|
file_data = yaml.safe_load(io.open(src_path))
|
|
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:
|
|
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)
|
|
|
|
vim_connection_obj_list.append(vim_conn)
|
|
|
|
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
|
|
inst_vnf_info.ext_cp_info = _set_ext_cp_info(instantiate_vnf_req)
|
|
inst_vnf_info.ext_virtual_link_info = _set_ext_virtual_link_info(
|
|
instantiate_vnf_req, inst_vnf_info.ext_cp_info)
|
|
|
|
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
|
|
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)
|
|
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
|
|
# 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
|
|
# 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
|
|
# 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 _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):
|
|
ext_cp_info_list = []
|
|
|
|
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))
|
|
|
|
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 _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=(False if ip_address.fixed_addresses else True),
|
|
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
|
|
|
|
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 _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'
|
|
|
|
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 = {}
|
|
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)
|
|
|
|
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
|
|
for 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):
|
|
vnf_package_id = _get_vnf_package_id(context, vnfd_id)
|
|
vnf_package_base_path = cfg.CONF.vnf_package.vnf_package_csar_path
|
|
vnf_package_path = vnf_package_base_path + '/' + vnf_package_id
|
|
return vnf_package_path
|
|
|
|
|
|
def _get_base_hot_dict(context, vnfd_id):
|
|
vnf_package_id = _get_vnf_package_id(context, vnfd_id)
|
|
vnf_package_base_path = cfg.CONF.vnf_package.vnf_package_csar_path
|
|
vnf_package_csar_path = vnf_package_base_path + '/' + vnf_package_id
|
|
base_hot_dir = 'BaseHOT'
|
|
ext = [".yaml", ".yml"]
|
|
|
|
base_hot_path = vnf_package_csar_path + '/' + base_hot_dir
|
|
base_hot_dict = None
|
|
if os.path.exists(base_hot_path):
|
|
for file in os.listdir(base_hot_path):
|
|
if file.endswith(tuple(ext)):
|
|
source_file_path = os.path.join(base_hot_path, file)
|
|
base_hot_dict = yaml.safe_load(open(source_file_path))
|
|
LOG.debug("Loaded base hot: %s", base_hot_dict)
|
|
return base_hot_dict
|