Tacker: ETSI MANO NFV Orchestrator / VNF Manager. See https://wiki.openstack.org/wiki/Tacker
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

1764 lines
66 KiB

# 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.
from copy import deepcopy
import datetime
import iso8601
import json
import os
import webob
from tacker.api.vnflcm.v1.router import VnflcmAPIRouter
from tacker.common import utils
from tacker import context
from tacker.db.db_sqlalchemy import models
from tacker import objects
from tacker.objects.change_ext_conn_req import ChangeExtConnRequest
from tacker.objects import fields
from tacker.objects.instantiate_vnf_req import ExtManagedVirtualLinkData
from tacker.objects.instantiate_vnf_req import ExtVirtualLinkData
from tacker.objects.instantiate_vnf_req import InstantiateVnfRequest
from tacker.objects import scale_vnf_request
from tacker.objects.vim_connection import VimConnectionInfo
from tacker.tests import constants
from tacker.tests import uuidsentinel
from tacker import wsgi
import tacker.db.vnfm.vnfm_db
import tacker.conf
CONF = tacker.conf.CONF
def return_vnf_interfaces():
vnf_interface = 'vnflcm_noop'
return vnf_interface
def return_default_vim():
default_vim = {
'vim_auth': {
'username': 'user123',
'password': 'pass123'
},
'placement_attr': {
'region': 'RegionOne'
},
'tenant': uuidsentinel.tenant_uuid,
'vim_id': uuidsentinel.vim_uuid,
'vim_type': 'openstack'
}
return default_vim
def return_vim_connection_object(fields):
access_info = {
'username': fields.get('vim_auth', {}).
get('username'),
'password': fields.get('vim_auth', {}).
get('password'),
'region': fields.get('placement_attr', {}).
get('region'),
'tenant': fields.get('tenant')
}
vim_con_info = objects.\
VimConnectionInfo(id=fields.get('vim_id'),
vim_id=fields.get('vim_id'),
vim_type=fields.get('vim_type'),
access_info=access_info)
return vim_con_info
def fake_vnf_package_vnfd_model_dict(**updates):
vnfd = {
'package_uuid': uuidsentinel.package_uuid,
'deleted': False,
'deleted_at': None,
'updated_at': None,
'created_at': datetime.datetime(2020, 1, 1, 1, 1, 1,
tzinfo=iso8601.UTC),
'vnf_product_name': 'Sample VNF',
'vnf_provider': 'test vnf provider',
'vnf_software_version': '1.0',
'vnfd_id': uuidsentinel.vnfd_id,
'vnfd_version': '1.0',
'id': constants.UUID,
}
if updates:
vnfd.update(updates)
return vnfd
def return_vnf_package_vnfd():
model_obj = models.VnfPackageVnfd()
model_obj.update(fake_vnf_package_vnfd_model_dict())
return model_obj
def scale_request_make(type, number_of_steps):
scale_request_data = {
'type': type,
'aspect_id': "SP1",
'number_of_steps': number_of_steps,
'scale_level': 1,
'additional_params': {"test": "test_value"},
}
scale_request = scale_vnf_request.ScaleVnfRequest(**scale_request_data)
return scale_request
def _model_non_instantiated_vnf_instance(**updates):
vnf_instance = {
'created_at': datetime.datetime(2020, 1, 1, 1, 1, 1,
tzinfo=iso8601.UTC),
'deleted': False,
'deleted_at': None,
'id': uuidsentinel.vnf_instance_id,
'instantiated_vnf_info': None,
'instantiation_state': fields.VnfInstanceState.NOT_INSTANTIATED,
'updated_at': None,
'vim_connection_info': [],
'vnf_instance_description': 'Vnf instance description',
'vnf_instance_name': 'Vnf instance name',
'vnf_product_name': 'Sample VNF',
'vnf_provider': 'Vnf provider',
'vnf_software_version': '1.0',
'tenant_id': uuidsentinel.tenant_id,
'vnfd_id': uuidsentinel.vnfd_id,
'vnfd_version': '1.0',
'vnf_pkg_id': uuidsentinel.vnf_pkg_id,
'vnf_metadata': {"key": "value"}}
if updates:
vnf_instance.update(**updates)
return vnf_instance
def return_vnf_instance_model(
instantiated_state=fields.VnfInstanceState.NOT_INSTANTIATED,
**updates):
model_obj = models.VnfInstance()
if instantiated_state == fields.VnfInstanceState.NOT_INSTANTIATED:
model_obj.update(_model_non_instantiated_vnf_instance(**updates))
return model_obj
def return_vnf_instance(
instantiated_state=fields.VnfInstanceState.NOT_INSTANTIATED,
scale_status=None,
**updates):
if instantiated_state == fields.VnfInstanceState.NOT_INSTANTIATED:
data = _model_non_instantiated_vnf_instance(**updates)
data['instantiation_state'] = instantiated_state
vnf_instance_obj = objects.VnfInstance(**data)
elif scale_status:
data = _model_non_instantiated_vnf_instance(**updates)
data['instantiation_state'] = instantiated_state
vnf_instance_obj = objects.VnfInstance(**data)
get_instantiated_vnf_info = {
'flavour_id': uuidsentinel.flavour_id,
'vnf_state': 'STARTED',
'instance_id': uuidsentinel.instance_id
}
instantiated_vnf_info = get_instantiated_vnf_info
if scale_status == "scale_status":
s_status = {"aspect_id": "SP1", "scale_level": 1}
scale_status = objects.ScaleInfo(**s_status)
instantiated_vnf_info.update(
{"ext_cp_info": [],
'ext_virtual_link_info': [],
'ext_managed_virtual_link_info': [],
'vnfc_resource_info': [],
'vnf_virtual_link_resource_info': [],
'virtual_storage_resource_info': [],
"flavour_id": "simple",
"scale_status": [scale_status],
"vnf_instance_id": "171f3af2-a753-468a-b5a7-e3e048160a79",
"additional_params": {"key": "value"},
'vnf_state': "STARTED"})
info_data = objects.InstantiatedVnfInfo(**instantiated_vnf_info)
vnf_instance_obj.instantiated_vnf_info = info_data
else:
data = _model_non_instantiated_vnf_instance(**updates)
data['instantiation_state'] = instantiated_state
vnf_instance_obj = objects.VnfInstance(**data)
inst_vnf_info = objects.InstantiatedVnfInfo.obj_from_primitive({
"ext_cp_info": [],
'ext_virtual_link_info': [],
'ext_managed_virtual_link_info': [],
'vnfc_resource_info': [],
'vnf_virtual_link_resource_info': [],
'virtual_storage_resource_info': [],
"flavour_id": "simple",
"additional_params": {"key": "value"},
'vnf_state': "STARTED"}, None)
vnf_instance_obj.instantiated_vnf_info = inst_vnf_info
return vnf_instance_obj
def _instantiated_vnf_links(vnf_instance_id):
links = {
"self": {"href": "/vnflcm/v1/vnf_instances/%s" % vnf_instance_id},
"terminate": {"href": "/vnflcm/v1/vnf_instances/%s/terminate" %
vnf_instance_id},
"heal": {"href": "/vnflcm/v1/vnf_instances/%s/heal" %
vnf_instance_id},
"changeExtConn": {"href":
"/vnflcm/v1/vnf_instances/%s/change_ext_conn" %
vnf_instance_id}}
return links
def _fake_vnf_instance_not_instantiated_response(
**updates):
vnf_instance = {
'vnfInstanceDescription': 'Vnf instance description',
'vnfInstanceName': 'Vnf instance name',
'vnfProductName': 'Sample VNF',
'_links': {
'self': {
'href': os.path.join(
'/vnflcm/v1/vnf_instances/',
uuidsentinel.vnf_instance_id)},
'instantiate': {
'href': os.path.join(
'/vnflcm/v1/vnf_instances',
uuidsentinel.vnf_instance_id,
'instantiate')}},
'instantiationState': 'NOT_INSTANTIATED',
'vnfProvider': 'Vnf provider',
'vnfdId': uuidsentinel.vnfd_id,
'vnfdVersion': '1.0',
'vnfSoftwareVersion': '1.0',
'vnfPkgId': uuidsentinel.vnf_pkg_id,
'id': uuidsentinel.vnf_instance_id,
'metadata': {'key': 'value'}
}
if updates:
vnf_instance.update(**updates)
return vnf_instance
def fake_vnf_instance_response(
instantiated_state=fields.VnfInstanceState.NOT_INSTANTIATED,
api_version=None, vimConnectionInfo=[], **updates):
if instantiated_state == fields.VnfInstanceState.NOT_INSTANTIATED:
data = _fake_vnf_instance_not_instantiated_response(**updates)
else:
data = _fake_vnf_instance_not_instantiated_response(**updates)
data['_links'] = _instantiated_vnf_links(uuidsentinel.vnf_instance_id)
data['instantiationState'] = instantiated_state
data['vimConnectionInfo'] = vimConnectionInfo
def _instantiated_vnf_info():
inst_vnf_info = {}
inst_vnf_info['extCpInfo'] = []
inst_vnf_info['flavourId'] = 'simple'
inst_vnf_info['vnfState'] = 'STARTED'
inst_vnf_info['additionalParams'] = {"key": "value"}
return inst_vnf_info
data['instantiatedVnfInfo'] = _instantiated_vnf_info()
if api_version == '2.6.1':
del data['vnfPkgId']
return data
def fake_vnf_package(**updates):
vnf_package = {
'algorithm': None,
'deleted': False,
'deleted_at': None,
'updated_at': None,
'created_at': datetime.datetime(1900, 1, 1, 1, 1, 1,
tzinfo=iso8601.UTC),
'hash': None,
'location_glance_store': None,
'onboarding_state': 'CREATED',
'operational_state': 'DISABLED',
'tenant_id': uuidsentinel.tenant_id,
'usage_state': 'NOT_IN_USE',
'user_data': {'abc': 'xyz'},
'id': constants.UUID,
}
if updates:
vnf_package.update(updates)
return vnf_package
def fake_vnf_package_deployment_flavour(**updates):
vnf_package_deployment_data = {
'flavour_description': 'flavour_description',
'instantiation_levels': ('{"levels": {'
'"instantiation_level_1":'
'{"description": "Smallest size",'
' "scale_info": {"worker_instance":'
'{"scale_level": 0}}}},'
' "default_level": '
'"instantiation_level_1"}'),
'package_uuid': constants.UUID,
'flavour_id': 'simple',
}
if updates:
vnf_package_deployment_data.update(updates)
return vnf_package_deployment_data
def fake_vnf_package_software_image(**updates):
vnf_package_software_image_data = {
'id': constants.UUID,
'name': 'name',
'provider': 'provider',
'version': 'version',
'algorithm': 'algorithm',
'hash': 'hash',
'container_format': 'container_format',
'disk_format': 'disk_format',
'min_disk': 2,
'min_ram': 10,
'size': 5,
'image_path': 'image/path',
'flavour_uuid': constants.UUID,
'software_image_id': constants.UUID,
'created_at': datetime.datetime(1900, 1, 1, 1, 1, 1,
tzinfo=iso8601.UTC)
}
if updates:
vnf_package_software_image_data.update(updates)
return vnf_package_software_image_data
def return_vnf_deployment_flavour():
model_obj = models.VnfDeploymentFlavour()
model_obj.update(fake_vnf_package_deployment_flavour())
return model_obj
def return_vnf_software_image():
model_obj = models.VnfSoftwareImage()
model_obj.update(fake_vnf_package_software_image())
return model_obj
def return_vnf_package():
model_obj = models.VnfPackage()
model_obj.update(fake_vnf_package())
return model_obj
def return_vnf_package_with_deployment_flavour():
vnf_package = objects.VnfPackage._from_db_object(
context, objects.VnfPackage(), return_vnf_package(),
expected_attrs=None)
vnf_package_deployment_flavour = \
objects.VnfDeploymentFlavour._from_db_object(
context, objects.VnfDeploymentFlavour(),
return_vnf_deployment_flavour(), expected_attrs=None)
vnf_software_image = objects.VnfSoftwareImage._from_db_object(
context, objects.VnfSoftwareImage(), return_vnf_software_image(),
expected_attrs=None)
vnf_software_image_list = objects.VnfSoftwareImagesList()
vnf_software_image_list.objects = [vnf_software_image]
vnf_package_deployment_flavour.software_images = vnf_software_image_list
vnf_package_deployment_flavour_list = objects.VnfDeploymentFlavoursList()
vnf_package_deployment_flavour_list.objects = \
[vnf_package_deployment_flavour]
vnf_package.vnf_deployment_flavours = vnf_package_deployment_flavour_list
return vnf_package
def get_vnf_instantiation_request_body():
instantiation_req_body = {
"flavourId": "simple",
"instantiationLevelId": "instantiation_level_1",
"additionalParams": {"key1": 'value1', "key2": 'value2'},
"extVirtualLinks": [{
"id": 'f8c35bd0-4d67-4436-9f11-14b8a84c92aa',
"resourceId": 'f8c35bd0-4d67-4436-9f11-14b8a84c92aa',
"extCps": [{
"cpdId": 'f8c35bd0-4d67-4436-9f11-14b8a84c92aa',
"cpConfig": [{
"cpInstanceId": 'f8c35bd0-4d67-4436-9f11-14b8a84c92aa',
"linkPortId": 'f8c35bd0-4d67-4436-9f11-14b8a84c92aa',
"cpProtocolData": [
{
"layerProtocol": 'IP_OVER_ETHERNET',
"ipOverEthernet": {
"macAddress":
'fa:16:3e:11:11:11',
"ipAddresses": [
{
"type": "IPV4",
"fixedAddresses": [
'192.168.11.01',
'192.168.21.202'
],
"subnetId":
'actual-subnet-id'
}
]
}
}
]
}
]
}],
"extLinkPorts": [
{
"id": 'f8c35bd0-4d67-4436-9f11-14b8a84c92aa',
"resourceHandle": {
"resourceId":
'f8c35bd0-4d67-4436-9f11-14b8a84c92aa',
"vimLevelResourceType":
'f8c35bd0-4d67-4436-9f11-14b8a84c92aa',
}
},
{
"id": 'f8c35bd0-4d67-4436-9f11-14b8a84c92aa',
"resourceHandle": {
"resourceId":
'f8c35bd0-4d67-4436-9f11-14b8a84c92aa',
"vimLevelResourceType":
'f8c35bd0-4d67-4436-9f11-14b8a84c92aa',
}
}],
}],
"extManagedVirtualLinks": [
{"id": 'f8c35bd0-4d67-4436-9f11-14b8a84c92aa',
"vnfVirtualLinkDescId": 'f8c35bd0-4d67-4436-9f11-14b8a84c92aa',
"resourceId": 'f8c35bd0-4d67-4436-9f11-14b8a84c92aa'},
{"id": 'f8c35bd0-4d67-4436-9f11-14b8a84c92aa',
"vnfVirtualLinkDescId": 'f8c35bd0-4d67-4436-9f11-14b8a84c92aa',
"resourceId": 'f8c35bd0-4d67-4436-9f11-14b8a84c92aa'}],
"vimConnectionInfo": [
{"id": 'f8c35bd0-4d67-4436-9f11-14b8a84c92aa',
"vimId": 'f8c35bd0-4d67-4436-9f11-14b8a84c92aa',
"vimType": 'openstack',
"accessInfo": {"key1": 'value1', "key2": 'value2'}}],
}
return instantiation_req_body
def get_instantiate_vnf_request_obj():
instantiate_vnf_req = InstantiateVnfRequest()
ext_managed_virtual_link_data = ExtManagedVirtualLinkData()
vim_connection_info = VimConnectionInfo()
ext_virtual_link_data = ExtVirtualLinkData()
ext_managed_virtual_link_data.id = uuidsentinel.ext_id
ext_managed_virtual_link_data.vnf_virtual_link_desc_id = 'VL3'
ext_managed_virtual_link_data.resource_id = \
'f8c35bd0-4d67-4436-9f11-14b8a84c92aa'
ext_managed_virtual_link_data.vim_connection_id = \
'f8c35bd0-4d67-4436-9f11-14b8a84c92aa'
instantiate_vnf_req.additional_params = None
instantiate_vnf_req.deleted = 0
instantiate_vnf_req.ext_managed_virtual_links = \
[ext_managed_virtual_link_data]
instantiate_vnf_req.ext_virtual_link_data = [ext_virtual_link_data]
instantiate_vnf_req.flavour_id = 'test'
instantiate_vnf_req.instantiation_level_id = 'instantiation_level_1'
instantiate_vnf_req.vim_connection_info = [vim_connection_info]
return instantiate_vnf_req
def create_types_yaml_file():
yaml_str = ("""imports:
- etsi_nfv_sol001_common_types.yaml
- etsi_nfv_sol001_vnfd_types.yaml
node_types:
company.provider.VNF:
derived_from: tosca.nodes.nfv.VNF
properties:
descriptor_id:
type: string
constraints: [ valid_values: [ b1bb0ce7-ebca-4fa7-95ed-4840d70a1177 ]]
default: 1111
descriptor_version:
type: string
constraints: [ valid_values: [ '1.0' ] ]
default: 'fake desc version'
provider:
type: string
constraints: [ valid_values: [ 'Company' ] ]
default: 'Company'
product_name:
type: string
constraints: [ valid_values: [ 'Sample VNF' ] ]
default: 'fake product name'
software_version:
type: string
constraints: [ valid_values: [ '1.0' ] ]
default: 'fake software version'
vnfm_info:
type: list
entry_schema:
type: string
constraints: [ valid_values: [ Tacker ] ]
default: [ Tacker ]
flavour_id:
type: string
constraints: [ valid_values: [ simple ] ]
default: fake id
flavour_description:
type: string
default: "fake flavour"
requirements:
- virtual_link_external:
capability: tosca.capabilities.nfv.VirtualLinkable
- virtual_link_internal:
capability: tosca.capabilities.nfv.VirtualLinkable
interfaces:
Vnflcm:
type: tosca.interfaces.nfv.Vnflcm""")
file_path = os.path.abspath(
os.path.join(os.path.dirname(__file__), 'types.yaml'))
yaml_file = open(file_path, "w+")
yaml_file.write(yaml_str)
yaml_file.close()
def delete_types_yaml_file():
file_path = os.path.abspath(
os.path.join(os.path.dirname(__file__), 'types.yaml'))
if os.path.exists(file_path):
os.remove(file_path)
def create_vnfd_dict_file():
vnfd_dict_str = str(get_vnfd_dict())
file_path = os.path.abspath(
os.path.join(os.path.dirname(__file__), 'vnfd_dict.yaml'))
vnfd_dict_file = open(file_path, "w+")
vnfd_dict_file.write(vnfd_dict_str)
vnfd_dict_file.close()
def delete_vnfd_dict_yaml_file():
file_path = os.path.abspath(
os.path.join(os.path.dirname(__file__), 'vnfd_dict.yaml'))
if os.path.exists(file_path):
os.remove(file_path)
def get_vnfd_dict(image_path=None):
if image_path is None:
image_path = 'fake/image/path'
vnfd_dict = {
'description': 'Simple deployment flavour for Sample VNF',
'imports': ['/opt/stack/tacker/tacker/tests/unit/vnflcm/types.yaml'],
'topology_template':
{'inputs': {'descriptor_id': {'type': 'string'},
'descriptor_version': {'type': 'string'},
'flavour_description': {'type': 'string'},
'flavour_id': {'type': 'string'},
'product_name': {'type': 'string'},
'provider': {'type': 'string'},
'software_version': {'type': 'string'},
'vnfm_info': {
'entry_schema': {'type': 'string'},
'type': 'list'}},
'node_templates': {
'CP3': {'properties': {
'layer_protocols': ['ipv4'], 'order': 2},
'requirements': [{'virtual_binding': 'VDU1'},
{'virtual_link': 'VL3'}],
'type': 'tosca.nodes.nfv.VduCp'},
'CP4': {'properties': {'layer_protocols': ['ipv4'],
'order': 3},
'requirements': [{'virtual_binding': 'VDU1'},
{'virtual_link': 'VL4'}],
'type': 'tosca.nodes.nfv.VduCp'},
'VDU1': {'artifacts': {
'sw_image': {
'file': image_path,
'type': 'tosca.artifacts.nfv.SwImage'}},
'capabilities': {
'virtual_compute': {'properties': {
'virtual_cpu': {'num_virtual_cpu': 1},
'virtual_local_storage': [
{'size_of_storage': '1 ''GiB'}],
'virtual_memory': {
'virtual_mem_size': '512 ''MiB'}}}},
'properties': {
'description': 'VDU1 compute node',
'name': 'VDU1',
'sw_image_data': {
'checksum': {
'algorithm': 'fake algo',
'hash': 'fake hash'},
'container_format':
'fake container format',
'disk_format': 'fake disk format',
'min_disk': '1 ''GiB',
'name': 'fake name',
'size': 'fake size ' 'GiB',
'version': 'fake version'},
'vdu_profile': {
'max_number_of_instances': 1,
'min_number_of_instances': 1}},
'type': 'tosca.nodes.nfv.Vdu.Compute'},
'VL3': {'properties': {
'connectivity_type': {'layer_protocols': []},
'description': 'Internal virtual link in VNF',
'vl_profile': {
'max_bitrate_requirements': {
'leaf': 1048576,
'root': 1048576
},
'min_bitrate_requirements': {
'leaf': 1048576,
'root': 1048576
},
'virtual_link_protocol_data': [
{'layer_protocol': 'ipv4',
'l3_protocol_data': {}
}]}},
'type': 'tosca.nodes.nfv.VnfVirtualLink'},
'VL4': {'properties': {'connectivity_type': {
'layer_protocols': ['ipv4']},
'description': 'Internal virtual link in VNF',
'vl_profile': {}},
'type': 'tosca.nodes.nfv.VnfVirtualLink'},
'VNF': {'interfaces': {'Vnflcm': {
'instantiate': [],
'instantiate_end': [],
'instantiate_start': [],
'modify_information': [],
'modify_information_end': [],
'modify_information_start': [], 'terminate': [],
'terminate_end': [], 'terminate_start': []}},
'properties': {
'flavour_description': 'A simple flavor'},
'type': 'company.provider.VNF'}},
'substitution_mappings': {
'node_type': 'company.provider.VNF',
'properties': {'flavour_id': 'simple'},
'requirements': {
'virtual_link_external': [
'CP1', 'virtual_link']}}},
'tosca_definitions_version': 'tosca_simple_yaml_1_2'}
return vnfd_dict
def get_dummy_vnf_instance():
connection_info = get_dummy_vim_connection_info()
return {'created_at': '', 'deleted': False, 'deleted_at': None,
'id': 'fake_id', 'instantiated_vnf_info': None,
'instantiation_state': 'NOT_INSTANTIATED',
'tenant_id': 'fake_tenant_id', 'updated_at': '',
'vim_connection_info': [connection_info],
'vnf_instance_description': 'VNF Description',
'vnf_instance_name': 'test', 'vnf_product_name': 'Sample VNF',
'vnf_provider': 'Company', 'vnf_software_version': '1.0',
'vnfd_id': 'fake_vnfd_id', 'vnfd_version': '1.0'}
def get_dummy_vim_connection_info():
return {'access_info': {
'auth_url': 'fake/url',
'cert_verify': 'False', 'password': 'admin',
'project_domain_name': 'Default',
'project_id': None, 'project_name': 'admin',
'user_domain_name': 'Default', 'username': 'admin'},
'created_at': '', 'deleted': False, 'deleted_at': '',
'id': 'fake_id', 'updated_at': '',
'vim_id': 'fake_vim_id', 'vim_type': 'openstack'}
def get_dummy_instantiate_vnf_request(**updates):
instantiate_vnf_request = {
'additional_params': None, 'created_at': '', 'deleted': '',
'deleted_at': '', 'flavour_id': 'simple',
'instantiation_level_id': 'instantiation_level_1',
'updated_at': '', 'vim_connection_info': []}
if updates:
instantiate_vnf_request['vim_connection_info'].append(updates)
return instantiate_vnf_request
def get_instantiate_vnf_request_with_ext_virtual_links(**updates):
instantiate_vnf_request = \
{"flavourId": "simple",
"instantiationLevelId": "instantiation_level_1",
"extVirtualLinks": [{
"id": "ext-vl-uuid-VL1",
"vimConnectionId": "8a3adb69-0784-43c7-833e-aab0b6ab4470",
"resourceId": "f671ea41-bb4a-4b86-b6bd-b058f68f0498",
"extCps": [{
"cpdId": "CP1",
"cpConfig": [{
"linkPortId": "ee2982f6-8d0d-4649-9357-e527bcb68ed1",
"cpProtocolData": [{
"layerProtocol": "IP_OVER_ETHERNET",
"ipOverEthernet": {
"ipAddresses": [{
"type": "IPV4",
"fixedAddresses": ["192.168.120.95"],
"subnetId": "f577b050-b80a-baed-96db88cd529b"
}]}}]}]}]},
{
"id": "ext-vl-uuid-VL1",
"vimConnectionId": "8a3adb69-0784-43c7-833e-aab0b6ab4470",
"resourceId": "f671ea41-bb4a-4b86-b6bd-b058f68f0498",
"extCps": [{
"cpdId": "CP2",
"cpConfig": [{
"cpProtocolData": [{
"layerProtocol": "IP_OVER_ETHERNET",
"ipOverEthernet": {
"ipAddresses": [{
"type": "IPV4",
"fixedAddresses": ["192.168.120.96"],
"subnetId": "f577b050-b80a-96db88cd529b"
}]}}]}]}]}],
"extManagedVirtualLinks": [{
"id": "extMngVLnk-uuid_VL3",
"vnfVirtualLinkDescId": "VL3",
"vimConnectionId": "8a3adb69-0784-43c7-833e-aab0b6ab4470",
"resourceId": "f671ea41-bb4a-4b86-b6bd-b058f68f0498"
}],
"vimConnectionInfo": []
}
if updates:
instantiate_vnf_request.update(updates)
return instantiate_vnf_request
def _get_vnf(**updates):
vnf_data = {
'tenant_id': uuidsentinel.tenant_id,
'name': "fake_name",
'vnfd_id': uuidsentinel.vnfd_id,
'vnf_instance_id': uuidsentinel.instance_id,
'mgmt_ip_address': "fake_mgmt_ip_address",
'status': 'ACTIVE',
'description': 'fake_description',
'placement_attr': 'fake_placement_attr',
'vim_id': 'uuidsentinel.vim_id',
'error_reason': 'fake_error_reason',
'instance_id': uuidsentinel.instance_id,
'attributes': {
"scale_group": '{"scaleGroupDict" : {"SP1": {"maxLevel" : 3}}}',
"heat_template": os.path.dirname(__file__) +
"/../../etc/samples/hot_lcm_template.yaml"}}
if updates:
vnf_data.update(**updates)
return vnf_data
def scale_request(type, aspect_id, number_of_steps, is_reverse):
scale_request_data = {
'type': type,
'aspect_id': aspect_id,
'number_of_steps': number_of_steps,
'scale_level': 1,
'additional_params': {"is_reverse": is_reverse},
}
scale_request = \
scale_vnf_request.ScaleVnfRequest(**scale_request_data)
return scale_request
def get_dummy_grant_response():
return {'VDU1': {'checksum': {'algorithm': 'fake algo',
'hash': 'fake hash'},
'container_format': 'fake container format',
'disk_format': 'fake disk format',
'image_path': ('/var/lib/tacker/vnfpackages/' +
uuidsentinel.instance_id +
'/Files/images/path'),
'min_disk': 1,
'min_ram': 0,
'name': 'fake name',
'version': 'fake version'}}
def return_vnf_resource():
version_obj = objects.VnfResource(
created_at=datetime.datetime(1900, 1, 1, 1, 1, 1, tzinfo=iso8601.UTC),
deleted=False,
deleted_at=None,
id=uuidsentinel.vnf_resource_id,
resource_identifier=uuidsentinel.resource_identifier,
resource_name='test-image',
resource_status='CREATED',
resource_type='image',
updated_at=None,
vnf_instance_id=uuidsentinel.vnf_instance_id
)
return version_obj
def vnf_scale():
return tacker.db.vnfm.vnfm_db.VNF(id=constants.UUID,
vnfd_id=uuidsentinel.vnfd_id,
name='test',
status='ACTIVE',
vim_id=uuidsentinel.vim_id)
def vnflcm_scale_in_cnf():
dt = datetime.datetime(2000, 1, 1, 1, 1, 1, tzinfo=iso8601.UTC)
return objects.VnfLcmOpOcc(
state_entered_time=dt,
start_time=dt,
vnf_instance_id=uuidsentinel.vnf_instance_id,
operation='SCALE',
operation_state='STARTING',
is_automatic_invocation=False,
operation_params='{"type": "SCALE_IN", "aspect_id": "vdu1_aspect"}',
error_point=1,
id=constants.UUID,
created_at=dt)
def vnflcm_scale_out_cnf():
dt = datetime.datetime(2000, 1, 1, 1, 1, 1, tzinfo=iso8601.UTC)
return objects.VnfLcmOpOcc(
state_entered_time=dt,
start_time=dt,
vnf_instance_id=uuidsentinel.vnf_instance_id,
operation='SCALE',
operation_state='STARTING',
is_automatic_invocation=False,
operation_params='{"type": "SCALE_OUT", "aspect_id": "vdu1_aspect"}',
error_point=1,
id=constants.UUID,
created_at=dt)
def vnflcm_rollback(error_point=7):
dt = datetime.datetime(2000, 1, 1, 1, 1, 1, tzinfo=iso8601.UTC)
return objects.VnfLcmOpOcc(
state_entered_time=dt,
start_time=dt,
vnf_instance_id=uuidsentinel.vnf_instance_id,
operation='SCALE',
operation_state='FAILED_TEMP',
is_automatic_invocation=False,
operation_params='{"type": "SCALE_OUT", "aspect_id": "SP1"}',
error_point=error_point,
id=constants.UUID,
created_at=dt)
def vnflcm_rollback_insta(error_point=7):
dt = datetime.datetime(2000, 1, 1, 1, 1, 1, tzinfo=iso8601.UTC)
return objects.VnfLcmOpOcc(
state_entered_time=dt,
start_time=dt,
vnf_instance_id=uuidsentinel.vnf_instance_id,
operation='INSTANTIATE',
operation_state='FAILED_TEMP',
is_automatic_invocation=False,
operation_params='{}',
error_point=error_point,
id=constants.UUID,
created_at=dt)
def vnflcm_fail_insta(error_point=7):
default_datetime = datetime.datetime(
2000, 1, 1, 1, 1, 1, tzinfo=iso8601.UTC)
ext_link_port_info = objects.ExtLinkPortInfo(
resource_handle=objects.ResourceHandle(
resource_id="109f5049-b51e-409a-9a99-d740ba5f3acb",
vim_level_resource_type="LINKPORT"),
cp_instance_id="f5c68d94-5736-4e38-ade5-c9462514f8b9",
id="1d868d02-ecd4-4402-8e6b-54e77ebdcc28")
changed_ext_connectivity_values = objects.ExtVirtualLinkInfo(
id=constants.UUID,
resource_handle=objects.ResourceHandle(
vim_connection_id=constants.UUID,
resource_id=constants.UUID,
vim_level_resource_type="OS::Neutron::Net"),
ext_link_ports=[ext_link_port_info]
)
return objects.VnfLcmOpOcc(
state_entered_time=default_datetime,
start_time=default_datetime,
vnf_instance_id=uuidsentinel.vnf_instance_id,
operation='INSTANTIATE',
operation_state='FAILED_TEMP',
is_automatic_invocation=False,
operation_params='{}',
error_point=error_point,
id=constants.UUID,
grant_id=constants.UUID,
created_at=default_datetime,
changed_ext_connectivity=[changed_ext_connectivity_values])
def vnflcm_fail_check_added_params(error_point=7):
ext_link_port_info = objects.ExtLinkPortInfo(
resource_handle=objects.ResourceHandle(
resource_id="109f5049-b51e-409a-9a99-d740ba5f3acb",
vim_level_resource_type="LINKPORT"),
cp_instance_id="f5c68d94-5736-4e38-ade5-c9462514f8b9",
id="1d868d02-ecd4-4402-8e6b-54e77ebdcc28")
changed_ext_connectivity_values = objects.ExtVirtualLinkInfo(
id=constants.UUID,
resource_handle=objects.ResourceHandle(
vim_connection_id=constants.UUID,
resource_id=constants.UUID,
vim_level_resource_type="OS::Neutron::Net"),
ext_link_ports=[ext_link_port_info]
)
changed_info_values = objects.VnfInfoModifications(
vnf_instance_name="fake_name",
vnf_instance_description="fake_vnf_instance_description",
vnfd_id="f26f181d-7891-4720-b022-b074ec1733ef",
vnf_provider="fake_vnf_provider",
vnf_product_name="fake_vnf_product_name",
vnf_software_version="fake_vnf_software_version",
vnfd_version="fake_vnfd_version")
return objects.VnfLcmOpOcc(
state_entered_time=datetime.datetime(2000, 1, 1, 1, 1, 1,
tzinfo=iso8601.UTC),
start_time=datetime.datetime(2000, 1, 1, 1, 1, 1,
tzinfo=iso8601.UTC),
vnf_instance_id=constants.UUID,
operation='INSTANTIATE',
operation_state='FAILED_TEMP',
is_automatic_invocation=False,
operation_params='{}',
error_point=error_point,
id=constants.UUID,
grant_id=constants.UUID,
created_at=datetime.datetime(2000, 1, 1, 1, 1, 1,
tzinfo=iso8601.UTC),
changed_ext_connectivity=[changed_ext_connectivity_values],
changed_info=changed_info_values)
def vnflcm_rollback_active():
dt = datetime.datetime(2000, 1, 1, 1, 1, 1, tzinfo=iso8601.UTC)
return objects.VnfLcmOpOcc(
state_entered_time=dt,
start_time=dt,
vnf_instance_id=uuidsentinel.vnf_instance_id,
operation='SCALE',
operation_state='ACTIVE',
is_automatic_invocation=False,
operation_params='{"type": "SCALE_OUT", "aspect_id": "SP1"}',
error_point=7,
id=constants.UUID,
created_at=dt)
def vnflcm_rollback_ope():
dt = datetime.datetime(2000, 1, 1, 1, 1, 1, tzinfo=iso8601.UTC)
return objects.VnfLcmOpOcc(
state_entered_time=dt,
start_time=dt,
vnf_instance_id=uuidsentinel.vnf_instance_id,
operation='HEAL',
operation_state='FAILED_TEMP',
is_automatic_invocation=False,
operation_params='{}',
error_point=7,
id=constants.UUID,
created_at=dt)
def vnflcm_rollback_scale_in():
dt = datetime.datetime(2000, 1, 1, 1, 1, 1, tzinfo=iso8601.UTC)
return objects.VnfLcmOpOcc(
state_entered_time=dt,
start_time=dt,
vnf_instance_id=uuidsentinel.vnf_instance_id,
operation='SCALE',
operation_state='FAILED_TEMP',
is_automatic_invocation=False,
operation_params='{"type": "SCALE_IN", "aspect_id": "SP1"}',
error_point=7,
id=constants.UUID,
created_at=dt)
def vnf_rollback():
return tacker.db.vnfm.vnfm_db.VNF(id=constants.UUID,
vnfd_id=uuidsentinel.vnfd_id,
name='test',
status='ERROR',
vim_id=uuidsentinel.vim_id)
def vnf_dict():
heat_temp = 'heat_template_version: ' + \
'2013-05-23\ndescription: \'VNF Descriptor (TEST)' + \
'\n\n \'\nparameters:\n current_num:\n type: ' + \
'number\n nfv:\n type: json\nresources:\n ' + \
'SP1_scale_out:\n type: OS::Heat::ScalingPolicy\n' + \
' properties:\n auto_scaling_group_id: ' + \
'{get_resource: SP1_group}\n adjustment_type: ' + \
'change_in_capacity\n scaling_adjustment: 1\n ' + \
'SP1_group:\n type: OS::Heat::AutoScalingGroup\n ' + \
'properties:\n min_size: 0\n desired_capacity:' + \
' {get_param: current_num}\n resource:\n ' + \
'type: SP1_res.yaml\n properties:\n nfv:' + \
' {get_param: nfv}\n max_size: 3\n SP1_scale_in:\n' + \
' type: OS::Heat::ScalingPolicy\n properties:\n' + \
' auto_scaling_group_id: {get_resource: SP1_group}\n' + \
' adjustment_type: change_in_capacity\n ' + \
'scaling_adjustment: -1\noutputs: {}\n'
scale_g = '{\"scaleGroupDict\": { \"SP1\": { \"vdu\":' + \
' [\"VDU1\"], \"num\": 1, \"maxLevel\": 3, \"initialNum\":' + \
' 0, \"initialLevel\": 0, \"default\": 0 }}}'
vnfd = 'tosca_definitions_version: ' + \
'tosca_simple_yaml_1_2\n\ndescription: Simple deployment' + \
' flavour for Sample VNF\n\nimports:\n' + \
' - etsi_nfv_sol001_common_types.yaml\n' + \
' - etsi_nfv_sol001_vnfd_types.yaml\n\n' + \
'topology_template:\n node_templates:\n' + \
' VNF:\n type: nec.ossmano.VNF\n' + \
' properties:\n' + \
' flavour_description: A simple flavour\n' + \
' interfaces:\n Vnflcm:\n' + \
' scale_start: noop\n' + \
' scale: scale_standard\n' + \
' scale_end: noop\n artifacts:\n' + \
' hot:\n' + \
' type: tosca.artifacts.Implementation.nfv.Hot\n' + \
' file: ../Files/scale.yaml\n hot-nest:\n' + \
' type: tosca.artifacts.Implementation.nfv.Hot\n' + \
' file: ../Files/SP1_res.yaml\n' + \
' properties:\n nest: "True"\n\n' + \
' VDU1:\n type: tosca.nodes.nfv.Vdu.Compute\n' + \
' properties:\n name: VDU1\n' + \
' description: VDU1 compute node\n' + \
' vdu_profile:\n' + \
' min_number_of_instances: 1\n' + \
' max_number_of_instances: 3\n\n' + \
' capabilities:\n virtual_compute:\n' + \
' properties:\n virtual_memory:\n' + \
' virtual_mem_size: 512 MB\n' + \
' virtual_cpu:\n' + \
' num_virtual_cpu: 1\n' + \
' virtual_local_storage:\n' + \
' - size_of_storage: 1 GB\n' + \
' requirements:\n' + \
' - virtual_storage: VirtualStorage\n\n' + \
' VirtualStorage:\n' + \
' type: tosca.nodes.nfv.Vdu.VirtualBlockStorage\n' + \
' properties:\n virtual_block_storage_data:\n' + \
' size_of_storage: 1 GB\n' + \
' rdma_enabled: true\n sw_image_data:\n' + \
' name: VirtualStorage\n' + \
' version: \'0.4.0\'\n checksum:\n' + \
' algorithm: sha-512\n' + \
' hash: 6513f21e44aa3da349f248188a44bc304a3' + \
'653a04122d8fb4535423c8e1d14cd6a153f735bb0982e2161b5b5' + \
'186106570c17a9e58b64dd39390617cd5a350f78\n' + \
' container_format: bare\n' + \
' disk_format: qcow2\n' + \
' min_disk: 2 GB\n' + \
' min_ram: 256 MB\n' + \
' size: 1 GB\n\n CP1:\n' + \
' type: tosca.nodes.nfv.VduCp\n' + \
' properties:\n layer_protocols: [ ipv4 ]\n' + \
' order: 2\n requirements:\n' + \
' - virtual_binding: VDU1\n' + \
' - virtual_link: internalVL1\n\n' + \
' internalVL1:\n' + \
' type: tosca.nodes.nfv.VnfVirtualLink\n' + \
' properties:\n connectivity_type:\n' + \
' layer_protocols: [ ipv4 ]\n' + \
' description: Internal Virtual link in the VNF\n' + \
' vl_profile:\n' + \
' max_bitrate_requirements:\n' + \
' root: 1048576\n' + \
' leaf: 1048576\n' + \
' min_bitrate_requirements:\n' + \
' root: 1048576\n leaf: 1048576\n' + \
' virtual_link_protocol_data:\n' + \
' - associated_layer_protocol: ipv4\n' + \
' l3_protocol_data:\n' + \
' ip_version: ipv4\n' + \
' cidr: 33.33.0.0/24\n\n policies:\n' + \
' - scaling_aspects:\n' + \
' type: tosca.policies.nfv.ScalingAspects\n' + \
' properties:\n aspects:\n' + \
' SP1:\n name: SP1_aspect\n' + \
' description: SP1 scaling aspect\n' + \
' max_scale_level: 2\n' + \
' step_deltas:\n' + \
' - delta_1\n\n' + \
' - VDU1_initial_delta:\n' + \
' type: tosca.policies.nfv.VduInitialDelta\n' + \
' properties:\n initial_delta:\n' + \
' number_of_instances: 0\n' + \
' targets: [ VDU1 ]\n\n' + \
' - VDU1_scaling_aspect_deltas:\n' + \
' type: tosca.policies.nfv.VduScalingAspectDeltas\n' + \
' properties:\n aspect: SP1\n' + \
' deltas:\n delta_1:\n' + \
' number_of_instances: 1\n' + \
' targets: [ VDU1 ]\n\n' + \
' - instantiation_levels:\n' + \
' type: tosca.policies.nfv.InstantiationLevels\n' + \
' properties:\n levels:\n' + \
' instantiation_level_1:\n' + \
' description: Smallest size\n' + \
' scale_info:\n SP1:\n' + \
' scale_level: 0\n' + \
' instantiation_level_2:\n' + \
' description: Largest size\n' + \
' scale_info:\n SP1:\n' + \
' scale_level: 3\n' + \
' default_level: instantiation_level_1\n\n' + \
' - VDU1_instantiation_levels:\n' + \
' type: tosca.policies.nfv.VduInstantiationLevels\n' + \
' properties:\n levels:\n' + \
' instantiation_level_1:\n' + \
' number_of_instances: 0\n' + \
' instantiation_level_2:\n' + \
' number_of_instances: 3\n' + \
' targets: [ VDU1 ]\n'
vnf_dict = {
'attributes': {
'heat_template': heat_temp,
'scale_group': scale_g
},
'status': 'ERROR',
'vnfd_id': '576acf48-b9df-491d-a57c-342de660ec78',
'tenant_id': '13d2ca8de70d48b2a2e0dbac2c327c0b',
'vim_id': '3f41faa7-5630-47d2-9d4a-1216953c8887',
'instance_id': 'd1121d3c-368b-4ac2-b39d-835aa3e4ccd8',
'placement_attr': {'vim_name': 'openstack-vim'},
'id': 'a27fc58e-66ae-4031-bba4-efede318c60b',
'name': 'vnf_create_1',
'vnfd': {
'attributes': {
'vnfd_simple': vnfd
}
}
}
return vnf_dict
def vnf_dict_cnf():
vnf_dict = {
'attributes': {},
'status': 'ACTIVE',
'vnfd_id': 'e889e4fe-52fe-437d-b1e1-a690dc95e3f8',
'tenant_id': '13d2ca8de70d48b2a2e0dbac2c327c0b',
'vim_id': '3f41faa7-5630-47d2-9d4a-1216953c8887',
'instance_id': 'd1121d3c-368b-4ac2-b39d-835aa3e4ccd8',
'placement_attr': {'vim_name': 'kubernetes-vim'},
'id': '436aaa6e-2db6-4d6e-a3fc-e728b2f0ac56',
'name': 'cnf_create_1',
'vnfd': {
'attributes': {
'vnfd_simple': 'dummy'
}
}
}
return vnf_dict
def vnfd_dict_cnf():
tacker_dir = os.getcwd()
def_dir = tacker_dir + "/samples/vnf_packages/Definitions/"
vnfd_dict = {
"tosca_definitions_version": "tosca_simple_yaml_1_2",
"description": "Sample VNF flavour for Sample VNF",
"imports": [
def_dir + "etsi_nfv_sol001_common_types.yaml",
def_dir + "etsi_nfv_sol001_vnfd_types.yaml",
def_dir + "helloworld3_types.yaml"],
"topology_template": {
"node_templates": {
"VNF": {
"type": "company.provider.VNF",
"properties": {
"flavour_description": "A simple flavour"}},
"VDU1": {
"type": "tosca.nodes.nfv.Vdu.Compute",
"properties": {
"name": "vdu1",
"description": "vdu1 compute node",
"vdu_profile": {
"min_number_of_instances": 1,
"max_number_of_instances": 3}}}},
"policies": [
{
"scaling_aspects": {
"type": "tosca.policies.nfv.ScalingAspects",
"properties": {
"aspects": {
"vdu1_aspect": {
"name": "vdu1_aspect",
"description": "vdu1 scaling aspect",
"max_scale_level": 2,
"step_deltas": ["delta_1"]}}}}},
{
"vdu1_initial_delta": {
"type": "tosca.policies.nfv.VduInitialDelta",
"properties": {
"initial_delta": {
"number_of_instances": 0}},
"targets": ["VDU1"]}},
{
"vdu1_scaling_aspect_deltas": {
"type": "tosca.policies.nfv.VduScalingAspectDeltas",
"properties": {
"aspect": "vdu1_aspect",
"deltas": {
"delta_1": {
"number_of_instances": 1}}},
"targets": ["VDU1"]}},
{
"instantiation_levels": {
"type": "tosca.policies.nfv.InstantiationLevels",
"properties": {
"levels": {
"instantiation_level_1": {
"description": "Smallest size",
"scale_info": {
"vdu1_aspect": {
"scale_level": 0}}},
"instantiation_level_2": {
"description": "Largest size",
"scale_info": {
"vdu1_aspect": {
"scale_level": 2}}}
},
"default_level": "instantiation_level_1"}}},
{
"vdu1_instantiation_levels": {
"type": "tosca.policies.nfv.VduInstantiationLevels",
"properties": {
"levels": {
"instantiation_level_1": {
"number_of_instances": 0},
"instantiation_level_2": {
"number_of_instances": 2}}},
"targets": ["VDU1"]}}
]
}
}
return vnfd_dict
class InjectContext(wsgi.Middleware):
"""Add a 'tacker.context' to WSGI environ."""
def __init__(self, context, *args, **kwargs):
self.context = context
super(InjectContext, self).__init__(*args, **kwargs)
@webob.dec.wsgify(RequestClass=wsgi.Request)
def __call__(self, req):
req.environ['tacker.context'] = self.context
return self.application
def wsgi_app_v1(fake_auth_context=None):
inner_app_v1 = VnflcmAPIRouter()
if fake_auth_context is not None:
ctxt = fake_auth_context
else:
ctxt = context.ContextBase(uuidsentinel.user_id,
uuidsentinel.project_id, is_admin=True)
api_v1 = InjectContext(ctxt, inner_app_v1)
return api_v1
VNFLCMOPOCC_RESPONSE = {
'_links': {
"self": {
"href": CONF.vnf_lcm.endpoint_url + '/vnflcm/v1/vnf_lcm_op_occs/'
'f26f181d-7891-4720-b022-b074ec1733ef'
},
"vnfInstance": {
"href": CONF.vnf_lcm.endpoint_url + '/vnflcm/v1/vnf_instances/'
'f26f181d-7891-4720-b022-b074ec1733ef'
},
"retry": {
"href": CONF.vnf_lcm.endpoint_url + '/vnflcm/v1/vnf_lcm_op_occs/'
'f26f181d-7891-4720-b022-b074ec1733ef/retry'
},
"rollback": {
"href": CONF.vnf_lcm.endpoint_url + '/vnflcm/v1/vnf_lcm_op_occs/'
'f26f181d-7891-4720-b022-b074ec1733ef/rollback'
},
"grant": {
"href": CONF.vnf_lcm.endpoint_url + '/vnflcm/v1/vnf_lcm_op_occs/'
'f26f181d-7891-4720-b022-b074ec1733ef/grant',
},
"fail": {
"href": CONF.vnf_lcm.endpoint_url + '/vnflcm/v1/vnf_lcm_op_occs/'
'f26f181d-7891-4720-b022-b074ec1733ef/fail'}},
'operationState': 'COMPLETED',
'stateEnteredTime': datetime.datetime(1900, 1, 1, 1, 1, 1,
tzinfo=iso8601.UTC),
'startTime': datetime.datetime(1900, 1, 1, 1, 1, 1,
tzinfo=iso8601.UTC),
'vnfInstanceId': 'f26f181d-7891-4720-b022-b074ec1733ef',
'grantId': 'f26f181d-7891-4720-b022-b074ec1733ef',
'operation': 'MODIFY_INFO',
'isAutomaticInvocation': False,
'operationParams': '{"is_reverse": False, "is_auto": False}',
'error': {
'status': 500,
'detail': "name 'con' is not defined",
'title': "ERROR"
},
'id': 'f26f181d-7891-4720-b022-b074ec1733ef',
'isCancelPending': False,
'resourceChanges': {
'affectedVnfcs': [{
'id': 'f26f181d-7891-4720-b022-b074ec1733ef',
'vduId': 'VDU1',
'changeType': 'ADDED',
'computeResource': {
'vimConnectionId': 'f26f181d-7891-4720-b022-b074ec1733ef',
'resourceId': 'f26f181d-7891-4720-b022-b074ec1733ef',
'vimLevelResourceType': "OS::Nova::Server",
},
'affectedVnfcCpIds': [],
'addedStorageResourceIds': [],
'removedStorageResourceIds': []
}],
'affectedVirtualLinks': [{
'id': 'f26f181d-7891-4720-b022-b074ec1733ef',
'vnfVirtualLinkDescId': 'f26f181d-7891-4720-b022-b074ec1733ef',
'changeType': 'ADDED',
'networkResource': {
'vimConnectionId': 'f26f181d-7891-4720-b022-b074ec1733ef',
'resourceId': 'f26f181d-7891-4720-b022-b074ec1733ef',
'vimLevelResourceType': 'COMPUTE'
}
}],
'affectedVirtualStorages': [{
'id': 'f26f181d-7891-4720-b022-b074ec1733ef',
'virtualStorageDescId': 'f26f181d-7891-4720-b022-b074ec1733ef',
'changeType': 'ADDED',
'storageResource': {
'vimConnectionId': 'f26f181d-7891-4720-b022-b074ec1733ef',
'resourceId': 'f26f181d-7891-4720-b022-b074ec1733ef',
'vimLevelResourceType': 'COMPUTE'
}
}]
},
'changedInfo': {
'metadata': {},
'vimConnectionInfo': [],
'vimConnectionInfoDeleteIds': [],
'vnfPkgId': None,
'vnfInstanceName': 'fake_name',
'vnfInstanceDescription': "fake_vnf_instance_description",
'vnfdId': 'f26f181d-7891-4720-b022-b074ec1733ef',
'vnfProvider': 'fake_vnf_provider',
'vnfProductName': 'fake_vnf_product_name',
'vnfSoftwareVersion': 'fake_vnf_software_version',
'vnfdVersion': 'fake_vnfd_version'
},
"changedExtConnectivity": [{
"id": constants.UUID,
"resourceHandle": {
"vimConnectionId": constants.UUID,
"resourceId": constants.UUID,
"vimLevelResourceType": "OS::Neutron::Net",
},
"extLinkPorts": [{
"id": constants.UUID,
"resourceHandle": {
"vimConnectionId": constants.UUID,
"resourceId": constants.UUID,
"vimLevelResourceType": "OS::Neutron::Port",
},
"cpInstanceId": constants.UUID,
}]
}]
}
VNFLCMOPOCC_INDEX_RESPONSE = [VNFLCMOPOCC_RESPONSE]
def index_response(remove_attrs=None, vnf_lcm_op_occs_updates=None):
# Returns VNFLCMOPOCC_RESPONSE
# parameter remove_attrs is a list of attribute names
# to be removed before returning the response
if not remove_attrs:
return VNFLCMOPOCC_INDEX_RESPONSE
vnf_lcm_op_occs = deepcopy(VNFLCMOPOCC_RESPONSE)
for attr in remove_attrs:
vnf_lcm_op_occs.pop(attr, None)
if vnf_lcm_op_occs_updates:
vnf_lcm_op_occs.update(vnf_lcm_op_occs_updates)
return [vnf_lcm_op_occs]
def fake_vnf_lcm_op_occs():
error = {"status": 500, "detail": "name 'con' is not defined",
"title": "ERROR"}
error_obj = objects.ProblemDetails(**error)
compute_resource = {
"vim_connection_id":
"f26f181d-7891-4720-b022-b074ec1733ef",
"resource_id":
"f26f181d-7891-4720-b022-b074ec1733ef",
"vim_level_resource_type": "OS::Nova::Server"}
compute_resource_obj = objects.ResourceHandle(**compute_resource)
affected_vnfcs = {
"id": "f26f181d-7891-4720-b022-b074ec1733ef",
"vdu_id": "VDU1",
"change_type": "ADDED",
"compute_resource": compute_resource_obj,
"affected_vnfc_cp_ids": [],
"added_storage_resource_ids": [],
"removed_storage_sesource_ids": []
}
affected_vnfcs_obj = objects.AffectedVnfc(**affected_vnfcs)
network_resource = {
"vim_connection_id":
"f26f181d-7891-4720-b022-b074ec1733ef",
"resource_id":
"f26f181d-7891-4720-b022-b074ec1733ef",
"vim_level_resource_type": "COMPUTE"
}
network_resource_obj = \
objects.ResourceHandle(**network_resource)
affected_virtual_links = {
"id": "f26f181d-7891-4720-b022-b074ec1733ef",
"vnf_virtual_link_desc_id":
"f26f181d-7891-4720-b022-b074ec1733ef",
"change_type": "ADDED",
"network_resource": network_resource_obj,
}
affected_virtual_links_obj = \
objects.AffectedVirtualLink(**affected_virtual_links)
storage_resource = {
"vim_connection_id":
"f26f181d-7891-4720-b022-b074ec1733ef",
"resource_id":
"f26f181d-7891-4720-b022-b074ec1733ef",
"vim_level_resource_type": "COMPUTE"}
storage_resource_obj = \
objects.ResourceHandle(**storage_resource)
affected_virtual_storages = {
"id": "f26f181d-7891-4720-b022-b074ec1733ef",
"virtual_storage_desc_id":
"f26f181d-7891-4720-b022-b074ec1733ef",
"change_type": "ADDED",
"storage_resource": storage_resource_obj,
}
affected_virtual_storages_obj = \
objects.AffectedVirtualStorage(**affected_virtual_storages)
resource_changes = {
"affected_vnfcs": [affected_vnfcs_obj],
"affected_virtual_links": [affected_virtual_links_obj],
"affected_virtual_storages": [affected_virtual_storages_obj]
}
resource_changes_obj = objects.ResourceChanges(**resource_changes)
changed_info = {
"vnf_instance_name": "fake_name",
"vnf_instance_description":
"fake_vnf_instance_description",
"metadata": {},
"vnfd_id": "f26f181d-7891-4720-b022-b074ec1733ef",
"vnf_provider": "fake_vnf_provider",
"vnf_product_name": "fake_vnf_product_name",
"vnf_software_version": "fake_vnf_software_version",
"vnfd_version": "fake_vnfd_version"
}
changed_info_obj = objects.VnfInfoModifications(**changed_info)
changed_ext_connectivity = [{
"id": constants.UUID,
"resource_handle": {
"vim_connection_id": constants.UUID,
"resource_id": constants.UUID,
"vim_level_resource_type": "OS::Neutron::Net",
},
"ext_link_ports": [{
"id": constants.UUID,
"resource_handle": {
"vim_connection_id": constants.UUID,
"resource_id": constants.UUID,
"vim_level_resource_type": "OS::Neutron::Port",
},
"cp_instance_id": constants.UUID,
}]
}]
changed_ext_connectivity_obj = \
[objects.ExtVirtualLinkInfo.obj_from_primitive(
chg_ext_conn, context) for chg_ext_conn in
changed_ext_connectivity]
dt = datetime.datetime(1900, 1, 1, 1, 1, 1, tzinfo=iso8601.UTC)
vnf_lcm_op_occs = {
'id': constants.UUID,
'operation_state': 'COMPLETED',
'state_entered_time': dt,
'start_time': dt,
'vnf_instance_id': constants.UUID,
'grant_id': constants.UUID,
'operation': 'MODIFY_INFO',
'is_automatic_invocation': False,
'operation_params': '{"is_reverse": False, "is_auto": False}',
'is_cancel_pending': False,
'error': error_obj,
'resource_changes': resource_changes_obj,
'changed_info': changed_info_obj,
'changed_ext_connectivity': changed_ext_connectivity_obj,
}
return vnf_lcm_op_occs
def return_vnf_lcm_opoccs_obj():
vnf_lcm_op_occs = fake_vnf_lcm_op_occs()
obj = objects.VnfLcmOpOcc(**vnf_lcm_op_occs)
return obj
def vnflcm_op_occs_retry_data(error_point=7, operation='INSTANTIATE',
operation_state='FAILED_TEMP'):
now = datetime.datetime(2000, 1, 1, 1, 1, 1, tzinfo=iso8601.UTC)
return objects.VnfLcmOpOcc(
state_entered_time=now,
start_time=now,
vnf_instance_id=uuidsentinel.vnf_instance_id,
operation=operation,
operation_state=operation_state,
is_automatic_invocation=False,
operation_params='{}',
error_point=error_point,
id=constants.UUID,
created_at=now)
def vnf_data(status='ACTIVE'):
return tacker.db.vnfm.vnfm_db.VNF(id=constants.UUID,
vnfd_id=uuidsentinel.vnfd_id,
name='test',
status=status,
vim_id=uuidsentinel.vim_id)
def return_vnf_lcm_opoccs_list():
vnf_lcm_op_occs = fake_vnf_lcm_op_occs()
obj = objects.VnfLcmOpOcc(**vnf_lcm_op_occs)
return [obj]
def get_change_ext_conn_request_body():
change_ext_conn_req_body = {
"extVirtualLinks": [{
"id": 'f8c35bd0-4d67-4436-9f11-14b8a84c92aa',
"vimConnectionId": '2b3beeff-d4a1-4dc7-a1f8-066f92cfcb75',
"resourceId": 'e08f5e67-55de-4c4a-815b-cf3f1e2bae04',
"extCps": [{
"cpdId": 'VDU2_CP2',
"cpConfig": [{
"cpInstanceId": '924d0ea7-786d-468b-bf45-65bfd483ee79',
"linkPortId": 'f8c35bd0-4d67-4436-9f11-14b8a84c92aa',
"cpProtocolData": [{
"layerProtocol": 'IP_OVER_ETHERNET',
"ipOverEthernet": {
"macAddress":
'fa:16:3e:11:11:11',
"ipAddresses": [{
"type": "IPV4",
"fixedAddresses": ["22.22.1.20"],
"subnetId":
'497b7a75-6c10-4a74-85fa-83d498da2501'
}]
}
}]
}]
}],
"extLinkPorts": [{
"id": 'decd78d2-993c-4112-9a8f-1ad54cade4d7',
"resourceHandle": {
"resourceId": 'cb602960-05ee-4e03-8fe2-ea0b64e08332',
"vimConnectionId": '2b3beeff-d4a1-4dc7-a1f8-066f92cfcb75',
"vimLevelResourceType":
'f8c35bd0-4d67-4436-9f11-14b8a84c92aa',
}
}],
"vimConnectionInfo": [{
"id": '2b3beeff-d4a1-4dc7-a1f8-066f92cfcb75',
"vimId": 'f8c35bd0-4d67-4436-9f11-14b8a84c92aa',
"vimType": 'openstack',
"interfaceInfo": {"key1": 'value1', "key2": 'value2'},
"accessInfo": {"key1": 'value1', "key2": 'value2'}
}],
}]
}
return change_ext_conn_req_body
def get_change_ext_conn_request_obj():
"""Return ChangeExtConnRequest Object
obj_from_primitive() needs snake_case dictionary
"""
body = utils.convert_camelcase_to_snakecase(
get_change_ext_conn_request_body())
return ChangeExtConnRequest.obj_from_primitive(
body, context)
def _fake_subscription_obj(**updates):
subscription = {
'id': uuidsentinel.subscription_id,
'filter': {
"vnfInstanceSubscriptionFilter": {
"vnfdIds": [uuidsentinel.vnfd_id],
"vnfProductsFromProviders": {
"vnfProvider": "Vnf Provider 1",
"vnfProducts": [
{
"vnfProductName": "Vnf Product 1",
"versions": [
{
"vnfSoftwareVersion": "v1",
"vnfdVersions": [
"vnfd.v1.1"
]
}
]
}
]
},
"vnfInstanceIds": [
uuidsentinel.vnf_instance_id
],
"vnfInstanceNames": ["Vnf Name 1"]
},
"notificationTypes": [
"VnfLcmOperationOccurrenceNotification",
"VnfIdentifierCreationNotification",
"VnfIdentifierDeletionNotification"
],
"operationTypes": [
"INSTANTIATE",
"SCALE",
"TERMINATE",
"HEAL",
"CHANGE_EXT_CONN",
"MODIFY_INFO"
],
"operationStates": [
"STARTING",
"PROCESSING",
"COMPLETED",
"FAILED_TEMP",
"FAILED",
"ROLLING_BACK",
"ROLLED_BACK"
]
},
'callback_uri': 'http://localhost/sample_callback_uri'}
if updates:
subscription.update(**updates)
return subscription
def return_subscription_object(**updates):
vnf_lcm_subscription = _fake_subscription_obj(**updates)
return vnf_lcm_subscription
def return_vnf_subscription_list(**updates):
vnc_lcm_subscription = return_subscription_object(**updates)
return [vnc_lcm_subscription]
def _subscription_links(subscription_dict):
links = {
"_links": {
"self": {
"href": "%(endpoint)s/vnflcm/v1/subscriptions/%(id)s"
% {'id': subscription_dict['id'],
'endpoint': CONF.vnf_lcm.endpoint_url}
}
}
}
subscription_dict.update(links)
return subscription_dict
def return_subscription_obj(**updates):
subscription = _fake_subscription_obj(**updates)
subscription['filter'] = json.dumps(subscription['filter'])
obj = objects.LccnSubscriptionRequest(**subscription)
return obj
def fake_subscription_response(**updates):
data = _fake_subscription_obj(**updates)
data = utils.convert_snakecase_to_camelcase(data)
data = _subscription_links(data)
return data