Support short notation for artifacts definition
As per [1], artifacts supports both short and extended notation. Extended notation is already supported. This patch adds support for short notation. Short notation example: artifacts: <artifact_name>: <artifact_file_URI> [1] https://docs.oasis-open.org/tosca/TOSCA-Simple-Profile-YAML/v1.2/os/TOSCA-Simple-Profile-YAML-v1.2-os.html#DEFN_ENTITY_ARTIFACT_DEF Closes-Bug: #1850755 Change-Id: I057bfae8ba8aeee7c8ecb57cca26e11b1bf82bab
This commit is contained in:
parent
4470236b5c
commit
aff272b3c4
|
@ -0,0 +1,6 @@
|
|||
---
|
||||
fixes:
|
||||
- |
|
||||
Fixes `bug 1850755`_ which adds short notation support for artifacts.
|
||||
|
||||
.. _bug 1850755: https://bugs.launchpad.net/tacker/+bug/1850755
|
|
@ -46,9 +46,11 @@ def _get_sw_image_artifact(artifacts):
|
|||
return
|
||||
|
||||
for artifact_value in artifacts.values():
|
||||
if 'type' in artifact_value:
|
||||
if artifact_value['type'] == 'tosca.artifacts.nfv.SwImage':
|
||||
if isinstance(artifact_value, dict):
|
||||
if artifact_value.get('type') == 'tosca.artifacts.nfv.SwImage':
|
||||
return artifact_value
|
||||
elif isinstance(artifact_value, str):
|
||||
return {'file': artifact_value}
|
||||
|
||||
|
||||
def _update_default_vnfd_data(node_value, node_type_value):
|
||||
|
@ -215,27 +217,31 @@ def _validate_instantiation_levels(policy, instantiation_levels):
|
|||
|
||||
|
||||
def _validate_sw_image_data_for_artifact(node_tpl, template_name):
|
||||
artifact_type = []
|
||||
artifact_names = []
|
||||
artifacts = node_tpl.get('artifacts')
|
||||
if artifacts:
|
||||
for key, value in artifacts.items():
|
||||
if not artifacts:
|
||||
return
|
||||
|
||||
for key, value in artifacts.items():
|
||||
if isinstance(value, dict):
|
||||
if value.get('type') == 'tosca.artifacts.nfv.SwImage':
|
||||
artifact_type.append(value.get('type'))
|
||||
artifact_names.append(key)
|
||||
elif isinstance(value, str):
|
||||
artifact_names.append(key)
|
||||
|
||||
if len(artifact_type) > 1:
|
||||
error_msg = ('artifacts of type "tosca.artifacts.nfv.SwImage"'
|
||||
' is added more than one time for'
|
||||
' node %(node)s.') % {'node': template_name}
|
||||
if len(artifact_names) > 1:
|
||||
error_msg = ('artifacts of type "tosca.artifacts.nfv.SwImage"'
|
||||
' is added more than one time for'
|
||||
' node %(node)s.') % {'node': template_name}
|
||||
raise exceptions.InvalidCSAR(error_msg)
|
||||
|
||||
if artifact_names and node_tpl.get('properties'):
|
||||
if not node_tpl.get('properties').get('sw_image_data'):
|
||||
error_msg = ('Node property "sw_image_data" is missing for'
|
||||
' artifact %(artifact_name)s for node %(node)s.') % {
|
||||
'artifact_name': artifact_names[0], 'node': template_name}
|
||||
raise exceptions.InvalidCSAR(error_msg)
|
||||
|
||||
if artifact_type and node_tpl.get('properties'):
|
||||
if not node_tpl.get('properties').get('sw_image_data'):
|
||||
error_msg = ('Node property "sw_image_data" is missing for'
|
||||
' artifact type %(type)s for '
|
||||
'node %(node)s.') % {
|
||||
'type': artifact_type[0], 'node': template_name}
|
||||
raise exceptions.InvalidCSAR(error_msg)
|
||||
|
||||
|
||||
def _validate_sw_image_data_for_artifacts(tosca):
|
||||
for tp in tosca.nested_tosca_templates_with_topology:
|
||||
|
|
|
@ -0,0 +1,44 @@
|
|||
tosca_definitions_version: tosca_simple_yaml_1_2
|
||||
|
||||
description: Simple deployment flavour for Sample VNF
|
||||
|
||||
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 GB
|
||||
size: 1 GB
|
||||
|
||||
artifacts:
|
||||
sw_image1: ../Files/images/cirros-0.4.0-x86_64-disk.img
|
||||
sw_image2:
|
||||
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 MB
|
||||
virtual_cpu:
|
||||
num_virtual_cpu: 1
|
||||
virtual_local_storage:
|
||||
- size_of_storage: 1 GB
|
|
@ -0,0 +1,7 @@
|
|||
TOSCA-Meta-File-Version: 1.0
|
||||
Created-by: Hiroyuki JO
|
||||
CSAR-Version: 1.1
|
||||
Entry-Definitions: Definitions/helloworld3_df_simple.yaml
|
||||
|
||||
Name: Files/images/cirros-0.4.0-x86_64-disk.img
|
||||
Content-type: application/x-iso9066-image
|
|
@ -0,0 +1,31 @@
|
|||
tosca_definitions_version: tosca_simple_yaml_1_2
|
||||
|
||||
description: Simple deployment flavour for Sample VNF
|
||||
|
||||
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
|
||||
|
||||
artifacts:
|
||||
sw_image: ../Files/images/cirros-0.4.0-x86_64-disk.img
|
||||
|
||||
capabilities:
|
||||
virtual_compute:
|
||||
properties:
|
||||
virtual_memory:
|
||||
virtual_mem_size: 512 MB
|
||||
virtual_cpu:
|
||||
num_virtual_cpu: 1
|
||||
virtual_local_storage:
|
||||
- size_of_storage: 1 GB
|
|
@ -0,0 +1,7 @@
|
|||
TOSCA-Meta-File-Version: 1.0
|
||||
Created-by: Hiroyuki JO
|
||||
CSAR-Version: 1.1
|
||||
Entry-Definitions: Definitions/helloworld3_df_simple.yaml
|
||||
|
||||
Name: Files/images/cirros-0.4.0-x86_64-disk.img
|
||||
Content-type: application/x-iso9066-image
|
|
@ -0,0 +1,114 @@
|
|||
tosca_definitions_version: tosca_simple_yaml_1_2
|
||||
|
||||
description: Simple deployment flavour for Sample VNF
|
||||
|
||||
imports:
|
||||
- etsi_nfv_sol001_common_types.yaml
|
||||
- etsi_nfv_sol001_vnfd_types.yaml
|
||||
- helloworld3_types.yaml
|
||||
|
||||
topology_template:
|
||||
inputs:
|
||||
descriptor_id:
|
||||
type: string
|
||||
descriptor_version:
|
||||
type: string
|
||||
provider:
|
||||
type: string
|
||||
product_name:
|
||||
type: string
|
||||
software_version:
|
||||
type: string
|
||||
vnfm_info:
|
||||
type: list
|
||||
entry_schema:
|
||||
type: string
|
||||
flavour_id:
|
||||
type: string
|
||||
flavour_description:
|
||||
type: string
|
||||
|
||||
substitution_mappings:
|
||||
node_type: company.provider.VNF
|
||||
properties:
|
||||
flavour_id: simple
|
||||
requirements:
|
||||
virtual_link_external: [ CP1, virtual_link ]
|
||||
|
||||
node_templates:
|
||||
VNF:
|
||||
type: company.provider.VNF
|
||||
properties:
|
||||
flavour_description: A simple flavour
|
||||
interfaces:
|
||||
Vnflcm:
|
||||
instantiate: []
|
||||
instantiate_start: []
|
||||
instantiate_end: []
|
||||
terminate: []
|
||||
terminate_start: []
|
||||
terminate_end: []
|
||||
modify_information: []
|
||||
modify_information_start: []
|
||||
modify_information_end: []
|
||||
|
||||
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 GB
|
||||
size: 1 GB
|
||||
|
||||
artifacts:
|
||||
sw_image: ../Files/images/cirros-0.4.0-x86_64-disk.img
|
||||
|
||||
capabilities:
|
||||
virtual_compute:
|
||||
properties:
|
||||
virtual_memory:
|
||||
virtual_mem_size: 512 MB
|
||||
virtual_cpu:
|
||||
num_virtual_cpu: 1
|
||||
virtual_local_storage:
|
||||
- size_of_storage: 1 GB
|
||||
|
||||
CP1:
|
||||
type: tosca.nodes.nfv.VduCp
|
||||
properties:
|
||||
layer_protocols: [ ipv4 ]
|
||||
order: 0
|
||||
vnic_type: direct-physical
|
||||
requirements:
|
||||
- virtual_binding: VDU1
|
||||
- virtual_link: internalVL2
|
||||
|
||||
internalVL2:
|
||||
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,31 @@
|
|||
tosca_definitions_version: tosca_simple_yaml_1_2
|
||||
|
||||
description: Sample VNF
|
||||
|
||||
imports:
|
||||
- etsi_nfv_sol001_common_types.yaml
|
||||
- etsi_nfv_sol001_vnfd_types.yaml
|
||||
- helloworld3_types.yaml
|
||||
- helloworld3_df_simple.yaml
|
||||
|
||||
topology_template:
|
||||
inputs:
|
||||
selected_flavour:
|
||||
type: string
|
||||
description: VNF deployment flavour selected by the consumer. It is provided in the API
|
||||
|
||||
node_templates:
|
||||
VNF:
|
||||
type: company.provider.VNF
|
||||
properties:
|
||||
flavour_id: { get_input: selected_flavour }
|
||||
descriptor_id: b1bb0ce7-ebca-4fa7-95ed-4840d70a1177
|
||||
provider: Company
|
||||
product_name: Sample VNF
|
||||
software_version: '1.0'
|
||||
descriptor_version: '1.0'
|
||||
vnfm_info:
|
||||
- Tacker
|
||||
requirements:
|
||||
#- virtual_link_external # mapped in lower-level templates
|
||||
#- virtual_link_internal # mapped in lower-level templates
|
|
@ -0,0 +1,53 @@
|
|||
tosca_definitions_version: tosca_simple_yaml_1_2
|
||||
|
||||
description: VNF type definition
|
||||
|
||||
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: b1bb0ce7-ebca-4fa7-95ed-4840d70a1177
|
||||
descriptor_version:
|
||||
type: string
|
||||
constraints: [ valid_values: [ '1.0' ] ]
|
||||
default: '1.0'
|
||||
provider:
|
||||
type: string
|
||||
constraints: [ valid_values: [ 'Company' ] ]
|
||||
default: 'Company'
|
||||
product_name:
|
||||
type: string
|
||||
constraints: [ valid_values: [ 'Sample VNF' ] ]
|
||||
default: 'Sample VNF'
|
||||
software_version:
|
||||
type: string
|
||||
constraints: [ valid_values: [ '1.0' ] ]
|
||||
default: '1.0'
|
||||
vnfm_info:
|
||||
type: list
|
||||
entry_schema:
|
||||
type: string
|
||||
constraints: [ valid_values: [ Tacker ] ]
|
||||
default: [ Tacker ]
|
||||
flavour_id:
|
||||
type: string
|
||||
constraints: [ valid_values: [ simple ] ]
|
||||
default: simple
|
||||
flavour_description:
|
||||
type: string
|
||||
default: ""
|
||||
requirements:
|
||||
- virtual_link_external:
|
||||
capability: tosca.capabilities.nfv.VirtualLinkable
|
||||
- virtual_link_internal:
|
||||
capability: tosca.capabilities.nfv.VirtualLinkable
|
||||
interfaces:
|
||||
Vnflcm:
|
||||
type: tosca.interfaces.nfv.Vnflcm
|
|
@ -0,0 +1,7 @@
|
|||
TOSCA-Meta-File-Version: 1.0
|
||||
Created-by: Hiroyuki JO
|
||||
CSAR-Version: 1.1
|
||||
Entry-Definitions: Definitions/helloworld3_top.vnfd.yaml
|
||||
|
||||
Name: Files/images/cirros-0.4.0-x86_64-disk.img
|
||||
Content-type: application/x-iso9066-image
|
|
@ -21,6 +21,7 @@ from tacker.common import csar_utils
|
|||
from tacker.common import exceptions
|
||||
from tacker import context
|
||||
from tacker.tests import constants
|
||||
from tacker.tests import utils
|
||||
|
||||
|
||||
class TestCSARUtils(testtools.TestCase):
|
||||
|
@ -112,8 +113,8 @@ class TestCSARUtils(testtools.TestCase):
|
|||
exc = self.assertRaises(exceptions.InvalidCSAR,
|
||||
csar_utils.load_csar_data,
|
||||
self.context, constants.UUID, file_path)
|
||||
msg = ('Node property "sw_image_data" is missing for artifact'
|
||||
' type tosca.artifacts.nfv.SwImage for node VDU1.')
|
||||
msg = ('Node property "sw_image_data" is missing for '
|
||||
'artifact sw_image for node VDU1.')
|
||||
self.assertEqual(msg, exc.format_message())
|
||||
|
||||
@mock.patch('tacker.common.csar_utils.extract_csar_zip_file')
|
||||
|
@ -136,8 +137,8 @@ class TestCSARUtils(testtools.TestCase):
|
|||
exc = self.assertRaises(exceptions.InvalidCSAR,
|
||||
csar_utils.load_csar_data,
|
||||
self.context, constants.UUID, file_path)
|
||||
msg = ('Node property "sw_image_data" is missing for artifact'
|
||||
' type tosca.artifacts.nfv.SwImage for node VDU1.')
|
||||
msg = ('Node property "sw_image_data" is missing for'
|
||||
' artifact sw_image for node VDU1.')
|
||||
self.assertEqual(msg, exc.format_message())
|
||||
|
||||
@mock.patch('tacker.common.csar_utils.extract_csar_zip_file')
|
||||
|
@ -175,3 +176,47 @@ class TestCSARUtils(testtools.TestCase):
|
|||
self.context, constants.UUID, file_path)
|
||||
self.assertIsNone(flavours[0].get('instantiation_levels'))
|
||||
self.assertEqual(vnf_data['descriptor_version'], '1.0')
|
||||
|
||||
@mock.patch('tacker.common.csar_utils.extract_csar_zip_file')
|
||||
def test_load_csar_with_artifacts_short_notation_without_sw_image_data(
|
||||
self, mock_extract_csar_zip_file):
|
||||
file_path = "./tacker/tests/etc/samples/etsi/nfv/" \
|
||||
"csar_short_notation_for_artifacts_without_sw_image_data"
|
||||
zip_name, uniqueid = utils.create_csar_with_unique_vnfd_id(file_path)
|
||||
exc = self.assertRaises(exceptions.InvalidCSAR,
|
||||
csar_utils.load_csar_data,
|
||||
self.context, constants.UUID, zip_name)
|
||||
msg = ('Node property "sw_image_data" is missing for'
|
||||
' artifact sw_image for node VDU1.')
|
||||
self.assertEqual(msg, exc.format_message())
|
||||
os.remove(zip_name)
|
||||
|
||||
@mock.patch('tacker.common.csar_utils.extract_csar_zip_file')
|
||||
def test_load_csar_data_with_artifacts_short_notation(
|
||||
self, mock_extract_csar_zip_file):
|
||||
file_path = "./tacker/tests/etc/samples/etsi/nfv/" \
|
||||
"csar_with_short_notation_for_artifacts"
|
||||
zip_name, uniqueid = utils.create_csar_with_unique_vnfd_id(file_path)
|
||||
|
||||
vnf_data, flavours = csar_utils.load_csar_data(
|
||||
self.context, constants.UUID, zip_name)
|
||||
self.assertEqual(vnf_data['descriptor_version'], '1.0')
|
||||
self.assertEqual(vnf_data['vnfm_info'], ['Tacker'])
|
||||
self.assertEqual(flavours[0]['flavour_id'], 'simple')
|
||||
self.assertIsNotNone(flavours[0]['sw_images'])
|
||||
os.remove(zip_name)
|
||||
|
||||
@mock.patch('tacker.common.csar_utils.extract_csar_zip_file')
|
||||
def test_load_csar_data_with_multiple_sw_image_data_with_short_notation(
|
||||
self, mock_extract_csar_zip_file):
|
||||
|
||||
file_path = "./tacker/tests/etc/samples/etsi/nfv/" \
|
||||
"csar_multiple_sw_image_data_with_short_notation"
|
||||
zip_name, uniqueid = utils.create_csar_with_unique_vnfd_id(file_path)
|
||||
exc = self.assertRaises(exceptions.InvalidCSAR,
|
||||
csar_utils.load_csar_data,
|
||||
self.context, constants.UUID, zip_name)
|
||||
msg = ('artifacts of type "tosca.artifacts.nfv.SwImage"'
|
||||
' is added more than one time for node VDU1.')
|
||||
self.assertEqual(msg, exc.format_message())
|
||||
os.remove(zip_name)
|
||||
|
|
Loading…
Reference in New Issue