Support importing def from local instead of url

Sometimes importing a nested definition from remote server is failed
for the server is busy. Although we usually can download the definition
before and change the path as local then, cannot for a case if the
contents of the template is fixed and it should not be changed.

This update is to avoid such a case. The url can be replaced with any
other path by using arg `local_defs` like as below. In this case, the
definition is imported from local path instead of url. It's also
includes some util functions to make it easier developers to find local
files.

    local_defs = {"https://example.org/orig": "/path/to/local/def"}
    tosca = ToscaTemplate(template, local_defs=local_defs}

Closes-Bug: #2008048
Depends-On: https://review.opendev.org/c/openstack/tosca-parser/+/873217
Signed-off-by: Yasufumi Ogawa <yasufum.o@gmail.com>
Change-Id: Ied30614f22282a85badb568854f20f2b76f64d70
This commit is contained in:
Yasufumi Ogawa 2023-02-22 07:19:44 +00:00
parent 9129640de8
commit 4654af7998
18 changed files with 358 additions and 52 deletions

View 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

View File

@ -1264,8 +1264,9 @@ class VnfLcmController(wsgi.Controller):
vnfd_dict = vnflcm_utils._get_vnfd_dict(context, vnfd_dict = vnflcm_utils._get_vnfd_dict(context,
vnf_instance.vnfd_id, vnf_instance.vnfd_id,
vnf_instance.instantiated_vnf_info.flavour_id) vnf_instance.instantiated_vnf_info.flavour_id)
tosca = tosca_template.ToscaTemplate(parsed_params={}, a_file=False, tosca = tosca_template.ToscaTemplate(
yaml_dict_tpl=vnfd_dict) parsed_params={}, a_file=False, yaml_dict_tpl=vnfd_dict,
local_defs=toscautils.tosca_tmpl_local_defs())
tosca_policies = tosca.topology_template.policies tosca_policies = tosca.topology_template.policies
aspect_max_level_dict = {} aspect_max_level_dict = {}

View File

