ETSI-NFV SOL 001 translation: CP,VL
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.VduCp - tosca.nodes.nfv.VnfVirtualLink [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 Change-Id: I28b4ff67b74e7d5ad4264acb93cd8c292b91a0d4 Story: 2006372 Task: 37620
This commit is contained in:
parent
4833eb5e92
commit
6f94614c71
117
translator/hot/tosca/etsi_nfv/tosca_nfv_vducp.py
Normal file
117
translator/hot/tosca/etsi_nfv/tosca_nfv_vducp.py
Normal file
@ -0,0 +1,117 @@
|
|||||||
|
#
|
||||||
|
# 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
|
||||||
|
|
||||||
|
from translator.hot.syntax.hot_resource import HotResource
|
||||||
|
log = logging.getLogger('heat-translator')
|
||||||
|
|
||||||
|
|
||||||
|
# Name used to dynamically load appropriate map class.
|
||||||
|
TARGET_CLASS_NAME = 'ToscaNfvVducp'
|
||||||
|
TOSCA_LINKS_TO = 'tosca.relationships.nfv.VirtualLinksTo'
|
||||||
|
TOSCA_BINDS_TO = 'tosca.relationships.nfv.VirtualBindsTo'
|
||||||
|
depends_on_set = (
|
||||||
|
TOSCA_LINKS_TO,
|
||||||
|
TOSCA_BINDS_TO,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class ToscaNfvVducp(HotResource):
|
||||||
|
"""Translate TOSCA node type tosca.nodes.nfv.VduCp."""
|
||||||
|
|
||||||
|
toscatype = 'tosca.nodes.nfv.VduCp'
|
||||||
|
EXTERNAL_VL = '#ADD_YOUR_NETWORK_HERE'
|
||||||
|
|
||||||
|
def __init__(self, nodetemplate, csar_dir=None):
|
||||||
|
super(ToscaNfvVducp, self).__init__(
|
||||||
|
nodetemplate,
|
||||||
|
type='OS::Neutron::Port',
|
||||||
|
csar_dir=csar_dir)
|
||||||
|
|
||||||
|
# Default order
|
||||||
|
self.order = 0
|
||||||
|
|
||||||
|
# Extract virtual_link and virtual_binding
|
||||||
|
self.virtual_link = None
|
||||||
|
self.virtual_binding = None
|
||||||
|
requirements = self.nodetemplate.requirements
|
||||||
|
for req in requirements:
|
||||||
|
if 'virtual_link' in req:
|
||||||
|
vl_val = req.get('virtual_link')
|
||||||
|
if isinstance(vl_val, dict):
|
||||||
|
self.virtual_link = vl_val.get('node')
|
||||||
|
else:
|
||||||
|
self.virtual_link = vl_val
|
||||||
|
elif 'virtual_binding' in req:
|
||||||
|
self.virtual_binding = req.get('virtual_binding')
|
||||||
|
|
||||||
|
def _generate_networks_for_compute(self, port_resources):
|
||||||
|
'''Generate compute networks property list from the port resources.'''
|
||||||
|
networks = []
|
||||||
|
for resource in port_resources:
|
||||||
|
networks.append({'port': '{ get_resource: %s }' % (resource.name)})
|
||||||
|
return networks
|
||||||
|
|
||||||
|
def _insert_sorted_resource(self, resources, resource):
|
||||||
|
'''Insert a resource in the list of resources and keep the order.'''
|
||||||
|
lo = 0
|
||||||
|
hi = len(resources)
|
||||||
|
while lo < hi:
|
||||||
|
mid = (lo + hi) // 2
|
||||||
|
if resource.order < resources[mid].order:
|
||||||
|
hi = mid
|
||||||
|
else:
|
||||||
|
lo = mid + 1
|
||||||
|
resources.insert(lo, resource)
|
||||||
|
|
||||||
|
def handle_properties(self):
|
||||||
|
tosca_props = self.get_tosca_props()
|
||||||
|
own_props = {}
|
||||||
|
|
||||||
|
if self.virtual_link:
|
||||||
|
own_props['network'] = '{ get_resource: %s }' % (
|
||||||
|
self.virtual_link
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
# If no virtual_binding is specified in VNFD, users
|
||||||
|
# have to input external VL given in instantiation VNF request.
|
||||||
|
own_props['network'] = '%s' % (
|
||||||
|
self.EXTERNAL_VL
|
||||||
|
)
|
||||||
|
|
||||||
|
for key, value in tosca_props.items():
|
||||||
|
if key == 'order':
|
||||||
|
self.order = value
|
||||||
|
elif key == 'vnic_type':
|
||||||
|
own_props['binding:vnic_type'] = value
|
||||||
|
|
||||||
|
# Remove depends_on
|
||||||
|
self.remove_depends_on(depends_on_set)
|
||||||
|
|
||||||
|
binds_to = None
|
||||||
|
for rel, node in self.nodetemplate.relationships.items():
|
||||||
|
# Check for BindsTo relationship. If found add network to the
|
||||||
|
# network property of the corresponding compute resource
|
||||||
|
if not binds_to and rel.is_derived_from(TOSCA_BINDS_TO):
|
||||||
|
binds_to = node
|
||||||
|
for hot_resource in self.depends_on_nodes:
|
||||||
|
if binds_to.name == hot_resource.name:
|
||||||
|
port_rsrcs = hot_resource.assoc_port_resources
|
||||||
|
self._insert_sorted_resource(port_rsrcs, self)
|
||||||
|
networks = \
|
||||||
|
self._generate_networks_for_compute(port_rsrcs)
|
||||||
|
hot_resource.properties['networks'] = networks
|
||||||
|
break
|
||||||
|
|
||||||
|
self.properties = own_props
|
167
translator/hot/tosca/etsi_nfv/tosca_nfv_vnfvirtuallink.py
Normal file
167
translator/hot/tosca/etsi_nfv/tosca_nfv_vnfvirtuallink.py
Normal file
@ -0,0 +1,167 @@
|
|||||||
|
#
|
||||||
|
# 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
|
||||||
|
|
||||||
|
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 = 'ToscaNfvVnfVirtualLink'
|
||||||
|
|
||||||
|
|
||||||
|
class ToscaNfvVnfVirtualLink(HotResource):
|
||||||
|
"""Translate TOSCA node type tosca.nodes.nfv.VnfVirtualLink."""
|
||||||
|
|
||||||
|
toscatype = 'tosca.nodes.nfv.VnfVirtualLink'
|
||||||
|
SUBNET_SUFFIX = '_subnet'
|
||||||
|
QOSPOLICY_SUFFIX = '_qospolicy'
|
||||||
|
BANDWIDTH_SUFFIX = '_bandwidth'
|
||||||
|
ip_map = {
|
||||||
|
'ipv4': '4',
|
||||||
|
'ipv6': '6',
|
||||||
|
}
|
||||||
|
|
||||||
|
def __init__(self, nodetemplate, csar_dir=None):
|
||||||
|
|
||||||
|
# Check if it is an IP network
|
||||||
|
tosca_props = {}
|
||||||
|
for prop in nodetemplate.get_properties_objects():
|
||||||
|
tosca_props[prop.name] = prop.value
|
||||||
|
|
||||||
|
lp = tosca_props.get('connectivity_type').get('layer_protocols')
|
||||||
|
self.ip_protocol = list(set(self.ip_map.keys()) & set(lp))
|
||||||
|
|
||||||
|
# Branch by IP or not
|
||||||
|
if self.ip_protocol:
|
||||||
|
super(ToscaNfvVnfVirtualLink, self).__init__(
|
||||||
|
nodetemplate,
|
||||||
|
type='OS::Neutron::Net',
|
||||||
|
csar_dir=csar_dir
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
super(ToscaNfvVnfVirtualLink, self).__init__(
|
||||||
|
nodetemplate,
|
||||||
|
csar_dir=csar_dir
|
||||||
|
)
|
||||||
|
log.warning(('Unsupported layer_protocols, '
|
||||||
|
'virtual_link_name:%s, protocol_name:%s')
|
||||||
|
% (self.name, lp))
|
||||||
|
|
||||||
|
def handle_properties(self):
|
||||||
|
|
||||||
|
# Branch by IP or not
|
||||||
|
if self.ip_protocol:
|
||||||
|
tosca_props = self.get_tosca_props()
|
||||||
|
own_props = {}
|
||||||
|
|
||||||
|
self.is_leaf = False
|
||||||
|
for key, value in tosca_props.items():
|
||||||
|
if key == 'vl_profile':
|
||||||
|
mbr = value['max_bitrate_requirements']
|
||||||
|
if 'leaf' in mbr:
|
||||||
|
max_bps = mbr['leaf']
|
||||||
|
# Convert to KiB
|
||||||
|
self.max_kbps = \
|
||||||
|
max_bps / MemoryUnit.UNIT_SIZE_DICT['KiB']
|
||||||
|
self.is_leaf = True
|
||||||
|
else:
|
||||||
|
log.warning('Can not set the required properties '
|
||||||
|
'max_kbps on HOT.'
|
||||||
|
'virtual_link_name:%s' % self.name)
|
||||||
|
|
||||||
|
if self.is_leaf:
|
||||||
|
own_props['qos_policy'] = '{ get_resource: %s%s }' % (
|
||||||
|
self.name,
|
||||||
|
self.QOSPOLICY_SUFFIX,
|
||||||
|
)
|
||||||
|
|
||||||
|
self.properties = own_props
|
||||||
|
|
||||||
|
else:
|
||||||
|
pass
|
||||||
|
|
||||||
|
def handle_expansion(self):
|
||||||
|
hot_resources = []
|
||||||
|
|
||||||
|
# Branch by IP or not
|
||||||
|
if self.ip_protocol:
|
||||||
|
tosca_props = self.get_tosca_props()
|
||||||
|
|
||||||
|
# subnet props
|
||||||
|
subnet_props = {}
|
||||||
|
subnet_props['ip_version'] = self.ip_map.get(self.ip_protocol[0])
|
||||||
|
subnet_props['network'] = '{ get_resource: %s }' % (self.name)
|
||||||
|
|
||||||
|
for key, value in tosca_props.items():
|
||||||
|
if key == 'vl_profile':
|
||||||
|
if 'virtual_link_protocol_data' in value:
|
||||||
|
vlpd = value['virtual_link_protocol_data']
|
||||||
|
if 'l3_protocol_data' in vlpd[0]:
|
||||||
|
l3pd = vlpd[0]['l3_protocol_data']
|
||||||
|
subnet_props['cidr'] = l3pd['cidr']
|
||||||
|
|
||||||
|
subnet_resource_name = self.name + self.SUBNET_SUFFIX
|
||||||
|
|
||||||
|
hot_resources.append(
|
||||||
|
HotResource(
|
||||||
|
self.nodetemplate,
|
||||||
|
type='OS::Neutron::Subnet',
|
||||||
|
name=subnet_resource_name,
|
||||||
|
properties=subnet_props,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
# qospolicy_props props
|
||||||
|
qospolicy_props = {}
|
||||||
|
|
||||||
|
qospolicy_resource_name = self.name + self.QOSPOLICY_SUFFIX
|
||||||
|
|
||||||
|
# bandwidth props
|
||||||
|
bandwidth_props = {}
|
||||||
|
bandwidth_props['policy'] = '{ get_resource: %s%s }' % (
|
||||||
|
self.name,
|
||||||
|
self.QOSPOLICY_SUFFIX,
|
||||||
|
)
|
||||||
|
|
||||||
|
bandwidth_resource_name = self.name + self.BANDWIDTH_SUFFIX
|
||||||
|
|
||||||
|
# Create QoSPolicy and QoSBandwidthLimitRule resources
|
||||||
|
# only when max_bitrate_requirements has leaf property.
|
||||||
|
if self.is_leaf:
|
||||||
|
hot_resources.append(
|
||||||
|
HotResource(
|
||||||
|
self.nodetemplate,
|
||||||
|
type='OS::Neutron::QoSPolicy',
|
||||||
|
name=qospolicy_resource_name,
|
||||||
|
properties=qospolicy_props,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
bandwidth_props['max_kbps'] = self.max_kbps
|
||||||
|
hot_resources.append(
|
||||||
|
HotResource(
|
||||||
|
self.nodetemplate,
|
||||||
|
type='OS::Neutron::QoSBandwidthLimitRule',
|
||||||
|
name=bandwidth_resource_name,
|
||||||
|
properties=bandwidth_props,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
else:
|
||||||
|
pass
|
||||||
|
|
||||||
|
return hot_resources
|
@ -218,9 +218,7 @@ class TranslateNodeTemplates(object):
|
|||||||
suffix = 0
|
suffix = 0
|
||||||
# Copy the TOSCA graph: nodetemplate
|
# Copy the TOSCA graph: nodetemplate
|
||||||
for node in self.nodetemplates:
|
for node in self.nodetemplates:
|
||||||
base_type = HotResource.get_base_type_str(node.type_definition)
|
base_type = self._get_supported_type(node)
|
||||||
if base_type not in TOSCA_TO_HOT_TYPE:
|
|
||||||
raise UnsupportedTypeError(type=_('%s') % base_type)
|
|
||||||
hot_node = TOSCA_TO_HOT_TYPE[base_type](node,
|
hot_node = TOSCA_TO_HOT_TYPE[base_type](node,
|
||||||
csar_dir=self.csar_dir)
|
csar_dir=self.csar_dir)
|
||||||
self.hot_resources.append(hot_node)
|
self.hot_resources.append(hot_node)
|
||||||
@ -408,6 +406,17 @@ class TranslateNodeTemplates(object):
|
|||||||
|
|
||||||
return self.hot_resources
|
return self.hot_resources
|
||||||
|
|
||||||
|
def _get_supported_type(self, original_node):
|
||||||
|
# trace parent types until finding a supported type
|
||||||
|
node = original_node
|
||||||
|
node_type = original_node.type
|
||||||
|
while node_type not in TOSCA_TO_HOT_TYPE:
|
||||||
|
node = node.parent_type
|
||||||
|
if node is None:
|
||||||
|
raise UnsupportedTypeError(type=_('%s') % original_node.type)
|
||||||
|
node_type = node.type
|
||||||
|
return node_type
|
||||||
|
|
||||||
def translate_param_value(self, param_value, resource):
|
def translate_param_value(self, param_value, resource):
|
||||||
tosca_template = None
|
tosca_template = None
|
||||||
if resource:
|
if resource:
|
||||||
|
82
translator/tests/data/etsi_nfv/tosca_nfv_check_cp_order.yaml
Normal file
82
translator/tests/data/etsi_nfv/tosca_nfv_check_cp_order.yaml
Normal file
@ -0,0 +1,82 @@
|
|||||||
|
tosca_definitions_version: tosca_simple_yaml_1_2
|
||||||
|
|
||||||
|
description: >
|
||||||
|
Template for deploying one VDU and four CP,
|
||||||
|
and check CP's order.
|
||||||
|
CP3 -> CP2 -> CP4 -> CP1
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
CP1:
|
||||||
|
type: tosca.nodes.nfv.VduCp
|
||||||
|
properties:
|
||||||
|
layer_protocols: [ ipv4 ]
|
||||||
|
order: 3
|
||||||
|
vnic_type: direct-physical
|
||||||
|
requirements:
|
||||||
|
- virtual_binding: VDU1
|
||||||
|
|
||||||
|
CP2:
|
||||||
|
type: tosca.nodes.nfv.VduCp
|
||||||
|
properties:
|
||||||
|
layer_protocols: [ ipv4 ]
|
||||||
|
order: 1
|
||||||
|
vnic_type: direct-physical
|
||||||
|
requirements:
|
||||||
|
- virtual_binding: VDU1
|
||||||
|
|
||||||
|
CP3:
|
||||||
|
type: tosca.nodes.nfv.VduCp
|
||||||
|
properties:
|
||||||
|
layer_protocols: [ ipv4 ]
|
||||||
|
order: 0
|
||||||
|
vnic_type: direct-physical
|
||||||
|
requirements:
|
||||||
|
- virtual_binding: VDU1
|
||||||
|
|
||||||
|
CP4:
|
||||||
|
type: tosca.nodes.nfv.VduCp
|
||||||
|
properties:
|
||||||
|
layer_protocols: [ ipv4 ]
|
||||||
|
order: 2
|
||||||
|
vnic_type: direct-physical
|
||||||
|
requirements:
|
||||||
|
- virtual_binding: VDU1
|
17
translator/tests/data/etsi_nfv/tosca_nfv_cp.yaml
Normal file
17
translator/tests/data/etsi_nfv/tosca_nfv_cp.yaml
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
tosca_definitions_version: tosca_simple_yaml_1_2
|
||||||
|
|
||||||
|
description: >
|
||||||
|
Template for deploying one CP.
|
||||||
|
|
||||||
|
imports:
|
||||||
|
- etsi_nfv_sol001_common_types.yaml
|
||||||
|
- etsi_nfv_sol001_vnfd_types.yaml
|
||||||
|
|
||||||
|
topology_template:
|
||||||
|
node_templates:
|
||||||
|
CP1:
|
||||||
|
type: tosca.nodes.nfv.VduCp
|
||||||
|
properties:
|
||||||
|
layer_protocols: [ ipv4 ]
|
||||||
|
order: 0
|
||||||
|
vnic_type: direct-physical
|
@ -0,0 +1,50 @@
|
|||||||
|
tosca_definitions_version: tosca_simple_yaml_1_2
|
||||||
|
|
||||||
|
description: >
|
||||||
|
Template for deploying CPs,
|
||||||
|
with several vnic_types.
|
||||||
|
|
||||||
|
imports:
|
||||||
|
- etsi_nfv_sol001_common_types.yaml
|
||||||
|
- etsi_nfv_sol001_vnfd_types.yaml
|
||||||
|
|
||||||
|
node_types:
|
||||||
|
custom.VduCp:
|
||||||
|
derived_from: tosca.nodes.nfv.VduCp
|
||||||
|
properties:
|
||||||
|
vnic_type:
|
||||||
|
type: string
|
||||||
|
constraints:
|
||||||
|
- valid_values: [ normal, virtio, direct-physical, direct, macvtap, baremetal ]
|
||||||
|
|
||||||
|
topology_template:
|
||||||
|
node_templates:
|
||||||
|
CP1:
|
||||||
|
type: custom.VduCp
|
||||||
|
properties:
|
||||||
|
layer_protocols: [ ipv4 ]
|
||||||
|
vnic_type: direct-physical
|
||||||
|
|
||||||
|
CP2:
|
||||||
|
type: custom.VduCp
|
||||||
|
properties:
|
||||||
|
layer_protocols: [ ipv4 ]
|
||||||
|
vnic_type: normal
|
||||||
|
|
||||||
|
CP3:
|
||||||
|
type: custom.VduCp
|
||||||
|
properties:
|
||||||
|
layer_protocols: [ ipv4 ]
|
||||||
|
vnic_type: direct
|
||||||
|
|
||||||
|
CP4:
|
||||||
|
type: custom.VduCp
|
||||||
|
properties:
|
||||||
|
layer_protocols: [ ipv4 ]
|
||||||
|
vnic_type: macvtap
|
||||||
|
|
||||||
|
CP5:
|
||||||
|
type: custom.VduCp
|
||||||
|
properties:
|
||||||
|
layer_protocols: [ ipv4 ]
|
||||||
|
vnic_type: baremetal
|
24
translator/tests/data/etsi_nfv/tosca_nfv_non_leaf_in_vl.yaml
Normal file
24
translator/tests/data/etsi_nfv/tosca_nfv_non_leaf_in_vl.yaml
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
tosca_definitions_version: tosca_simple_yaml_1_2
|
||||||
|
|
||||||
|
description: >
|
||||||
|
Template for deploying one VirtualLink,
|
||||||
|
and omit non required properties
|
||||||
|
which are required in HOT.
|
||||||
|
|
||||||
|
imports:
|
||||||
|
- etsi_nfv_sol001_common_types.yaml
|
||||||
|
- etsi_nfv_sol001_vnfd_types.yaml
|
||||||
|
|
||||||
|
node_types:
|
||||||
|
topology_template:
|
||||||
|
node_templates:
|
||||||
|
VL1:
|
||||||
|
type: tosca.nodes.nfv.VnfVirtualLink
|
||||||
|
properties:
|
||||||
|
connectivity_type:
|
||||||
|
layer_protocols: [ ipv4 ]
|
||||||
|
vl_profile:
|
||||||
|
max_bitrate_requirements:
|
||||||
|
root: 1048576
|
||||||
|
min_bitrate_requirements:
|
||||||
|
root: 1048576
|
30
translator/tests/data/etsi_nfv/tosca_nfv_vl.yaml
Normal file
30
translator/tests/data/etsi_nfv/tosca_nfv_vl.yaml
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
tosca_definitions_version: tosca_simple_yaml_1_2
|
||||||
|
|
||||||
|
description: >
|
||||||
|
Template for deploying one VirtualLink.
|
||||||
|
|
||||||
|
imports:
|
||||||
|
- etsi_nfv_sol001_common_types.yaml
|
||||||
|
- etsi_nfv_sol001_vnfd_types.yaml
|
||||||
|
|
||||||
|
node_types:
|
||||||
|
topology_template:
|
||||||
|
node_templates:
|
||||||
|
VL1:
|
||||||
|
type: tosca.nodes.nfv.VnfVirtualLink
|
||||||
|
properties:
|
||||||
|
connectivity_type:
|
||||||
|
layer_protocols: [ ipv4 ]
|
||||||
|
description: Internal Virtual link in the VNF
|
||||||
|
vl_profile:
|
||||||
|
max_bitrate_requirements:
|
||||||
|
root: 1048576
|
||||||
|
leaf: 1048576
|
||||||
|
min_bitrate_requirements:
|
||||||
|
root: 1048576
|
||||||
|
leaf: 1048576
|
||||||
|
virtual_link_protocol_data:
|
||||||
|
- associated_layer_protocol: ipv4
|
||||||
|
l3_protocol_data:
|
||||||
|
ip_version: ipv4
|
||||||
|
cidr: 11.11.0.0/24
|
@ -0,0 +1,95 @@
|
|||||||
|
tosca_definitions_version: tosca_simple_yaml_1_2
|
||||||
|
|
||||||
|
description: >
|
||||||
|
Template for VirtualLink with unsupported layer_protocols.
|
||||||
|
|
||||||
|
imports:
|
||||||
|
- etsi_nfv_sol001_common_types.yaml
|
||||||
|
- etsi_nfv_sol001_vnfd_types.yaml
|
||||||
|
|
||||||
|
node_types:
|
||||||
|
topology_template:
|
||||||
|
node_templates:
|
||||||
|
VL1:
|
||||||
|
type: tosca.nodes.nfv.VnfVirtualLink
|
||||||
|
properties:
|
||||||
|
connectivity_type:
|
||||||
|
layer_protocols: [ ipv4 ]
|
||||||
|
description: Internal Virtual link in the VNF
|
||||||
|
vl_profile:
|
||||||
|
max_bitrate_requirements:
|
||||||
|
root: 1048576
|
||||||
|
leaf: 1048576
|
||||||
|
min_bitrate_requirements:
|
||||||
|
root: 1048576
|
||||||
|
leaf: 1048576
|
||||||
|
|
||||||
|
VL2:
|
||||||
|
type: tosca.nodes.nfv.VnfVirtualLink
|
||||||
|
properties:
|
||||||
|
connectivity_type:
|
||||||
|
layer_protocols: [ ipv6 ]
|
||||||
|
description: Internal Virtual link in the VNF
|
||||||
|
vl_profile:
|
||||||
|
max_bitrate_requirements:
|
||||||
|
root: 1048576
|
||||||
|
leaf: 1048576
|
||||||
|
min_bitrate_requirements:
|
||||||
|
root: 1048576
|
||||||
|
leaf: 1048576
|
||||||
|
|
||||||
|
VL3:
|
||||||
|
type: tosca.nodes.nfv.VnfVirtualLink
|
||||||
|
properties:
|
||||||
|
connectivity_type:
|
||||||
|
layer_protocols: [ ethernet ]
|
||||||
|
description: Internal Virtual link in the VNF
|
||||||
|
vl_profile:
|
||||||
|
max_bitrate_requirements:
|
||||||
|
root: 1048576
|
||||||
|
leaf: 1048576
|
||||||
|
min_bitrate_requirements:
|
||||||
|
root: 1048576
|
||||||
|
leaf: 1048576
|
||||||
|
|
||||||
|
VL4:
|
||||||
|
type: tosca.nodes.nfv.VnfVirtualLink
|
||||||
|
properties:
|
||||||
|
connectivity_type:
|
||||||
|
layer_protocols: [ mpls ]
|
||||||
|
description: Internal Virtual link in the VNF
|
||||||
|
vl_profile:
|
||||||
|
max_bitrate_requirements:
|
||||||
|
root: 1048576
|
||||||
|
leaf: 1048576
|
||||||
|
min_bitrate_requirements:
|
||||||
|
root: 1048576
|
||||||
|
leaf: 1048576
|
||||||
|
|
||||||
|
VL5:
|
||||||
|
type: tosca.nodes.nfv.VnfVirtualLink
|
||||||
|
properties:
|
||||||
|
connectivity_type:
|
||||||
|
layer_protocols: [ odu2 ]
|
||||||
|
description: Internal Virtual link in the VNF
|
||||||
|
vl_profile:
|
||||||
|
max_bitrate_requirements:
|
||||||
|
root: 1048576
|
||||||
|
leaf: 1048576
|
||||||
|
min_bitrate_requirements:
|
||||||
|
root: 1048576
|
||||||
|
leaf: 1048576
|
||||||
|
|
||||||
|
VL6:
|
||||||
|
type: tosca.nodes.nfv.VnfVirtualLink
|
||||||
|
properties:
|
||||||
|
connectivity_type:
|
||||||
|
layer_protocols: [ pseudo-wire ]
|
||||||
|
description: Internal Virtual link in the VNF
|
||||||
|
vl_profile:
|
||||||
|
max_bitrate_requirements:
|
||||||
|
root: 1048576
|
||||||
|
leaf: 1048576
|
||||||
|
min_bitrate_requirements:
|
||||||
|
root: 1048576
|
||||||
|
leaf: 1048576
|
@ -0,0 +1,45 @@
|
|||||||
|
heat_template_version: 2013-05-23
|
||||||
|
description: >
|
||||||
|
Template for deploying one VDU and four CP,
|
||||||
|
and check CP's order.
|
||||||
|
CP3 -> CP2 -> CP4 -> CP1
|
||||||
|
parameters: {}
|
||||||
|
resources:
|
||||||
|
CP1:
|
||||||
|
type: OS::Neutron::Port
|
||||||
|
properties:
|
||||||
|
network: #ADD_YOUR_NETWORK_HERE
|
||||||
|
binding:vnic_type: direct-physical
|
||||||
|
CP2:
|
||||||
|
type: OS::Neutron::Port
|
||||||
|
properties:
|
||||||
|
network: #ADD_YOUR_NETWORK_HERE
|
||||||
|
binding:vnic_type: direct-physical
|
||||||
|
CP3:
|
||||||
|
type: OS::Neutron::Port
|
||||||
|
properties:
|
||||||
|
network: #ADD_YOUR_NETWORK_HERE
|
||||||
|
binding:vnic_type: direct-physical
|
||||||
|
CP4:
|
||||||
|
type: OS::Neutron::Port
|
||||||
|
properties:
|
||||||
|
network: #ADD_YOUR_NETWORK_HERE
|
||||||
|
binding:vnic_type: direct-physical
|
||||||
|
VDU1:
|
||||||
|
type: OS::Nova::Server
|
||||||
|
properties:
|
||||||
|
flavor: { get_resource: VDU1_flavor }
|
||||||
|
name: VDU1
|
||||||
|
image: #ADD_YOUR_IMAGE_HERE
|
||||||
|
networks:
|
||||||
|
- port: { get_resource: CP3 }
|
||||||
|
- port: { get_resource: CP2 }
|
||||||
|
- port: { get_resource: CP4 }
|
||||||
|
- port: { get_resource: CP1 }
|
||||||
|
VDU1_flavor:
|
||||||
|
type: OS::Nova::Flavor
|
||||||
|
properties:
|
||||||
|
ram: 512
|
||||||
|
vcpus: 1
|
||||||
|
disk: 1
|
||||||
|
outputs: {}
|
11
translator/tests/data/hot_output/etsi_nfv/hot_nfv_cp.yaml
Normal file
11
translator/tests/data/hot_output/etsi_nfv/hot_nfv_cp.yaml
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
heat_template_version: 2013-05-23
|
||||||
|
description: >
|
||||||
|
Template for deploying one CP.
|
||||||
|
parameters: {}
|
||||||
|
resources:
|
||||||
|
CP1:
|
||||||
|
type: OS::Neutron::Port
|
||||||
|
properties:
|
||||||
|
network: #ADD_YOUR_NETWORK_HERE
|
||||||
|
binding:vnic_type: direct-physical
|
||||||
|
outputs: {}
|
@ -0,0 +1,32 @@
|
|||||||
|
heat_template_version: 2013-05-23
|
||||||
|
description: >
|
||||||
|
Template for deploying CPs,
|
||||||
|
with several vnic_types.
|
||||||
|
parameters: {}
|
||||||
|
resources:
|
||||||
|
CP1:
|
||||||
|
type: OS::Neutron::Port
|
||||||
|
properties:
|
||||||
|
network: #ADD_YOUR_NETWORK_HERE
|
||||||
|
binding:vnic_type: direct-physical
|
||||||
|
CP2:
|
||||||
|
type: OS::Neutron::Port
|
||||||
|
properties:
|
||||||
|
network: #ADD_YOUR_NETWORK_HERE
|
||||||
|
binding:vnic_type: normal
|
||||||
|
CP3:
|
||||||
|
type: OS::Neutron::Port
|
||||||
|
properties:
|
||||||
|
network: #ADD_YOUR_NETWORK_HERE
|
||||||
|
binding:vnic_type: direct
|
||||||
|
CP4:
|
||||||
|
type: OS::Neutron::Port
|
||||||
|
properties:
|
||||||
|
network: #ADD_YOUR_NETWORK_HERE
|
||||||
|
binding:vnic_type: macvtap
|
||||||
|
CP5:
|
||||||
|
type: OS::Neutron::Port
|
||||||
|
properties:
|
||||||
|
network: #ADD_YOUR_NETWORK_HERE
|
||||||
|
binding:vnic_type: baremetal
|
||||||
|
outputs: {}
|
@ -0,0 +1,15 @@
|
|||||||
|
heat_template_version: 2013-05-23
|
||||||
|
description: >
|
||||||
|
Template for deploying one VirtualLink,
|
||||||
|
and omit non required properties
|
||||||
|
which are required in HOT.
|
||||||
|
parameters: {}
|
||||||
|
resources:
|
||||||
|
VL1:
|
||||||
|
type: OS::Neutron::Net
|
||||||
|
VL1_subnet:
|
||||||
|
type: OS::Neutron::Subnet
|
||||||
|
properties:
|
||||||
|
network: { get_resource: VL1 }
|
||||||
|
ip_version: 4
|
||||||
|
outputs: {}
|
23
translator/tests/data/hot_output/etsi_nfv/hot_nfv_vl.yaml
Normal file
23
translator/tests/data/hot_output/etsi_nfv/hot_nfv_vl.yaml
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
heat_template_version: 2013-05-23
|
||||||
|
description: >
|
||||||
|
Template for deploying one VirtualLink.
|
||||||
|
parameters: {}
|
||||||
|
resources:
|
||||||
|
VL1:
|
||||||
|
type: OS::Neutron::Net
|
||||||
|
properties:
|
||||||
|
qos_policy: { get_resource: VL1_qospolicy }
|
||||||
|
VL1_subnet:
|
||||||
|
type: OS::Neutron::Subnet
|
||||||
|
properties:
|
||||||
|
network: { get_resource: VL1 }
|
||||||
|
ip_version: 4
|
||||||
|
cidr: 11.11.0.0/24
|
||||||
|
VL1_bandwidth:
|
||||||
|
type: OS::Neutron::QoSBandwidthLimitRule
|
||||||
|
properties:
|
||||||
|
max_kbps: 1024
|
||||||
|
policy: { get_resource: VL1_qospolicy }
|
||||||
|
VL1_qospolicy:
|
||||||
|
type: OS::Neutron::QoSPolicy
|
||||||
|
outputs: {}
|
@ -0,0 +1,38 @@
|
|||||||
|
heat_template_version: 2013-05-23
|
||||||
|
description: >
|
||||||
|
Template for VirtualLink with unsupported layer_protocols.
|
||||||
|
parameters: {}
|
||||||
|
resources:
|
||||||
|
VL1:
|
||||||
|
type: OS::Neutron::Net
|
||||||
|
properties:
|
||||||
|
qos_policy: { get_resource: VL1_qospolicy }
|
||||||
|
VL1_subnet:
|
||||||
|
type: OS::Neutron::Subnet
|
||||||
|
properties:
|
||||||
|
network: { get_resource: VL1 }
|
||||||
|
ip_version: 4
|
||||||
|
VL1_bandwidth:
|
||||||
|
type: OS::Neutron::QoSBandwidthLimitRule
|
||||||
|
properties:
|
||||||
|
max_kbps: 1024
|
||||||
|
policy: { get_resource: VL1_qospolicy }
|
||||||
|
VL1_qospolicy:
|
||||||
|
type: OS::Neutron::QoSPolicy
|
||||||
|
VL2:
|
||||||
|
type: OS::Neutron::Net
|
||||||
|
properties:
|
||||||
|
qos_policy: { get_resource: VL2_qospolicy }
|
||||||
|
VL2_subnet:
|
||||||
|
type: OS::Neutron::Subnet
|
||||||
|
properties:
|
||||||
|
network: { get_resource: VL2 }
|
||||||
|
ip_version: 6
|
||||||
|
VL2_bandwidth:
|
||||||
|
type: OS::Neutron::QoSBandwidthLimitRule
|
||||||
|
properties:
|
||||||
|
max_kbps: 1024
|
||||||
|
policy: { get_resource: VL2_qospolicy }
|
||||||
|
VL2_qospolicy:
|
||||||
|
type: OS::Neutron::QoSPolicy
|
||||||
|
outputs: {}
|
@ -112,3 +112,82 @@ class EtsiToscaHotTranslationTest(TestCase):
|
|||||||
expected_msg,
|
expected_msg,
|
||||||
self.log_fixture.output
|
self.log_fixture.output
|
||||||
)
|
)
|
||||||
|
|
||||||
|
def test_hot_translate_etsi_nfv_cp(self):
|
||||||
|
tosca_file = '../tests/data/etsi_nfv/' \
|
||||||
|
'tosca_nfv_cp.yaml'
|
||||||
|
hot_files = [
|
||||||
|
'../tests/data/hot_output/etsi_nfv/'
|
||||||
|
'hot_nfv_cp.yaml',
|
||||||
|
]
|
||||||
|
self._test_successful_translation(tosca_file, hot_files, params={})
|
||||||
|
|
||||||
|
def test_hot_translate_etsi_nfv_cp_with_extended_vnic_type(self):
|
||||||
|
tosca_file = '../tests/data/etsi_nfv/' \
|
||||||
|
'tosca_nfv_cp_with_extended_vnic_type.yaml'
|
||||||
|
hot_files = [
|
||||||
|
'../tests/data/hot_output/etsi_nfv/'
|
||||||
|
'hot_nfv_cp_with_extended_vnic_type.yaml',
|
||||||
|
]
|
||||||
|
self._test_successful_translation(tosca_file, hot_files, params={})
|
||||||
|
|
||||||
|
def test_hot_translate_etsi_nfv_check_cp_order(self):
|
||||||
|
tosca_file = '../tests/data/etsi_nfv/' \
|
||||||
|
'tosca_nfv_check_cp_order.yaml'
|
||||||
|
hot_files = [
|
||||||
|
'../tests/data/hot_output/etsi_nfv/'
|
||||||
|
'hot_nfv_check_cp_order.yaml',
|
||||||
|
]
|
||||||
|
self._test_successful_translation(tosca_file, hot_files, params={})
|
||||||
|
|
||||||
|
def test_hot_translate_etsi_nfv_vl(self):
|
||||||
|
tosca_file = '../tests/data/etsi_nfv/' \
|
||||||
|
'tosca_nfv_vl.yaml'
|
||||||
|
hot_files = [
|
||||||
|
'../tests/data/hot_output/etsi_nfv/'
|
||||||
|
'hot_nfv_vl.yaml',
|
||||||
|
]
|
||||||
|
self._test_successful_translation(tosca_file, hot_files, params={})
|
||||||
|
|
||||||
|
def test_hot_translate_etsi_nfv_vl_with_unsupported_protocol(self):
|
||||||
|
tosca_file = '../tests/data/etsi_nfv/' \
|
||||||
|
'tosca_nfv_vl_with_unsupported_protocol.yaml'
|
||||||
|
hot_files = [
|
||||||
|
'../tests/data/hot_output/etsi_nfv/'
|
||||||
|
'hot_nfv_vl_with_unsupported_protocol.yaml',
|
||||||
|
]
|
||||||
|
expected_msgs = (
|
||||||
|
'Unsupported layer_protocols, virtual_link_name:VL3, '
|
||||||
|
'protocol_name:[\'ethernet\']',
|
||||||
|
'Unsupported layer_protocols, virtual_link_name:VL4, '
|
||||||
|
'protocol_name:[\'mpls\']',
|
||||||
|
'Unsupported layer_protocols, virtual_link_name:VL5, '
|
||||||
|
'protocol_name:[\'odu2\']',
|
||||||
|
'Unsupported layer_protocols, virtual_link_name:VL6, '
|
||||||
|
'protocol_name:[\'pseudo-wire\']'
|
||||||
|
)
|
||||||
|
self._test_successful_translation(tosca_file, hot_files, params={})
|
||||||
|
for expected_msg in expected_msgs:
|
||||||
|
self.assertIn(
|
||||||
|
expected_msg,
|
||||||
|
self.log_fixture.output
|
||||||
|
)
|
||||||
|
|
||||||
|
def test_hot_translate_etsi_nfv_non_leaf_in_vl(self):
|
||||||
|
vl_name = 'VL1'
|
||||||
|
tosca_file = '../tests/data/etsi_nfv/' \
|
||||||
|
'tosca_nfv_non_leaf_in_vl.yaml'
|
||||||
|
hot_files = [
|
||||||
|
'../tests/data/hot_output/etsi_nfv/'
|
||||||
|
'hot_nfv_non_leaf_in_vl.yaml',
|
||||||
|
]
|
||||||
|
expected_msgs = (
|
||||||
|
'Can not set the required properties '
|
||||||
|
'max_kbps on HOT.'
|
||||||
|
'virtual_link_name:%s' % vl_name,)
|
||||||
|
self._test_successful_translation(tosca_file, hot_files, params={})
|
||||||
|
for expected_msg in expected_msgs:
|
||||||
|
self.assertIn(
|
||||||
|
expected_msg,
|
||||||
|
self.log_fixture.output
|
||||||
|
)
|
||||||
|
@ -36,7 +36,9 @@ class TranslateNodeTemplatesTest(TestCase):
|
|||||||
'tosca.policies.Scaling',
|
'tosca.policies.Scaling',
|
||||||
'tosca.policies.Scaling.Cluster',
|
'tosca.policies.Scaling.Cluster',
|
||||||
'tosca.nodes.nfv.VNF',
|
'tosca.nodes.nfv.VNF',
|
||||||
'tosca.nodes.nfv.Vdu.Compute'
|
'tosca.nodes.nfv.Vdu.Compute',
|
||||||
|
'tosca.nodes.nfv.VduCp',
|
||||||
|
'tosca.nodes.nfv.VnfVirtualLink'
|
||||||
]
|
]
|
||||||
actual_type_list = list(_generate_type_map())
|
actual_type_list = list(_generate_type_map())
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user