b3bf4ec2ce
This patch provides a sample script that allows users to install or delete kubernetes on VMs in the VNF when executing instantiate/terminate/scale/heal through the kubespray ansible server. It also provides script to install and configure Load Balancer for kubernetes cluster in the VNF. When instantiating CNF with service resource whose type is `NodePort` on Kubernetes VIM deployed by kubespray, its port must be added into Load Balancer's configuration and restart it. So this patch also provides a sample MgmtDriver and shell script to fix this problem. At the same time, we found that if instantiate operation fails, after the `instantiate_end` operation, the `terminate_end` operation will not be executed in the rollback, which may cause the modification in `instantiate_end` remains in the environment, so this patch adds a `terminate_end` operation in `post_rollback_vnf`. Implements: blueprint k8s-mgmtdriver-kubespray Change-Id: I45661b5d8006e87db5f46a595756231849723ce6
1388 lines
53 KiB
Python
1388 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'],
|
|
'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
|