@ -33,6 +33,7 @@ from toscaparser.tosca_template import ToscaTemplate
from tacker.common import exceptions from tacker.common import exceptions
import tacker.conf import tacker.conf
from tacker.extensions import vnfm from tacker.extensions import vnfm
from tacker.tosca import utils as toscautils
HASH_DICT = { HASH_DICT = {
@ -542,7 +543,9 @@ def load_csar_data(context, package_uuid, zip_path):
extract_csar_zip_file(zip_path, extract_zip_path) extract_csar_zip_file(zip_path, extract_zip_path)
try: try:
tosca = ToscaTemplate(zip_path, None, True) tosca = ToscaTemplate(
zip_path, None, True,
local_defs=toscautils.tosca_tmpl_local_defs())
return _get_data_from_csar(tosca, context, package_uuid) return _get_data_from_csar(tosca, context, package_uuid)
except exceptions.InvalidCSAR as exp: except exceptions.InvalidCSAR as exp:
with excutils.save_and_reraise_exception(): with excutils.save_and_reraise_exception():

View File

@ -87,6 +87,17 @@ else:
getargspec = inspect.getargspec getargspec = inspect.getargspec
def proj_root():
"""Return tacker's project root dir.
It's assumed `abspath(__file__)` is equals to ${PROJ_ROOT}/tacker/common.
The result is like as "/opt/stack/tacker".
"""
dir_to_common = os.path.dirname(os.path.abspath(__file__))
return "/".join(dir_to_common.split('/')[:-2])
def find_config_file(options, config_file): def find_config_file(options, config_file):
"""Return the first config file found. """Return the first config file found.

View File

@ -26,6 +26,7 @@ from oslo_utils import excutils
from oslo_utils import strutils from oslo_utils import strutils
from oslo_utils import uuidutils from oslo_utils import uuidutils
from tempfile import mkstemp from tempfile import mkstemp
from toscaparser import tosca_template
from toscaparser.tosca_template import ToscaTemplate from toscaparser.tosca_template import ToscaTemplate
from tacker._i18n import _ from tacker._i18n import _
@ -42,11 +43,10 @@ from tacker.extensions import nfvo
from tacker.keymgr import API as KEYMGR_API from tacker.keymgr import API as KEYMGR_API
from tacker import manager from tacker import manager
from tacker.plugins.common import constants from tacker.plugins.common import constants
from tacker.tosca import utils as toscautils
from tacker.vnfm import keystone from tacker.vnfm import keystone
from tacker.vnfm import vim_client from tacker.vnfm import vim_client
from tacker.tosca import utils as toscautils
from toscaparser import tosca_template
LOG = logging.getLogger(__name__) LOG = logging.getLogger(__name__)
CONF = cfg.CONF CONF = cfg.CONF
@ -256,7 +256,8 @@ class NfvoPlugin(nfvo_db_plugin.NfvoPluginDb, vnffg_db.VnffgPluginDbMixin,
try: try:
tosca_template.ToscaTemplate( tosca_template.ToscaTemplate(
a_file=False, yaml_dict_tpl=template) a_file=False, yaml_dict_tpl=template,
local_defs=toscautils.tosca_tmpl_local_defs())
except Exception as e: except Exception as e:
LOG.exception("tosca-parser error: %s", str(e)) LOG.exception("tosca-parser error: %s", str(e))
raise nfvo.ToscaParserFailed(error_msg_details=str(e)) raise nfvo.ToscaParserFailed(error_msg_details=str(e))
@ -666,7 +667,8 @@ class NfvoPlugin(nfvo_db_plugin.NfvoPluginDb, vnffg_db.VnffgPluginDbMixin,
try: try:
ToscaTemplate(a_file=False, ToscaTemplate(a_file=False,
yaml_dict_tpl=inner_nsd_dict) yaml_dict_tpl=inner_nsd_dict,
local_defs=toscautils.tosca_tmpl_local_defs())
except Exception as e: except Exception as e:
LOG.exception("tosca-parser error: %s", str(e)) LOG.exception("tosca-parser error: %s", str(e))
raise nfvo.ToscaParserFailed(error_msg_details=str(e)) raise nfvo.ToscaParserFailed(error_msg_details=str(e))

View File

@ -54,7 +54,8 @@ class VnfTestToscaMultipleVDU(base.BaseTackerTest):
toscautils.updateimports(tosca_dict) toscautils.updateimports(tosca_dict)
tosca = tosca_template.ToscaTemplate(parsed_params={}, a_file=False, tosca = tosca_template.ToscaTemplate(parsed_params={}, a_file=False,
yaml_dict_tpl=tosca_dict) yaml_dict_tpl=tosca_dict,
local_defs=toscautils.tosca_tmpl_local_defs())
vdus = toscautils.findvdus(tosca) vdus = toscautils.findvdus(tosca)

View File

@ -81,7 +81,8 @@ class VnfTestToscaVNFC(base.BaseTackerTest):
toscautils.updateimports(input_dict) toscautils.updateimports(input_dict)
tosca = tosca_template.ToscaTemplate(parsed_params={}, a_file=False, tosca = tosca_template.ToscaTemplate(parsed_params={}, a_file=False,
yaml_dict_tpl=input_dict) yaml_dict_tpl=input_dict,
local_defs=toscautils.tosca_tmpl_local_defs())
vdus = toscautils.findvdus(tosca) vdus = toscautils.findvdus(tosca)

View File

@ -19,7 +19,7 @@ from toscaparser import tosca_template
from toscaparser.utils import yamlparser from toscaparser.utils import yamlparser
from translator.hot import tosca_translator from translator.hot import tosca_translator
from tacker.tosca import utils from tacker.tosca import utils as toscautils
class TestSamples(testtools.TestCase): class TestSamples(testtools.TestCase):
@ -54,20 +54,20 @@ class TestSamples(testtools.TestCase):
yaml_dict, yaml_dict,
"Yaml parser failed to parse %s" % f) "Yaml parser failed to parse %s" % f)
utils.updateimports(yaml_dict) toscautils.updateimports(yaml_dict)
tosca = None tosca = None
try: try:
tosca = tosca_template.ToscaTemplate( tosca = tosca_template.ToscaTemplate(
a_file=False, a_file=False, yaml_dict_tpl=yaml_dict,
yaml_dict_tpl=yaml_dict) local_defs=toscautils.tosca_tmpl_local_defs())
except: # noqa except: # noqa
pass pass
self.assertIsNotNone( self.assertIsNotNone(
tosca, tosca,
"Tosca parser failed to parse %s" % f) "Tosca parser failed to parse %s" % f)
utils.post_process_template(tosca) toscautils.post_process_template(tosca)
hot = None hot = None
try: try:
hot = tosca_translator.TOSCATranslator(tosca, hot = tosca_translator.TOSCATranslator(tosca,

View File

@ -39,6 +39,7 @@ from tacker.tests.unit.conductor import fakes
from tacker.tests.unit.db import base as db_base from tacker.tests.unit.db import base as db_base
from tacker.tests.unit.db import utils from tacker.tests.unit.db import utils
from tacker.tests.unit.vnflcm import fakes as vnflcm_fakes from tacker.tests.unit.vnflcm import fakes as vnflcm_fakes
from tacker.tosca import utils as toscautils
from tacker.vnfm import monitor from tacker.vnfm import monitor
from tacker.vnfm import plugin from tacker.vnfm import plugin
@ -388,7 +389,8 @@ class TestVNFMPlugin(db_base.SqlTestCase):
self.assertIn('template_source', result) self.assertIn('template_source', result)
yaml_dict = yaml.safe_load(utils.tosca_vnfd_openwrt) yaml_dict = yaml.safe_load(utils.tosca_vnfd_openwrt)
mock_tosca_template.assert_called_once_with( mock_tosca_template.assert_called_once_with(
a_file=False, yaml_dict_tpl=yaml_dict) a_file=False, yaml_dict_tpl=yaml_dict,
local_defs=toscautils.tosca_tmpl_local_defs())
mock_get_mgmt_driver.assert_called_once_with(mock.ANY) mock_get_mgmt_driver.assert_called_once_with(mock.ANY)
mock_update_imports.assert_called_once_with(yaml_dict) mock_update_imports.assert_called_once_with(yaml_dict)
self._cos_db_plugin.create_event.assert_called_once_with( self._cos_db_plugin.create_event.assert_called_once_with(

View File

@ -39,7 +39,8 @@ class TestToscaUtils(testtools.TestCase):
def setUp(self): def setUp(self):
super(TestToscaUtils, self).setUp() super(TestToscaUtils, self).setUp()
self.tosca = tosca_template.ToscaTemplate( self.tosca = tosca_template.ToscaTemplate(
parsed_params={}, a_file=False, yaml_dict_tpl=self.vnfd_dict) parsed_params={}, a_file=False, yaml_dict_tpl=self.vnfd_dict,
local_defs=toscautils.tosca_tmpl_local_defs())
self.tosca_flavor = _get_template('test_tosca_flavor.yaml') self.tosca_flavor = _get_template('test_tosca_flavor.yaml')
def test_updateimport(self): def test_updateimport(self):
@ -76,8 +77,9 @@ class TestToscaUtils(testtools.TestCase):
'test_tosca_post_process_template.yaml') 'test_tosca_post_process_template.yaml')
vnfd_dict = yaml.safe_load(tosca_post_process_tpl) vnfd_dict = yaml.safe_load(tosca_post_process_tpl)
toscautils.updateimports(vnfd_dict) toscautils.updateimports(vnfd_dict)
tosca = tosca_template.ToscaTemplate(parsed_params={}, a_file=False, tosca = tosca_template.ToscaTemplate(
yaml_dict_tpl=vnfd_dict) parsed_params={}, a_file=False, yaml_dict_tpl=vnfd_dict,
local_defs=toscautils.tosca_tmpl_local_defs())
toscautils.post_process_template(tosca) toscautils.post_process_template(tosca)
invalidNodes = 0 invalidNodes = 0
@ -123,7 +125,8 @@ class TestToscaUtils(testtools.TestCase):
def test_post_process_heat_template(self): def test_post_process_heat_template(self):
tosca1 = tosca_template.ToscaTemplate(parsed_params={}, a_file=False, tosca1 = tosca_template.ToscaTemplate(parsed_params={}, a_file=False,
yaml_dict_tpl=self.vnfd_dict) yaml_dict_tpl=self.vnfd_dict,
local_defs=toscautils.tosca_tmpl_local_defs())
toscautils.post_process_template(tosca1) toscautils.post_process_template(tosca1)
translator = tosca_translator.TOSCATranslator(tosca1, {}) translator = tosca_translator.TOSCATranslator(tosca1, {})
heat_template_yaml = translator.translate() heat_template_yaml = translator.translate()
@ -148,8 +151,9 @@ class TestToscaUtils(testtools.TestCase):
def test_get_flavor_dict(self): def test_get_flavor_dict(self):
vnfd_dict = yaml.safe_load(self.tosca_flavor) vnfd_dict = yaml.safe_load(self.tosca_flavor)
toscautils.updateimports(vnfd_dict) toscautils.updateimports(vnfd_dict)
tosca = tosca_template.ToscaTemplate(a_file=False, tosca = tosca_template.ToscaTemplate(
yaml_dict_tpl=vnfd_dict) a_file=False, yaml_dict_tpl=vnfd_dict,
local_defs=toscautils.tosca_tmpl_local_defs())
expected_flavor_dict = { expected_flavor_dict = {
"VDU1": { "VDU1": {
"vcpus": 2, "vcpus": 2,
@ -181,8 +185,9 @@ class TestToscaUtils(testtools.TestCase):
'tosca_flavor_all_numa_count.yaml') 'tosca_flavor_all_numa_count.yaml')
vnfd_dict = yaml.safe_load(tosca_fes_all_numa_count) vnfd_dict = yaml.safe_load(tosca_fes_all_numa_count)
toscautils.updateimports(vnfd_dict) toscautils.updateimports(vnfd_dict)
tosca = tosca_template.ToscaTemplate(a_file=False, tosca = tosca_template.ToscaTemplate(
yaml_dict_tpl=vnfd_dict) a_file=False, yaml_dict_tpl=vnfd_dict,
local_defs=toscautils.tosca_tmpl_local_defs())
expected_flavor_dict = { expected_flavor_dict = {
"VDU1": { "VDU1": {
"vcpus": 8, "vcpus": 8,
@ -204,8 +209,9 @@ class TestToscaUtils(testtools.TestCase):
'tosca_flavor_with_wrong_cpu.yaml') 'tosca_flavor_with_wrong_cpu.yaml')
vnfd_dict = yaml.safe_load(tosca_fes) vnfd_dict = yaml.safe_load(tosca_fes)
toscautils.updateimports(vnfd_dict) toscautils.updateimports(vnfd_dict)
tosca = tosca_template.ToscaTemplate(a_file=False, tosca = tosca_template.ToscaTemplate(
yaml_dict_tpl=vnfd_dict) a_file=False, yaml_dict_tpl=vnfd_dict,
local_defs=toscautils.tosca_tmpl_local_defs())
self.assertRaises(vnfm.CpuAllocationInvalidValues, self.assertRaises(vnfm.CpuAllocationInvalidValues,
toscautils.get_flavor_dict, toscautils.get_flavor_dict,
@ -216,8 +222,9 @@ class TestToscaUtils(testtools.TestCase):
'tosca_flavor_all_numa_count.yaml') 'tosca_flavor_all_numa_count.yaml')
vnfd_dict = yaml.safe_load(tosca_fes_all_numa_count) vnfd_dict = yaml.safe_load(tosca_fes_all_numa_count)
toscautils.updateimports(vnfd_dict) toscautils.updateimports(vnfd_dict)
tosca = tosca_template.ToscaTemplate(a_file=False, tosca = tosca_template.ToscaTemplate(
yaml_dict_tpl=vnfd_dict) a_file=False, yaml_dict_tpl=vnfd_dict,
local_defs=toscautils.tosca_tmpl_local_defs())
expected_flavor_dict = { expected_flavor_dict = {
"VDU1": { "VDU1": {
"vcpus": 8, "vcpus": 8,

View File

@ -19,12 +19,17 @@ import re
import shutil import shutil
import threading import threading
from oslo_utils import uuidutils
import socketserver import socketserver
import tempfile import tempfile
import yaml import yaml
import zipfile import zipfile
from oslo_log import log as logging
from oslo_utils import uuidutils
LOG = logging.getLogger(__name__)
def read_file(input_file): def read_file(input_file):
yaml_file = os.path.abspath(os.path.join(os.path.dirname(__file__), yaml_file = os.path.abspath(os.path.join(os.path.dirname(__file__),

View File

@ -32,8 +32,9 @@ from toscaparser import properties
from toscaparser.utils import yamlparser from toscaparser.utils import yamlparser
FAILURE = 'tosca.policies.tacker.Failure'
LOG = logging.getLogger(__name__) LOG = logging.getLogger(__name__)
FAILURE = 'tosca.policies.tacker.Failure'
MONITORING = 'tosca.policies.Monitoring' MONITORING = 'tosca.policies.Monitoring'
SCALING = 'tosca.policies.Scaling' SCALING = 'tosca.policies.Scaling'
RESERVATION = 'tosca.policies.Reservation' RESERVATION = 'tosca.policies.Reservation'
@ -1388,3 +1389,58 @@ def get_scale_group(vnf_dict, vnfd_dict, inst_req_info):
scaling_group_dict.update({'scaleGroupDict': data_dict}) scaling_group_dict.update({'scaleGroupDict': data_dict})
return scaling_group_dict return scaling_group_dict
def tosca_tmpl_local_defs():
"""Return local defs for ToscaTemplate
It's a remedy to avoid a failure for a busy access while importing remote
definition in a TOSCA template. While instantiating a ToscaTemplate obj
with given local_defs arg, it uses a local file instead of remote one by
referring the local defs returned from this function. The returned value
is a dict consists of entries of url and local path such as below.
.. code-block:: python
{
"https://forge.etsi.org/.../aaa.yaml": "/path/to/aaa.yaml",
"https://forge.etsi.org/.../bbb.yaml": "/path/to/bbb.yaml"
}
:return: A set of url and local file path as a dict
"""
def sol001_url(ver, fname):
baseurl = "https://forge.etsi.org/rep/nfv/SOL001"
return os.path.join(baseurl, "raw", "v" + ver, fname)
def path_sol001_def(ver, fname):
"""Return a path of specified ETSI's def file.
The name of file given with `fname` follows the original repo
https://forge.etsi.org/rep/nfv/SOL001.
"""
fpath = os.path.join(utils.proj_root(), "etc", "etsi-nfv", "sol001",
ver, fname)
try:
if os.path.isfile(fpath) is not True:
raise FileNotFoundError
except FileNotFoundError:
LOG.error("No SOL001 def file found '%'", fpath)
return fpath
ldefs = {}
# NOTE(yasufum): There are several updates made for each definitions under
# SOL001, but no all of versions are required for tests in tacker
# currently.
# TODO(yasufum): Add all required defs for supporting several usecases
# although tacker uses just a few defs as below. We can find all the
# version in commits of SOL001's repo.
fname = "etsi_nfv_sol001_common_types.yaml"
def_ver = "2.6.1"
k = sol001_url(def_ver, fname)
v = path_sol001_def(def_ver, fname)
ldefs[k] = v
return ldefs

View File

@ -1128,8 +1128,9 @@ def _convert_desired_capacity(inst_level_id, vnfd_dict, vdu):
aspect_max_level_dict = {} aspect_max_level_dict = {}
desired_capacity = 1 desired_capacity = 1
tosca = tosca_template.ToscaTemplate(parsed_params={}, a_file=False, tosca = tosca_template.ToscaTemplate(
yaml_dict_tpl=vnfd_dict) parsed_params={}, a_file=False, yaml_dict_tpl=vnfd_dict,
local_defs=toscautils.tosca_tmpl_local_defs())
tosca_policies = tosca.topology_template.policies tosca_policies = tosca.topology_template.policies
default_inst_level_id = toscautils._extract_policy_info( default_inst_level_id = toscautils._extract_policy_info(
tosca_policies, inst_level_dict, tosca_policies, inst_level_dict,
@ -1252,8 +1253,9 @@ def get_default_scale_status(context, vnf_instance, vnfd_dict):
vnfd_dict = _get_vnfd_dict(context, vnfd_dict = _get_vnfd_dict(context,
vnf_instance.vnfd_id, vnf_instance.vnfd_id,
vnf_instance.instantiated_vnf_info.flavour_id) vnf_instance.instantiated_vnf_info.flavour_id)
tosca = tosca_template.ToscaTemplate(parsed_params={}, a_file=False, tosca = tosca_template.ToscaTemplate(
yaml_dict_tpl=vnfd_dict) parsed_params={}, a_file=False, yaml_dict_tpl=vnfd_dict,
local_defs=toscautils.tosca_tmpl_local_defs())
extract_policy_infos = get_extract_policy_infos(tosca) extract_policy_infos = get_extract_policy_infos(tosca)
if extract_policy_infos['inst_level_dict'] is None: if extract_policy_infos['inst_level_dict'] is None:

View File

@ -42,6 +42,7 @@ from tacker import manager
from tacker import objects from tacker import objects
from tacker.objects import fields from tacker.objects import fields
from tacker.objects.fields import ErrorPoint as EP from tacker.objects.fields import ErrorPoint as EP
from tacker.tosca import utils as toscautils
from tacker.vnflcm import abstract_driver from tacker.vnflcm import abstract_driver
from tacker.vnflcm import utils as vnflcm_utils from tacker.vnflcm import utils as vnflcm_utils
@ -1420,7 +1421,8 @@ class VnfLcmDriver(abstract_driver.VnfInstanceAbstractDriver):
vnf_instance.vnfd_id, vnf_instance.vnfd_id,
vnf_instance.instantiated_vnf_info.flavour_id) vnf_instance.instantiated_vnf_info.flavour_id)
tosca = tosca_template.ToscaTemplate( tosca = tosca_template.ToscaTemplate(
parsed_params={}, a_file=False, yaml_dict_tpl=vnfd_dict) parsed_params={}, a_file=False, yaml_dict_tpl=vnfd_dict,
local_defs=toscautils.tosca_tmpl_local_defs())
extract_policy_infos = vnflcm_utils.get_extract_policy_infos(tosca) extract_policy_infos = vnflcm_utils.get_extract_policy_infos(tosca)
policy['vdu_defs'] = vnflcm_utils.get_target_vdu_def_dict( policy['vdu_defs'] = vnflcm_utils.get_target_vdu_def_dict(
extract_policy_infos=extract_policy_infos, extract_policy_infos=extract_policy_infos,

View File

@ -72,7 +72,8 @@ class Parser(object):
tosca = tosca_template.\ tosca = tosca_template.\
ToscaTemplate(parsed_params=parserd_params, ToscaTemplate(parsed_params=parserd_params,
a_file=False, a_file=False,
yaml_dict_tpl=self.vnfd_dict) yaml_dict_tpl=self.vnfd_dict,
local_defs=toscautils.tosca_tmpl_local_defs())
except Exception as e: except Exception as e:
LOG.error("tosca-parser error: %s", str(e)) LOG.error("tosca-parser error: %s", str(e))
raise vnfm.ToscaParserFailed(error_msg_details=str(e)) raise vnfm.ToscaParserFailed(error_msg_details=str(e))

View File

@ -41,6 +41,7 @@ from tacker.objects.fields import ErrorPoint as EP
from tacker.objects import vnf_package as vnf_package_obj from tacker.objects import vnf_package as vnf_package_obj
from tacker.objects import vnf_package_vnfd as vnfd_obj from tacker.objects import vnf_package_vnfd as vnfd_obj
from tacker.objects import vnf_resources as vnf_resource_obj from tacker.objects import vnf_resources as vnf_resource_obj
from tacker.tosca import utils as toscautils # TODO(yasufum)
from tacker.vnflcm import utils as vnflcm_utils from tacker.vnflcm import utils as vnflcm_utils
from tacker.vnfm.infra_drivers import abstract_driver from tacker.vnfm.infra_drivers import abstract_driver
from tacker.vnfm.infra_drivers.kubernetes.helm import helm_client from tacker.vnfm.infra_drivers.kubernetes.helm import helm_client
@ -1660,8 +1661,9 @@ class Kubernetes(abstract_driver.VnfAbstractDriver,
# check parameters for scale operation # check parameters for scale operation
vnfd = vnflcm_utils.get_vnfd_dict(context, vnf_instance.vnfd_id, vnfd = vnflcm_utils.get_vnfd_dict(context, vnf_instance.vnfd_id,
instantiate_vnf_req.flavour_id) instantiate_vnf_req.flavour_id)
tosca = tosca_template.ToscaTemplate(parsed_params={}, a_file=False, tosca = tosca_template.ToscaTemplate(
yaml_dict_tpl=vnfd) parsed_params={}, a_file=False, yaml_dict_tpl=vnfd,
local_defs=toscautils.tosca_tmpl_local_defs())
extract_policy_infos = vnflcm_utils.get_extract_policy_infos(tosca) extract_policy_infos = vnflcm_utils.get_extract_policy_infos(tosca)
helm_replica_values = additional_params.get('helm_replica_values', {}) helm_replica_values = additional_params.get('helm_replica_values', {})
for aspect_id in extract_policy_infos['aspect_id_dict'].keys(): for aspect_id in extract_policy_infos['aspect_id_dict'].keys():
@ -1988,7 +1990,8 @@ class Kubernetes(abstract_driver.VnfAbstractDriver,
context, vnf_instance.vnfd_id, context, vnf_instance.vnfd_id,
vnf_instance.instantiated_vnf_info.flavour_id) vnf_instance.instantiated_vnf_info.flavour_id)
tosca = tosca_template.ToscaTemplate( tosca = tosca_template.ToscaTemplate(
parsed_params={}, a_file=False, yaml_dict_tpl=vnfd_dict) parsed_params={}, a_file=False, yaml_dict_tpl=vnfd_dict,
local_defs=toscautils.tosca_tmpl_local_defs())
tosca_node_tpls = tosca.topology_template.nodetemplates tosca_node_tpls = tosca.topology_template.nodetemplates
# get vdu_ids dict {vdu_name: vdu_id} from VNFD # get vdu_ids dict {vdu_name: vdu_id} from VNFD
vdu_ids = {} vdu_ids = {}
@ -2512,9 +2515,9 @@ class Kubernetes(abstract_driver.VnfAbstractDriver,
vnfd_dict = vnflcm_utils._get_vnfd_dict(context, vnfd_dict = vnflcm_utils._get_vnfd_dict(context,
vnf_instance.vnfd_id, vnf_instance.vnfd_id,
inst_vnf_info.flavour_id) inst_vnf_info.flavour_id)
tosca = tosca_template.ToscaTemplate(parsed_params={}, tosca = tosca_template.ToscaTemplate(
a_file=False, parsed_params={}, a_file=False, yaml_dict_tpl=vnfd_dict,
yaml_dict_tpl=vnfd_dict) local_defs=toscautils.tosca_tmpl_local_defs())
extract_policy_infos = vnflcm_utils.get_extract_policy_infos(tosca) extract_policy_infos = vnflcm_utils.get_extract_policy_infos(tosca)
aspect_id = scale_vnf_request.aspect_id aspect_id = scale_vnf_request.aspect_id
vdu_defs = vnflcm_utils.get_target_vdu_def_dict( vdu_defs = vnflcm_utils.get_target_vdu_def_dict(
@ -2592,8 +2595,9 @@ class Kubernetes(abstract_driver.VnfAbstractDriver,
vnfd_dict = vnflcm_utils._get_vnfd_dict(context, vnfd_dict = vnflcm_utils._get_vnfd_dict(context,
vnf_instance.vnfd_id, vnf_instance.vnfd_id,
vnf_instance.instantiated_vnf_info.flavour_id) vnf_instance.instantiated_vnf_info.flavour_id)
tosca = tosca_template.ToscaTemplate(parsed_params={}, a_file=False, tosca = tosca_template.ToscaTemplate(
yaml_dict_tpl=vnfd_dict) parsed_params={}, a_file=False, yaml_dict_tpl=vnfd_dict,
local_defs=toscautils.tosca_tmpl_local_defs())
extract_policy_infos = vnflcm_utils.get_extract_policy_infos(tosca) extract_policy_infos = vnflcm_utils.get_extract_policy_infos(tosca)
policy = dict() policy = dict()
@ -2635,8 +2639,9 @@ class Kubernetes(abstract_driver.VnfAbstractDriver,
vnfd_dict = vnflcm_utils._get_vnfd_dict(context, vnfd_dict = vnflcm_utils._get_vnfd_dict(context,
vnf_instance.vnfd_id, vnf_instance.vnfd_id,
vnf_instance.instantiated_vnf_info.flavour_id) vnf_instance.instantiated_vnf_info.flavour_id)
tosca = tosca_template.ToscaTemplate(parsed_params={}, a_file=False, tosca = tosca_template.ToscaTemplate(
yaml_dict_tpl=vnfd_dict) parsed_params={}, a_file=False, yaml_dict_tpl=vnfd_dict,
local_defs=toscautils.tosca_tmpl_local_defs())
extract_policy_infos = vnflcm_utils.get_extract_policy_infos(tosca) extract_policy_infos = vnflcm_utils.get_extract_policy_infos(tosca)
policy = dict() policy = dict()

View File

@ -279,9 +279,10 @@ class TOSCAToHOT(object):
) )
try: try:
tosca = tosca_template.ToscaTemplate(parsed_params=parsed_params, tosca = tosca_template.ToscaTemplate(
a_file=False, parsed_params=parsed_params, a_file=False,
yaml_dict_tpl=vnfd_dict) yaml_dict_tpl=vnfd_dict,
local_defs=toscautils.tosca_tmpl_local_defs())
except Exception as e: except Exception as e:
LOG.error("tosca-parser error: %s", str(e)) LOG.error("tosca-parser error: %s", str(e))

View File

@ -215,8 +215,10 @@ class VNFMPlugin(vnfm_db.VNFMPluginDb, VNFMMgmtMixin):
toscautils.updateimports(inner_vnfd_dict) toscautils.updateimports(inner_vnfd_dict)
try: try:
tosca = ToscaTemplate(a_file=False, tosca = ToscaTemplate(
yaml_dict_tpl=inner_vnfd_dict) a_file=False,
yaml_dict_tpl=inner_vnfd_dict,
local_defs=toscautils.tosca_tmpl_local_defs())
except Exception as e: except Exception as e:
LOG.exception("tosca-parser error: %s", str(e)) LOG.exception("tosca-parser error: %s", str(e))
raise vnfm.ToscaParserFailed(error_msg_details=str(e)) raise vnfm.ToscaParserFailed(error_msg_details=str(e))
@ -263,8 +265,10 @@ class VNFMPlugin(vnfm_db.VNFMPluginDb, VNFMMgmtMixin):
return return
try: try:
toscautils.updateimports(vnfd_dict) toscautils.updateimports(vnfd_dict)
tosca_vnfd = ToscaTemplate(a_file=False, tosca_vnfd = ToscaTemplate(
yaml_dict_tpl=vnfd_dict) a_file=False,
yaml_dict_tpl=vnfd_dict,
local_defs=toscautils.tosca_tmpl_local_defs())
except Exception as e: except Exception as e:
LOG.exception("tosca-parser error: %s", str(e)) LOG.exception("tosca-parser error: %s", str(e))
raise vnfm.ToscaParserFailed(error_msg_details=str(e)) raise vnfm.ToscaParserFailed(error_msg_details=str(e))