ETSI-NFV SOL 001 translation: VNF, Compute
Currently heat-translator supports translation of TOSCA Simple Profile for YAML[1] and TOSCA Simple Profile for NFV[2] only. This commit enables to translation of the follwoing type defined in ETSI NFV-SOL 001[3]. - tosca.nodes.nfv.VNF - tosca.nodes.nfv.Vdu.Compute [1] http://docs.oasis-open.org/tosca/tosca-nfv/v1.0/tosca-nfv-v1.0.html [2] http://docs.oasis-open.org/tosca/TOSCA-Simple-Profile-YAML/v1.0/TOSCA-Simple-Profile-YAML-v1.0.html [3] https://www.etsi.org/deliver/etsi_gs/NFV-SOL/001_099/001/02.06.01_60/gs_NFV-SOL001v020601p.pdf Story: 2006372 Task: 36161 Change-Id: I69263dce88bab5413a2d6f74f8d0c920dd454bf3
This commit is contained in:
parent
9d5056a9d7
commit
4833eb5e92
@ -75,7 +75,7 @@ stevedore==1.20.0
|
||||
testrepository==0.0.18
|
||||
testscenarios==0.4
|
||||
testtools==2.2.0
|
||||
tosca-parser==1.4.0
|
||||
tosca-parser==1.6.1
|
||||
traceback2==1.4.0
|
||||
unittest2==1.1.0
|
||||
warlock==1.2.0
|
||||
|
@ -7,7 +7,7 @@ cliff!=2.9.0,>=2.8.0 # Apache-2.0
|
||||
PyYAML>=3.12 # MIT
|
||||
python-dateutil>=2.5.3 # BSD
|
||||
six>=1.10.0 # MIT
|
||||
tosca-parser>=1.4.0 # Apache-2.0
|
||||
tosca-parser>=1.6.1 # Apache-2.0
|
||||
keystoneauth1>=3.4.0 # Apache-2.0
|
||||
python-novaclient>=9.1.0 # Apache-2.0
|
||||
python-heatclient>=1.10.0 # Apache-2.0
|
||||
|
@ -465,6 +465,17 @@ class HotResource(object):
|
||||
tosca_props[prop.name] = prop.value
|
||||
return tosca_props
|
||||
|
||||
def remove_depends_on(self, depends_on_set):
|
||||
# Remove all depends_on including depends_on_set.
|
||||
for rel, node in self.nodetemplate.relationships.items():
|
||||
for do in depends_on_set:
|
||||
if rel.is_derived_from(do):
|
||||
for hot_resource in self.depends_on_nodes:
|
||||
if node.name == hot_resource.name and \
|
||||
hot_resource in self.depends_on:
|
||||
self.depends_on.remove(hot_resource)
|
||||
break
|
||||
|
||||
@staticmethod
|
||||
def get_all_artifacts(nodetemplate):
|
||||
# workaround bug in the parser
|
||||
|
0
translator/hot/tosca/etsi_nfv/__init__.py
Executable file
0
translator/hot/tosca/etsi_nfv/__init__.py
Executable file
148
translator/hot/tosca/etsi_nfv/tosca_nfv_vdu_compute.py
Executable file
148
translator/hot/tosca/etsi_nfv/tosca_nfv_vdu_compute.py
Executable file
@ -0,0 +1,148 @@
|
||||
#
|
||||
# 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 logging
|
||||
import yaml
|
||||
|
||||
from translator.common.utils import MemoryUnit
|
||||
from translator.hot.syntax.hot_resource import HotResource
|
||||
log = logging.getLogger('heat-translator')
|
||||
|
||||
|
||||
# Name used to dynamically load appropriate map class.
|
||||
TARGET_CLASS_NAME = 'ToscaNfvVduCompute'
|
||||
TOSCA_ATTACHES_TO = 'tosca.relationships.nfv.AttachesTo'
|
||||
depends_on_set = (
|
||||
TOSCA_ATTACHES_TO,
|
||||
)
|
||||
|
||||
|
||||
class ToscaNfvVduCompute(HotResource):
|
||||
"""Translate TOSCA node type tosca.nodes.nfv.Vdu.Compute."""
|
||||
|
||||
toscatype = 'tosca.nodes.nfv.Vdu.Compute'
|
||||
IMAGE = '#ADD_YOUR_IMAGE_HERE'
|
||||
FLAVOR_SUFFIX = '_flavor'
|
||||
|
||||
def __init__(self, nodetemplate, csar_dir=None):
|
||||
super(ToscaNfvVduCompute, self).__init__(
|
||||
nodetemplate,
|
||||
type='OS::Nova::Server',
|
||||
csar_dir=csar_dir)
|
||||
# Associated resources
|
||||
self.assoc_port_resources = []
|
||||
self.virtual_storages = []
|
||||
self.flavor_resource_name = None
|
||||
|
||||
def handle_properties(self):
|
||||
tosca_props = self.get_tosca_props()
|
||||
own_props = {}
|
||||
|
||||
own_props['flavor'] = '{ get_resource: %s%s }' % (
|
||||
self.name,
|
||||
self.FLAVOR_SUFFIX,
|
||||
)
|
||||
|
||||
for key, value in tosca_props.items():
|
||||
if key == 'name':
|
||||
own_props['name'] = value
|
||||
elif key == 'sw_image_data':
|
||||
# Users have to add an image ID or name because heat deprecated
|
||||
# creating an image from a local file.
|
||||
own_props['image'] = '%s' % (
|
||||
self.IMAGE
|
||||
)
|
||||
|
||||
# Multi virtual_storages support
|
||||
requirements = self.nodetemplate.requirements
|
||||
self.virtual_storages = []
|
||||
for req in requirements:
|
||||
vs_val = req.get('virtual_storage')
|
||||
if isinstance(vs_val, dict):
|
||||
if vs_val.get('node') is not None:
|
||||
self.virtual_storages.append(vs_val['node'])
|
||||
else:
|
||||
self.virtual_storages.append(vs_val)
|
||||
dict_rsrcs = self.nodetemplate.templates
|
||||
bdmv2s = []
|
||||
for vs_name in self.virtual_storages:
|
||||
# Supported virtual storage types:
|
||||
# - tosca.nodes.nfv.Vdu.VirtualBlockStorage
|
||||
vs_type = None
|
||||
for rsrc_name, rsrc_info in dict_rsrcs.items():
|
||||
rsrc_type = rsrc_info['type']
|
||||
if rsrc_type == 'tosca.nodes.nfv.Vdu.VirtualBlockStorage':
|
||||
vs_type = rsrc_type
|
||||
|
||||
if vs_type is not None:
|
||||
bdmv2s.append({
|
||||
'volume_id': '{ get_resource: %s }' % (vs_name)
|
||||
})
|
||||
else:
|
||||
log.warning(('Unsupported virtual_storage, '
|
||||
'vdu_name:%s, virtual_storage_name:%s')
|
||||
% (self.name, vs_name))
|
||||
|
||||
if bdmv2s != []:
|
||||
own_props['block_device_mapping_v2'] = bdmv2s
|
||||
|
||||
self.flavor_resource_name = self.name + self.FLAVOR_SUFFIX
|
||||
|
||||
# Remove depends_on
|
||||
self.remove_depends_on(depends_on_set)
|
||||
|
||||
self.properties = own_props
|
||||
|
||||
def handle_expansion(self):
|
||||
hot_resources = []
|
||||
flavor_props = {}
|
||||
|
||||
tosca_capas = self.nodetemplate.get_capability('virtual_compute')
|
||||
tosca_c_props = tosca_capas.get_properties_objects()
|
||||
|
||||
for prop in tosca_c_props:
|
||||
if prop.name == 'virtual_cpu':
|
||||
flavor_props['vcpus'] = prop.value['num_virtual_cpu']
|
||||
elif prop.name == 'virtual_memory':
|
||||
# Convert to MiB
|
||||
flavor_props['ram'] = \
|
||||
MemoryUnit.convert_unit_size_to_num(
|
||||
prop.value['virtual_mem_size'], 'MiB')
|
||||
elif prop.name == 'virtual_local_storage':
|
||||
# Convert to GiB
|
||||
flavor_props['disk'] = \
|
||||
MemoryUnit.convert_unit_size_to_num(
|
||||
prop.value[0]['size_of_storage'], 'GiB')
|
||||
elif prop.name == 'compute_requirements':
|
||||
if prop.value.get('nova_extra_specs') is not None:
|
||||
nova_es = prop.value['nova_extra_specs']
|
||||
try:
|
||||
# Check if it is in yaml format
|
||||
yaml.safe_load(nova_es)
|
||||
flavor_props['extra_specs'] = nova_es
|
||||
except Exception:
|
||||
log.warning(('Unsupported format of '
|
||||
'compute_requirements, '
|
||||
'vdu_name:%s, nova_extra_specs:%s')
|
||||
% (self.name, nova_es))
|
||||
|
||||
hot_resources.append(
|
||||
HotResource(
|
||||
self.nodetemplate,
|
||||
type='OS::Nova::Flavor',
|
||||
name=self.flavor_resource_name,
|
||||
properties=flavor_props,
|
||||
)
|
||||
)
|
||||
|
||||
return hot_resources
|
31
translator/hot/tosca/etsi_nfv/tosca_nfv_vnf.py
Executable file
31
translator/hot/tosca/etsi_nfv/tosca_nfv_vnf.py
Executable file
@ -0,0 +1,31 @@
|
||||
#
|
||||
# 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 translator.hot.syntax.hot_resource import HotResource
|
||||
|
||||
# Name used to dynamically load appropriate map class.
|
||||
TARGET_CLASS_NAME = 'ToscaNfvVnf'
|
||||
|
||||
|
||||
class ToscaNfvVnf(HotResource):
|
||||
"""Translate TOSCA node type tosca.nodes.nfv.VNF."""
|
||||
|
||||
toscatype = 'tosca.nodes.nfv.VNF'
|
||||
|
||||
def __init__(self, nodetemplate, csar_dir):
|
||||
super(ToscaNfvVnf, self).__init__(
|
||||
nodetemplate,
|
||||
csar_dir=csar_dir)
|
||||
|
||||
def handle_properties(self):
|
||||
pass
|
@ -52,7 +52,8 @@ def _generate_type_map():
|
||||
'''
|
||||
|
||||
# Base types directory
|
||||
BASE_PATH = 'translator/hot/tosca'
|
||||
BASE_PATHS = ('translator/hot/tosca',
|
||||
'translator/hot/tosca/etsi_nfv')
|
||||
|
||||
# Custom types directory defined in conf file
|
||||
custom_path = translatorConfig.get_value('DEFAULT',
|
||||
@ -61,7 +62,7 @@ def _generate_type_map():
|
||||
# First need to load the parent module, for example 'contrib.hot',
|
||||
# for all of the dynamically loaded classes.
|
||||
classes = []
|
||||
_load_classes((BASE_PATH, custom_path), classes)
|
||||
_load_classes(BASE_PATHS + (custom_path,), classes)
|
||||
try:
|
||||
types_map = {clazz.toscatype: clazz for clazz in classes}
|
||||
except AttributeError as e:
|
||||
|
202
translator/tests/data/etsi_nfv/etsi_nfv_sol001_common_types.yaml
Normal file
202
translator/tests/data/etsi_nfv/etsi_nfv_sol001_common_types.yaml
Normal file
@ -0,0 +1,202 @@
|
||||
tosca_definitions_version: tosca_simple_yaml_1_2
|
||||
description: ETSI NFV SOL 001 common types definitions version 2.6.1
|
||||
metadata:
|
||||
template_name: etsi_nfv_sol001_common_types
|
||||
template_author: ETSI_NFV
|
||||
template_version: 2.6.1
|
||||
|
||||
data_types:
|
||||
tosca.datatypes.nfv.L2AddressData:
|
||||
derived_from: tosca.datatypes.Root
|
||||
description: Describes the information on the MAC addresses to be assigned to a connection point.
|
||||
properties:
|
||||
mac_address_assignment:
|
||||
type: boolean
|
||||
description: Specifies if the address assignment is the responsibility of management and orchestration function or not. If it is set to True, it is the management and orchestration function responsibility
|
||||
required: true
|
||||
|
||||
tosca.datatypes.nfv.L3AddressData:
|
||||
derived_from: tosca.datatypes.Root
|
||||
description: Provides information about Layer 3 level addressing scheme and parameters applicable to a CP
|
||||
properties:
|
||||
ip_address_assignment:
|
||||
type: boolean
|
||||
description: Specifies if the address assignment is the responsibility of management and orchestration function or not. If it is set to True, it is the management and orchestration function responsibility
|
||||
required: true
|
||||
floating_ip_activated:
|
||||
type: boolean
|
||||
description: Specifies if the floating IP scheme is activated on the Connection Point or not
|
||||
required: true
|
||||
ip_address_type:
|
||||
type: string
|
||||
description: Defines address type. The address type should be aligned with the address type supported by the layer_protocols properties of the parent VnfExtCp
|
||||
required: false
|
||||
constraints:
|
||||
- valid_values: [ ipv4, ipv6 ]
|
||||
number_of_ip_address:
|
||||
type: integer
|
||||
description: Minimum number of IP addresses to be assigned
|
||||
required: false
|
||||
constraints:
|
||||
- greater_than: 0
|
||||
|
||||
tosca.datatypes.nfv.AddressData:
|
||||
derived_from: tosca.datatypes.Root
|
||||
description: Describes information about the addressing scheme and parameters applicable to a CP
|
||||
properties:
|
||||
address_type:
|
||||
type: string
|
||||
description: Describes the type of the address to be assigned to a connection point. The content type shall be aligned with the address type supported by the layerProtocol property of the connection point
|
||||
required: true
|
||||
constraints:
|
||||
- valid_values: [ mac_address, ip_address ]
|
||||
l2_address_data:
|
||||
type: tosca.datatypes.nfv.L2AddressData
|
||||
description: Provides the information on the MAC addresses to be assigned to a connection point.
|
||||
required: false
|
||||
l3_address_data:
|
||||
type: tosca.datatypes.nfv.L3AddressData
|
||||
description: Provides the information on the IP addresses to be assigned to a connection point
|
||||
required: false
|
||||
|
||||
tosca.datatypes.nfv.ConnectivityType:
|
||||
derived_from: tosca.datatypes.Root
|
||||
description: describes additional connectivity information of a virtualLink
|
||||
properties:
|
||||
layer_protocols:
|
||||
type: list
|
||||
description: Identifies the protocol a virtualLink gives access to (ethernet, mpls, odu2, ipv4, ipv6, pseudo-wire).The top layer protocol of the virtualLink protocol stack shall always be provided. The lower layer protocols may be included when there are specific requirements on these layers.
|
||||
required: true
|
||||
entry_schema:
|
||||
type: string
|
||||
constraints:
|
||||
- valid_values: [ ethernet, mpls, odu2, ipv4, ipv6, pseudo-wire ]
|
||||
flow_pattern:
|
||||
type: string
|
||||
description: Identifies the flow pattern of the connectivity
|
||||
required: false
|
||||
constraints:
|
||||
- valid_values: [ line, tree, mesh ]
|
||||
|
||||
tosca.datatypes.nfv.LinkBitrateRequirements:
|
||||
derived_from: tosca.datatypes.Root
|
||||
description: describes the requirements in terms of bitrate for a virtual link
|
||||
properties:
|
||||
root:
|
||||
type: integer # in bits per second
|
||||
description: Specifies the throughput requirement in bits per second of the link (e.g. bitrate of E-Line, root bitrate of E-Tree, aggregate capacity of E-LAN).
|
||||
required: true
|
||||
constraints:
|
||||
- greater_or_equal: 0
|
||||
leaf:
|
||||
type: integer # in bits per second
|
||||
description: Specifies the throughput requirement in bits per second of leaf connections to the link when applicable to the connectivity type (e.g. for E-Tree and E LAN branches).
|
||||
required: false
|
||||
constraints:
|
||||
- greater_or_equal: 0
|
||||
|
||||
tosca.datatypes.nfv.CpProtocolData:
|
||||
derived_from: tosca.datatypes.Root
|
||||
description: Describes and associates the protocol layer that a CP uses together with other protocol and connection point information
|
||||
properties:
|
||||
associated_layer_protocol:
|
||||
type: string
|
||||
required: true
|
||||
description: One of the values of the property layer_protocols of the CP
|
||||
constraints:
|
||||
- valid_values: [ ethernet, mpls, odu2, ipv4, ipv6, pseudo-wire ]
|
||||
address_data:
|
||||
type: list
|
||||
description: Provides information on the addresses to be assigned to the CP
|
||||
entry_schema:
|
||||
type: tosca.datatypes.nfv.AddressData
|
||||
required: false
|
||||
|
||||
tosca.datatypes.nfv.VnfProfile:
|
||||
derived_from: tosca.datatypes.Root
|
||||
description: describes a profile for instantiating VNFs of a particular NS DF according to a specific VNFD and VNF DF.
|
||||
properties:
|
||||
instantiation_level:
|
||||
type: string
|
||||
description: Identifier of the instantiation level of the VNF DF to be used for instantiation. If not present, the default instantiation level as declared in the VNFD shall be used.
|
||||
required: false
|
||||
min_number_of_instances:
|
||||
type: integer
|
||||
description: Minimum number of instances of the VNF based on this VNFD that is permitted to exist for this VnfProfile.
|
||||
required: true
|
||||
constraints:
|
||||
- greater_or_equal: 0
|
||||
max_number_of_instances:
|
||||
type: integer
|
||||
description: Maximum number of instances of the VNF based on this VNFD that is permitted to exist for this VnfProfile.
|
||||
required: true
|
||||
constraints:
|
||||
- greater_or_equal: 0
|
||||
|
||||
tosca.datatypes.nfv.Qos:
|
||||
derived_from: tosca.datatypes.Root
|
||||
description: describes QoS data for a given VL used in a VNF deployment flavour
|
||||
properties:
|
||||
latency:
|
||||
type: scalar-unit.time #Number
|
||||
description: Specifies the maximum latency
|
||||
required: true
|
||||
constraints:
|
||||
- greater_than: 0 s
|
||||
packet_delay_variation:
|
||||
type: scalar-unit.time #Number
|
||||
description: Specifies the maximum jitter
|
||||
required: true
|
||||
constraints:
|
||||
- greater_or_equal: 0 s
|
||||
packet_loss_ratio:
|
||||
type: float
|
||||
description: Specifies the maximum packet loss ratio
|
||||
required: false
|
||||
constraints:
|
||||
- in_range: [ 0.0, 1.0 ]
|
||||
|
||||
capability_types:
|
||||
tosca.capabilities.nfv.VirtualLinkable:
|
||||
derived_from: tosca.capabilities.Node
|
||||
description: A node type that includes the VirtualLinkable capability indicates that it can be pointed by tosca.relationships.nfv.VirtualLinksTo relationship type
|
||||
|
||||
relationship_types:
|
||||
tosca.relationships.nfv.VirtualLinksTo:
|
||||
derived_from: tosca.relationships.DependsOn
|
||||
description: Represents an association relationship between the VduCp and VnfVirtualLink node types
|
||||
valid_target_types: [ tosca.capabilities.nfv.VirtualLinkable ]
|
||||
|
||||
node_types:
|
||||
tosca.nodes.nfv.Cp:
|
||||
derived_from: tosca.nodes.Root
|
||||
description: Provides information regarding the purpose of the connection point
|
||||
properties:
|
||||
layer_protocols:
|
||||
type: list
|
||||
description: Identifies which protocol the connection point uses for connectivity purposes
|
||||
required: true
|
||||
entry_schema:
|
||||
type: string
|
||||
constraints:
|
||||
- valid_values: [ ethernet, mpls, odu2, ipv4, ipv6, pseudo-wire ]
|
||||
role: #Name in ETSI NFV IFA011 v0.7.3: cpRole
|
||||
type: string
|
||||
description: Identifies the role of the port in the context of the traffic flow patterns in the VNF or parent NS
|
||||
required: false
|
||||
constraints:
|
||||
- valid_values: [ root, leaf ]
|
||||
description:
|
||||
type: string
|
||||
description: Provides human-readable information on the purpose of the connection point
|
||||
required: false
|
||||
protocol:
|
||||
type: list
|
||||
description: Provides information on the addresses to be assigned to the connection point(s) instantiated from this Connection Point Descriptor
|
||||
required: false
|
||||
entry_schema:
|
||||
type: tosca.datatypes.nfv.CpProtocolData
|
||||
trunk_mode:
|
||||
type: boolean
|
||||
description: Provides information about whether the CP instantiated from this Cp is in Trunk mode (802.1Q or other), When operating in "trunk mode", the Cp is capable of carrying traffic for several VLANs. Absence of this property implies that trunkMode is not configured for the Cp i.e. It is equivalent to boolean value "false".
|
||||
required: false
|
1465
translator/tests/data/etsi_nfv/etsi_nfv_sol001_vnfd_types.yaml
Normal file
1465
translator/tests/data/etsi_nfv/etsi_nfv_sol001_vnfd_types.yaml
Normal file
File diff suppressed because it is too large
Load Diff
44
translator/tests/data/etsi_nfv/tosca_nfv_vdu.yaml
Normal file
44
translator/tests/data/etsi_nfv/tosca_nfv_vdu.yaml
Normal file
@ -0,0 +1,44 @@
|
||||
tosca_definitions_version: tosca_simple_yaml_1_2
|
||||
|
||||
description: >
|
||||
Template for deploying one VDU.
|
||||
|
||||
imports:
|
||||
- etsi_nfv_sol001_common_types.yaml
|
||||
- etsi_nfv_sol001_vnfd_types.yaml
|
||||
|
||||
topology_template:
|
||||
node_templates:
|
||||
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: 1
|
||||
sw_image_data:
|
||||
name: Software of VDU1
|
||||
version: '0.4.0'
|
||||
checksum:
|
||||
algorithm: sha-256
|
||||
hash: b9c3036539fd7a5f87a1bf38eb05fdde8b556a1a7e664dbeda90ed3cd74b4f9d
|
||||
container_format: bare
|
||||
disk_format: qcow2
|
||||
min_disk: 1 GiB
|
||||
size: 1 GiB
|
||||
|
||||
artifacts:
|
||||
sw_image:
|
||||
type: tosca.artifacts.nfv.SwImage
|
||||
file: Files/images/cirros-0.4.0-x86_64-disk.img
|
||||
|
||||
capabilities:
|
||||
virtual_compute:
|
||||
properties:
|
||||
virtual_memory:
|
||||
virtual_mem_size: 512 MiB
|
||||
virtual_cpu:
|
||||
num_virtual_cpu: 1
|
||||
virtual_local_storage:
|
||||
- size_of_storage: 1 GiB
|
@ -0,0 +1,35 @@
|
||||
tosca_definitions_version: tosca_simple_yaml_1_2
|
||||
|
||||
description: >
|
||||
Template for deploying one VDU,
|
||||
and define capabilities including compute_requirements.
|
||||
|
||||
imports:
|
||||
- etsi_nfv_sol001_common_types.yaml
|
||||
- etsi_nfv_sol001_vnfd_types.yaml
|
||||
|
||||
topology_template:
|
||||
node_templates:
|
||||
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: 1
|
||||
capabilities:
|
||||
virtual_compute:
|
||||
properties:
|
||||
virtual_memory:
|
||||
virtual_mem_size: 512 MiB
|
||||
virtual_cpu:
|
||||
num_virtual_cpu: 1
|
||||
virtual_local_storage:
|
||||
- size_of_storage: 1 GiB
|
||||
compute_requirements:
|
||||
nova_extra_specs:
|
||||
'{
|
||||
"pci_passthrough:alias": "vf:1",
|
||||
"hw:cpu_policy": "shared"
|
||||
}'
|
@ -0,0 +1,31 @@
|
||||
tosca_definitions_version: tosca_simple_yaml_1_2
|
||||
|
||||
description: >
|
||||
Template for deploying one VDU,
|
||||
and define capabilities including invalid compute_requirements.
|
||||
|
||||
imports:
|
||||
- etsi_nfv_sol001_common_types.yaml
|
||||
- etsi_nfv_sol001_vnfd_types.yaml
|
||||
|
||||
topology_template:
|
||||
node_templates:
|
||||
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: 1
|
||||
capabilities:
|
||||
virtual_compute:
|
||||
properties:
|
||||
virtual_memory:
|
||||
virtual_mem_size: 512 MiB
|
||||
virtual_cpu:
|
||||
num_virtual_cpu: 1
|
||||
virtual_local_storage:
|
||||
- size_of_storage: 1 GiB
|
||||
compute_requirements:
|
||||
nova_extra_specs: 'dummy: ]['
|
@ -0,0 +1,34 @@
|
||||
tosca_definitions_version: tosca_simple_yaml_1_2
|
||||
|
||||
description: >
|
||||
Template for deploying one VDU,
|
||||
and define capabilities including non translated property.
|
||||
|
||||
imports:
|
||||
- etsi_nfv_sol001_common_types.yaml
|
||||
- etsi_nfv_sol001_vnfd_types.yaml
|
||||
|
||||
topology_template:
|
||||
node_templates:
|
||||
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: 1
|
||||
|
||||
capabilities:
|
||||
virtual_compute:
|
||||
properties:
|
||||
virtual_memory:
|
||||
virtual_mem_size: 512 MiB
|
||||
virtual_cpu:
|
||||
num_virtual_cpu: 1
|
||||
virtual_local_storage:
|
||||
- size_of_storage: 1 GiB
|
||||
logical_node:
|
||||
logical_node_1:
|
||||
logical_node_requirements:
|
||||
custom: test
|
@ -0,0 +1,40 @@
|
||||
tosca_definitions_version: tosca_simple_yaml_1_2
|
||||
|
||||
description: >
|
||||
Template for VDU with unsupported storage type.
|
||||
|
||||
imports:
|
||||
- etsi_nfv_sol001_common_types.yaml
|
||||
- etsi_nfv_sol001_vnfd_types.yaml
|
||||
|
||||
topology_template:
|
||||
node_templates:
|
||||
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: 1
|
||||
|
||||
capabilities:
|
||||
virtual_compute:
|
||||
properties:
|
||||
virtual_memory:
|
||||
virtual_mem_size: 512 MiB
|
||||
virtual_cpu:
|
||||
num_virtual_cpu: 1
|
||||
virtual_local_storage:
|
||||
- size_of_storage: 1 GiB
|
||||
requirements:
|
||||
- virtual_storage: UnsupportedStorage
|
||||
|
||||
UnsupportedStorage:
|
||||
type: tosca.nodes.nfv.Vdu.Compute
|
||||
properties:
|
||||
name: UnsupportedStorage
|
||||
description: UnsupportedStorage node
|
||||
vdu_profile:
|
||||
min_number_of_instances: 1
|
||||
max_number_of_instances: 1
|
29
translator/tests/data/etsi_nfv/tosca_nfv_vnf.yaml
Normal file
29
translator/tests/data/etsi_nfv/tosca_nfv_vnf.yaml
Normal file
@ -0,0 +1,29 @@
|
||||
tosca_definitions_version: tosca_simple_yaml_1_2
|
||||
|
||||
description: >
|
||||
Template for deploying one VNF.
|
||||
|
||||
imports:
|
||||
- etsi_nfv_sol001_common_types.yaml
|
||||
- etsi_nfv_sol001_vnfd_types.yaml
|
||||
|
||||
topology_template:
|
||||
inputs:
|
||||
selected_flavour:
|
||||
type: string
|
||||
default: simple
|
||||
description: VNF deployment flavour selected by the consumer. It is provided in the API
|
||||
|
||||
node_templates:
|
||||
VNF:
|
||||
type: tosca.nodes.nfv.VNF
|
||||
properties:
|
||||
flavour_id: { get_input: selected_flavour }
|
||||
descriptor_id: b1bb0ce7-ebca-4fa7-95ed-4840d70a1177
|
||||
provider: Sample company
|
||||
product_name: Sample VNF
|
||||
software_version: '1.0'
|
||||
descriptor_version: '1.0'
|
||||
vnfm_info:
|
||||
- 00:sampleVNFM
|
||||
flavour_description: A simple flavour
|
18
translator/tests/data/hot_output/etsi_nfv/hot_nfv_vdu.yaml
Normal file
18
translator/tests/data/hot_output/etsi_nfv/hot_nfv_vdu.yaml
Normal file
@ -0,0 +1,18 @@
|
||||
heat_template_version: 2013-05-23
|
||||
description: >
|
||||
Template for deploying one VDU.
|
||||
parameters: {}
|
||||
resources:
|
||||
VDU1:
|
||||
type: OS::Nova::Server
|
||||
properties:
|
||||
flavor: { get_resource: VDU1_flavor }
|
||||
name: VDU1
|
||||
image: #ADD_YOUR_IMAGE_HERE
|
||||
VDU1_flavor:
|
||||
type: OS::Nova::Flavor
|
||||
properties:
|
||||
ram: 512
|
||||
vcpus: 1
|
||||
disk: 1
|
||||
outputs: {}
|
@ -0,0 +1,19 @@
|
||||
heat_template_version: 2013-05-23
|
||||
description: >
|
||||
Template for deploying one VDU,
|
||||
and define capabilities including compute_requirements.
|
||||
parameters: {}
|
||||
resources:
|
||||
VDU1:
|
||||
type: OS::Nova::Server
|
||||
properties:
|
||||
flavor: { get_resource: VDU1_flavor }
|
||||
name: VDU1
|
||||
VDU1_flavor:
|
||||
type: OS::Nova::Flavor
|
||||
properties:
|
||||
ram: 512
|
||||
vcpus: 1
|
||||
disk: 1
|
||||
extra_specs: { "pci_passthrough:alias": "vf:1", "hw:cpu_policy": "shared" }
|
||||
outputs: {}
|
@ -0,0 +1,18 @@
|
||||
heat_template_version: 2013-05-23
|
||||
description: >
|
||||
Template for deploying one VDU,
|
||||
and define capabilities including invalid compute_requirements.
|
||||
parameters: {}
|
||||
resources:
|
||||
VDU1:
|
||||
type: OS::Nova::Server
|
||||
properties:
|
||||
flavor: { get_resource: VDU1_flavor }
|
||||
name: VDU1
|
||||
VDU1_flavor:
|
||||
type: OS::Nova::Flavor
|
||||
properties:
|
||||
ram: 512
|
||||
vcpus: 1
|
||||
disk: 1
|
||||
outputs: {}
|
@ -0,0 +1,18 @@
|
||||
heat_template_version: 2013-05-23
|
||||
description: >
|
||||
Template for deploying one VDU,
|
||||
and define capabilities including non translated property.
|
||||
parameters: {}
|
||||
resources:
|
||||
VDU1:
|
||||
type: OS::Nova::Server
|
||||
properties:
|
||||
flavor: { get_resource: VDU1_flavor }
|
||||
name: VDU1
|
||||
VDU1_flavor:
|
||||
type: OS::Nova::Flavor
|
||||
properties:
|
||||
ram: 512
|
||||
vcpus: 1
|
||||
disk: 1
|
||||
outputs: {}
|
@ -0,0 +1,24 @@
|
||||
heat_template_version: 2013-05-23
|
||||
description: >
|
||||
Template for VDU with unsupported storage type.
|
||||
parameters: {}
|
||||
resources:
|
||||
VDU1:
|
||||
type: OS::Nova::Server
|
||||
properties:
|
||||
flavor: { get_resource: VDU1_flavor }
|
||||
name: VDU1
|
||||
UnsupportedStorage:
|
||||
type: OS::Nova::Server
|
||||
properties:
|
||||
flavor: { get_resource: UnsupportedStorage_flavor }
|
||||
name: UnsupportedStorage
|
||||
VDU1_flavor:
|
||||
type: OS::Nova::Flavor
|
||||
properties:
|
||||
ram: 512
|
||||
vcpus: 1
|
||||
disk: 1
|
||||
UnsupportedStorage_flavor:
|
||||
type: OS::Nova::Flavor
|
||||
outputs: {}
|
11
translator/tests/data/hot_output/etsi_nfv/hot_nfv_vnf.yaml
Normal file
11
translator/tests/data/hot_output/etsi_nfv/hot_nfv_vnf.yaml
Normal file
@ -0,0 +1,11 @@
|
||||
heat_template_version: 2013-05-23
|
||||
description: >
|
||||
Template for deploying one VNF.
|
||||
parameters:
|
||||
selected_flavour:
|
||||
type: string
|
||||
description: VNF deployment flavour selected by the consumer. It is provided in
|
||||
the API
|
||||
default: simple
|
||||
resources: {}
|
||||
outputs: {}
|
114
translator/tests/test_etsi_tosca_hot_translation.py
Normal file
114
translator/tests/test_etsi_tosca_hot_translation.py
Normal file
@ -0,0 +1,114 @@
|
||||
# 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 json
|
||||
import os
|
||||
|
||||
from toscaparser.common.exception import ExceptionCollector
|
||||
from toscaparser.utils.gettextutils import _
|
||||
from translator.common.utils import TranslationUtils
|
||||
from translator.tests.base import TestCase
|
||||
|
||||
|
||||
class EtsiToscaHotTranslationTest(TestCase):
|
||||
|
||||
def _test_successful_translation(self, tosca_file, hot_files, params=None):
|
||||
if not params:
|
||||
params = {}
|
||||
if not isinstance(hot_files, list):
|
||||
hot_files = [hot_files]
|
||||
diff = TranslationUtils.compare_tosca_translation_with_hot(tosca_file,
|
||||
hot_files,
|
||||
params)
|
||||
self.assertEqual({}, diff, '<difference> : ' +
|
||||
json.dumps(diff, indent=4, separators=(', ', ': ')))
|
||||
|
||||
def _test_failed_translation(self, tosca_file, hot_file, params, msg,
|
||||
msg_path, error_raise, error_collect):
|
||||
if msg_path:
|
||||
path = os.path.normpath(os.path.join(
|
||||
os.path.dirname(os.path.realpath(__file__)), tosca_file))
|
||||
msg = msg % path
|
||||
self.assertRaises(
|
||||
error_raise,
|
||||
TranslationUtils.compare_tosca_translation_with_hot,
|
||||
tosca_file, hot_file, params)
|
||||
ExceptionCollector.assertExceptionMessage(error_collect, msg)
|
||||
|
||||
def test_hot_translate_etsi_nfv_vnf(self):
|
||||
tosca_file = '../tests/data/etsi_nfv/' \
|
||||
'tosca_nfv_vnf.yaml'
|
||||
hot_files = [
|
||||
'../tests/data/hot_output/etsi_nfv/'
|
||||
'hot_nfv_vnf.yaml',
|
||||
]
|
||||
self._test_successful_translation(tosca_file, hot_files, params={})
|
||||
|
||||
def test_hot_translate_etsi_nfv_vdu(self):
|
||||
tosca_file = '../tests/data/etsi_nfv/' \
|
||||
'tosca_nfv_vdu.yaml'
|
||||
hot_files = [
|
||||
'../tests/data/hot_output/etsi_nfv/'
|
||||
'hot_nfv_vdu.yaml',
|
||||
]
|
||||
self._test_successful_translation(tosca_file, hot_files, params={})
|
||||
|
||||
def test_hot_translate_etsi_nfv_vdu_with_compute_requirements(self):
|
||||
tosca_file = '../tests/data/etsi_nfv/' \
|
||||
'tosca_nfv_vdu_with_compute_requirements.yaml'
|
||||
hot_files = [
|
||||
'../tests/data/hot_output/etsi_nfv/'
|
||||
'hot_nfv_vdu_with_compute_requirements.yaml',
|
||||
]
|
||||
self._test_successful_translation(tosca_file, hot_files, params={})
|
||||
|
||||
def test_hot_translate_etsi_nfv_vdu_with_invalid_compute_requirements(
|
||||
self):
|
||||
tosca_file = '../tests/data/etsi_nfv/' \
|
||||
'tosca_nfv_vdu_with_invalid_compute_requirements.yaml'
|
||||
hot_files = [
|
||||
'../tests/data/hot_output/etsi_nfv/'
|
||||
'hot_nfv_vdu_with_invalid_compute_requirements.yaml',
|
||||
]
|
||||
expected_msg = _('Unsupported format of '
|
||||
'compute_requirements, '
|
||||
'vdu_name:VDU1, nova_extra_specs:dummy: ][')
|
||||
self._test_successful_translation(tosca_file, hot_files, params={})
|
||||
self.assertIn(
|
||||
expected_msg,
|
||||
self.log_fixture.output
|
||||
)
|
||||
|
||||
def test_hot_translate_etsi_nfv_vdu_with_logical_node(self):
|
||||
tosca_file = '../tests/data/etsi_nfv/' \
|
||||
'tosca_nfv_vdu_with_logical_node.yaml'
|
||||
hot_files = [
|
||||
'../tests/data/hot_output/etsi_nfv/'
|
||||
'hot_nfv_vdu_with_logical_node.yaml',
|
||||
]
|
||||
self._test_successful_translation(tosca_file, hot_files, params={})
|
||||
|
||||
def test_hot_translate_etsi_nfv_vdu_with_unsupported_storage(self):
|
||||
tosca_file = '../tests/data/etsi_nfv/' \
|
||||
'tosca_nfv_vdu_with_unsupported_storage.yaml'
|
||||
hot_files = [
|
||||
'../tests/data/hot_output/etsi_nfv/'
|
||||
'hot_nfv_vdu_with_unsupported_storage.yaml',
|
||||
]
|
||||
expected_msg = _('Unsupported virtual_storage, '
|
||||
'vdu_name:VDU1, '
|
||||
'virtual_storage_name:UnsupportedStorage')
|
||||
self._test_successful_translation(tosca_file, hot_files, params={})
|
||||
self.assertIn(
|
||||
expected_msg,
|
||||
self.log_fixture.output
|
||||
)
|
@ -34,7 +34,9 @@ class TranslateNodeTemplatesTest(TestCase):
|
||||
'tosca.policies.Placement',
|
||||
'tosca.policies.Reservation',
|
||||
'tosca.policies.Scaling',
|
||||
'tosca.policies.Scaling.Cluster'
|
||||
'tosca.policies.Scaling.Cluster',
|
||||
'tosca.nodes.nfv.VNF',
|
||||
'tosca.nodes.nfv.Vdu.Compute'
|
||||
]
|
||||
actual_type_list = list(_generate_type_map())
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user