'cloud-init-file',]
IGNORE_PROPS = []
- toscatype = 'tosca.nodes.Compute'
+ toscatype = 'tosca.nodes.nfv.VDU'
+
+ VALUE_TYPE_CONVERSION_MAP = {
+ 'integer': 'INT',
+ 'string':'STRING',
+ 'float':'DECIMAL'
+ }
def __init__(self, log, nodetemplate, metadata=None):
super(ToscaCompute, self).__init__(log,
self._vnf = None
self._yang = None
self._id = self.name
+ self._monitor_param = []
+ self._mgmt_interface = {}
@property
def image(self):
def handle_capabilities(self):
+ def get_mgmt_interface(specs):
+ mgmt_intfce = {}
+ mgmt_intfce['vdu-id'] = self.id
+ if 'dashboard_params' in specs:
+ mgmt_intfce['dashboard-params'] = {'path':specs['dashboard_params']['path'], 'port':specs['dashboard_params']['port']}
+ if 'port' in specs:
+ mgmt_intfce['port'] = specs['port']
+ return mgmt_intfce;
+
+ def get_monitor_param(specs, monitor_id):
+ monitor_param = {}
+ monitor_param['id'] = monitor_id
+ if 'name' in specs:
+ monitor_param['name'] = specs['name']
+ if 'json_query_method' in specs:
+ monitor_param['json_query_method'] = specs['json_query_method'].upper()
+ if 'description' in specs:
+ monitor_param['description'] = specs['description']
+ if 'url_path' in specs:
+ monitor_param['http-endpoint-ref'] = specs['url_path']
+ if 'ui_data' in specs:
+ if 'widget_type' in specs['ui_data']:
+ monitor_param['widget-type'] = specs['ui_data']['widget_type'].upper()
+ if 'units' in specs['ui_data']:
+ monitor_param['units'] = specs['ui_data']['units']
+ if 'group_tag' in specs['ui_data']:
+ monitor_param['group_tag'] = specs['ui_data']['group_tag']
+ if 'constraints' in specs:
+ if 'value_type' in specs['constraints']:
+ monitor_param['value-type'] = ToscaCompute.VALUE_TYPE_CONVERSION_MAP[specs['constraints']['value_type']]
+
+ return monitor_param
+
def get_vm_flavor(specs):
vm_flavor = {}
if 'num_cpus' in specs:
return vm_flavor
+ def get_host_epa(specs):
+ host_epa = {}
+ if 'cpu_model' in specs:
+ host_epa["cpu-model"] = specs['cpu_model'].upper()
+ if 'cpu_arch' in specs:
+ host_epa["cpu-arch"] = specs['cpu_arch'].upper()
+ if 'cpu_vendor' in specs:
+ host_epa["cpu-vendor"] = specs['cpu_vendor'].upper()
+ if 'cpu_socket_count' in specs:
+ host_epa["cpu-socket-count"] = specs['cpu_socket_count']
+ if 'cpu_core_count' in specs:
+ host_epa["cpu-core-count"] = specs['cpu_core_count']
+ if 'cpu_core_thread_count' in specs:
+ host_epa["cpu-core-thread-count"] = specs['cpu_core_thread_count']
+ if 'om_cpu_model_string' in specs:
+ host_epa["om-cpu-model-string"] = specs['om_cpu_model_string']
+ if 'cpu_feature' in specs:
+ cpu_feature_prop = []
+ for spec in specs['cpu_feature']:
+ cpu_feature_prop.append({'feature':spec.upper()})
+ host_epa['cpu-feature'] = cpu_feature_prop
+ if 'om_cpu_feature' in specs:
+ cpu_feature_prop = []
+ for spec in specs['om_cpu_feature']:
+ cpu_feature_prop.append({'feature':spec})
+ host_epa['om-cpu-feature'] = cpu_feature_prop
+ return host_epa;
+
+ def get_vswitch_epa(specs):
+ vswitch_epa = {}
+ if 'ovs_acceleration' in specs:
+ vswitch_epa['ovs-acceleration'] = specs['ovs_acceleration'].upper()
+ if 'ovs_offload' in specs:
+ vswitch_epa['ovs-offload'] = specs['ovs_offload'].upper()
+ return vswitch_epa
+
+ def get_hypervisor_epa(specs):
+ hypervisor_epa = {}
+ if 'type' in specs:
+ hypervisor_epa['type'] = specs['type'].upper()
+ if 'version' in specs:
+ hypervisor_epa['version'] = specs['version']
+
+ return hypervisor_epa
+
+ def get_guest_epa(specs):
+ guest_epa = {}
+ guest_epa['numa-node-policy'] = {}
+ guest_epa['numa-node-policy']['node'] = []
+ if 'mem_policy' in specs:
+ guest_epa['numa-node-policy']['mem-policy'] = specs['mem_policy'].upper()
+ if 'node_cnt' in specs:
+ guest_epa['numa-node-policy']['node-cnt'] = specs['node_cnt']
+ if 'node' in specs:
+ for node in specs['node']:
+ node_prop = {}
+ if 'id' in node:
+ node_prop['id'] = node['id']
+ if 'mem_size' in node:
+ if 'MiB' in node['mem_size'] or 'MB' in node['mem_size']:
+ node_prop['memory-mb'] = int(node['mem_size'].replace('MB',''))
+ else:
+ err_msg = "Specify mem_size of NUMA extension should be in MB"
+ raise ValidationError(message=err_msg)
+ if 'om_numa_type' in node:
+ numa_type = node['om_numa_type']
+ if 'paired-threads' == numa_type:
+ node_prop['paired_threads'] = {}
+ node_prop['paired_threads']['num_paired_threads'] = node['paired_threads']['num_paired_threads']
+ elif 'threads' == numa_type:
+ if 'num_threads' in node:
+ node_prop['num_threads'] = node['num_threads']
+ elif 'cores' == numa_type:
+ if 'num_cores' in node:
+ node_prop['num_cores'] = node['num_cores']
+ else:
+ err_msg = "om_numa_type should be among cores, paired-threads or threads"
+ raise ValidationError(message=err_msg)
+ guest_epa['numa-node-policy']['node'].append(node_prop)
+ return guest_epa
+
tosca_caps = self.get_tosca_caps()
self.log.debug(_("VDU {0} tosca capabilites: {1}").
format(self.name, tosca_caps))
-
- if 'host' in tosca_caps:
- self.properties['vm-flavor'] = get_vm_flavor(tosca_caps['host'])
+ if 'nfv_compute' in tosca_caps:
+ self.properties['vm-flavor'] = get_vm_flavor(tosca_caps['nfv_compute'])
self.log.debug(_("VDU {0} properties: {1}").
format(self.name, self.properties))
+ if 'host_epa' in tosca_caps:
+ self.properties['host-epa'] = get_host_epa(tosca_caps['host_epa'])
+ if 'hypervisor_epa' in tosca_caps:
+ self.properties['hypervisor-epa'] = get_hypervisor_epa(tosca_caps['hypervisor_epa'])
+ if 'vswitch_epa' in tosca_caps:
+ self.properties['vswitch-epa'] = get_vswitch_epa(tosca_caps['vswitch_epa'])
+ if 'numa_extension' in tosca_caps:
+ self.properties['guest-epa'] = get_guest_epa(tosca_caps['numa_extension'])
+ if 'monitoring_param' in tosca_caps:
+ self._monitor_param.append(get_monitor_param(tosca_caps['monitoring_param'], '1'))
+ if 'monitoring_param_1' in tosca_caps:
+ self._monitor_param.append(get_monitor_param(tosca_caps['monitoring_param_1'], '2'))
+ if 'mgmt_interface' in tosca_caps:
+ self._mgmt_interface = get_mgmt_interface(tosca_caps['mgmt_interface'])
def handle_artifacts(self):
if self.artifacts is None:
if isinstance(props, dict):
details = {}
for name, value in props.items():
- if name == 'type':
+ if name == 'type' and value == 'tosca.artifacts.Deployment.Image.riftio.QCOW2':
prefix, type_ = value.rsplit('.', 1)
if type_ == 'QCOW2':
details['type'] = 'qcow2'
- else:
- err_msg = _("VDU {0}, Currently only QCOW2 images "
- "are supported in artifacts ({1}:{2})"). \
- format(self.name, key, value)
- self.log.error(err_msg)
- raise ValidationError(message=err_msg)
+ self.properties['image'] = os.path.basename(props['file'])
+ elif name == 'type' and value == 'tosca.artifacts.Deployment.riftio.cloud_init_file':
+ details['cloud_init_file'] = os.path.basename(props['file'])
+ self.properties['cloud_init_file'] = os.path.basename(props['file'])
elif name == 'file':
details['file'] = value
elif name == 'image_checksum':
- details['image_checksum'] = value
+ self.properties['image_checksum'] = value
else:
self.log.warn(_("VDU {0}, unsuported attribute {1}").
format(self.name, name))
return None
self._update_properties_for_model()
props = convert_keys_to_python(self.properties)
+
+ for monitor_param in self._monitor_param:
+ monitor_props = convert_keys_to_python(monitor_param)
+ vnfd.monitoring_param.add().from_dict(monitor_props)
try:
+ if len(self._mgmt_interface) > 0:
+ vnfd.mgmt_interface.from_dict(convert_keys_to_python(self._mgmt_interface))
vnfd.vdu.add().from_dict(props)
except Exception as e:
err_msg = _("{0} Exception vdu from dict {1}: {2}"). \
--- /dev/null
+from rift.mano.tosca_translator.rwmano.syntax.mano_resource import ManoResource
+from toscaparser.functions import GetInput
+
+TARGET_CLASS_NAME = 'ToscaForwardingGraph'
+class ToscaForwardingGraph(ManoResource):
+ '''Translate TOSCA node type tosca.nodes.nfv.FP'''
+ toscatype = 'tosca.groups.nfv.VNFFG'
+
+ def __init__(self, log, group, metadata=None):
+ #super(ToscaForwardingGraph, self).__init__(log, nodetemplate, type_='forwardgraph', metadata=metadata)
+ super(ToscaForwardingGraph, self).__init__(log,
+ group,
+ type_="vnfgd",
+ metadata=metadata)
+ self.name = group.name
+ self.type_ = 'vnffg'
+ self.metadata = metadata
+ self.group = group
+ self.properties = {}
+ self.classifiers = []
+ self.rsp = []
+ self.log = log
+
+ def get_tosca_group_props(self):
+ tosca_props = {}
+ for prop in self.group.get_properties_objects():
+ if isinstance(prop.value, GetInput):
+ tosca_props[prop.name] = {'get_param': prop.value.input_name}
+ else:
+ tosca_props[prop.name] = prop.value
+ return tosca_props
+
+ def handle_properties(self, nodes, groups):
+ self.properties['name'] = self.name
+ self.properties['vendor'] = self.metadata['vendor']
+ self.properties['id'] = self.id
+ self.properties['classifier'] = []
+ self.properties['rsp'] = []
+
+ tosca_props = self.get_tosca_group_props()
+ forwarding_paths = []
+ for member in self.group.members:
+ forwarding_paths.append(member)
+
+ for forwarding_path in forwarding_paths:
+ node = self.get_node_with_name(forwarding_path, nodes)
+ if node.classifier is not None:
+ self.properties['classifier'].append(node.classifier)
+ if node.rsp is not None:
+ self.properties['rsp'].append(node.rsp)
+
+ def generate_yang_model_gi(self, nsd, vnfds):
+ try:
+ nsd.vnffgd.add().from_dict(self.properties)
+ except Exception as e:
+ err_msg = "Error updating VNNFG to nsd"
+ self.log.error(err_msg)
+ raise e
+
+ def generate_yang_model(self, nsd, vnfds, use_gi=False):
+ if use_gi:
+ return self.generate_yang_model_gi(nsd, vnfds)
\ No newline at end of file
--- /dev/null
+from rift.mano.tosca_translator.rwmano.syntax.mano_resource import ManoResource
+import uuid
+
+
+TARGET_CLASS_NAME = 'ToscaForwardingPath'
+class ToscaForwardingPath(ManoResource):
+ '''Translate TOSCA node type tosca.nodes.nfv.FP'''
+
+ toscatype = 'tosca.nodes.nfv.FP'
+
+
+ def __init__(self, log, node, metadata=None):
+ super(ToscaForwardingPath, self).__init__(log, node, type_='forwarding_path', metadata=metadata)
+ self.metadata = metadata
+ self.classifier = None
+ self.rsp = None
+ self.cp = None
+ self.properties = {}
+
+ def handle_forwarding_path_dependencies(self, nodes, vnf_type_to_capability_substitution_mapping):
+ def get_classifier(specs):
+ classifier_prop = {}
+ classifier_prop['name'] = 'VNFFG -' + str(self.name)
+ classifier_prop['id'] = self.id
+ if 'policy' in specs:
+ classifier_prop['match_attributes'] = []
+ policy = specs['policy']
+ if 'criteria' in policy:
+ match_prop = {}
+ match_prop['id'] = str(uuid.uuid1())
+ for criteria in policy['criteria']:
+ if 'ip_dst_prefix' in criteria:
+ match_prop['destination_ip_address'] = criteria['ip_dst_prefix']
+ if 'ip_proto' in criteria:
+ match_prop['ip_proto'] = criteria['ip_proto']
+ if 'source_port_range' in criteria:
+ match_prop['source_port'] = int(criteria['source_port_range'])
+ if 'destination_port_range' in criteria:
+ match_prop['destination_port'] = int(criteria['destination_port_range'])
+ classifier_prop['match_attributes'].append(match_prop)
+ if 'cp' in specs:
+ cp_node_name = specs['cp']['capability']
+ cp_node = self.get_node_with_name(cp_node_name, nodes)
+ if cp_node:
+ classifier_prop['vnfd_connection_point_ref'] = cp_node.cp_name
+ if 'cp' in specs:
+ vnf_node_name = specs['cp']['forwarder']
+ vnf_node = self.get_node_with_name(vnf_node_name, nodes)
+ if vnf_node:
+ classifier_prop['vnfd_id_ref'] = vnf_node.id
+ classifier_prop['member_vnf_index_ref'] = vnf_node.get_member_vnf_index()
+ return classifier_prop
+
+ def get_rsp(specs):
+ rsp = {}
+ rsp['id'] = str(uuid.uuid1())
+ rsp['name'] = 'VNFFG-RSP-' + str(self.name)
+ rsp['vnfd_connection_point_ref'] = []
+ if 'path' in specs:
+ fp_connection_point = []
+ vnf_index = 1
+ order_index = 1
+ for rsp_item in specs['path']:
+ vnf_node_name = rsp_item['forwarder']
+ conn_forwarder = rsp_item['capability']
+ vnf_node = self.get_node_with_name(vnf_node_name, nodes)
+ for subs_mapping in vnf_type_to_capability_substitution_mapping[vnf_node.vnf_type]:
+ prop = {}
+ if conn_forwarder in subs_mapping:
+ fp_connection_point.append(subs_mapping[conn_forwarder])
+ cp_node_name = subs_mapping[conn_forwarder]
+ cp_node = self.get_node_with_name(cp_node_name, nodes)
+ prop['vnfd_connection_point_ref'] = cp_node.cp_name
+ prop['vnfd_id_ref'] = vnf_node.id
+ prop['member_vnf_index_ref'] = vnf_index
+ prop['order'] = order_index
+ rsp['vnfd_connection_point_ref'].append(prop)
+ vnf_index = vnf_index + 1
+ order_index = order_index + 1
+ return rsp
+
+ tosca_props = self.get_tosca_props()
+ self.classifier = get_classifier(tosca_props)
+ self.rsp = get_rsp(tosca_props)
+ if self.classifier and self.rsp:
+ self.classifier['rsp_id_ref'] = self.rsp['id']
from rift.mano.tosca_translator.common.utils import _
from rift.mano.tosca_translator.common.utils import convert_keys_to_python
from rift.mano.tosca_translator.rwmano.syntax.mano_resource import ManoResource
+from toscaparser.functions import GetInput
from toscaparser.common.exception import ValidationError
class ToscaInitialConfig(ManoResource):
'''Translate TOSCA node type tosca.policies.InitialConfigPrimitive.'''
- toscatype = 'tosca.policies.riftio.InitialConfigPrimitive'
+ toscatype = 'tosca.policies.nfv.riftio.initial_config_primitive'
IGNORE_PROPS = []
- def __init__(self, log, primitive, metadata=None):
+ def __init__(self, log, policy, metadata=None):
# TODO(Philip):Not inheriting for ManoResource, as there is no
# instance from parser
self.log = log
- for name, details in primitive.items():
- self.name = name
- self.details = details
- break
+ self.name = policy.name
+ self.policy = policy
self.type_ = 'initial-cfg'
self.metadata = metadata
self.properties = {}
return "%s(%s)" % (self.name, self.type)
def handle_properties(self, nodes, groups):
- tosca_props = self.details
+ tosca_props = self.get_policy_props()
self.log.debug(_("{0} with tosca properties: {1}").
format(self, tosca_props))
self.properties['name'] = tosca_props['name']
self.log.debug(_("{0} properties: {1}").format(self, self.properties))
+ def get_policy_props(self):
+ tosca_props = {}
+ for prop in self.policy.get_properties_objects():
+ if isinstance(prop.value, GetInput):
+ tosca_props[prop.name] = {'get_param': prop.value.input_name}
+ else:
+ tosca_props[prop.name] = prop.value
+ return tosca_props
def get_yang_model_gi(self, nsd, vnfds):
props = convert_keys_to_python(self.properties)
try:
nodetemplate,
type_='vld',
metadata=metadata)
-
- def handle_properties(self):
+ self._vld = {}
+ self._ip_profile = {}
+
+ def handle_vld_properties(self, nodes, vnf_type_substitution_mapping):
+ def get_vld_props(specs):
+ vld_prop = {}
+ vld_prop['id'] = self.id
+ vld_prop['name'] = self.name
+ vld_prop['short-name'] = self.name
+ vld_prop['type'] = self.get_type()
+ if 'description' in specs:
+ vld_prop['description'] = specs['description']
+ if 'vendor' in specs:
+ vld_prop['vendor'] = specs['vendor']
+
+ index_count = 1
+ vld_connection_point_list = []
+ for node in nodes:
+ if node.type == "vnfd":
+ substitution_mapping_list = vnf_type_substitution_mapping[node.vnf_type];
+ for req_key, req_value in node._reqs.items():
+ for mapping in substitution_mapping_list:
+ if req_key in mapping:
+ # link the VLD to the connection point
+ node = self.get_node_with_name(mapping[req_key][0], nodes)
+ if node:
+ #print()
+ prop = {}
+ prop['member-vnf-index-ref'] = index_count
+ prop['vnfd-connection-point-ref'] = node.cp_name
+ prop['vnfd-id-ref'] = node.vnf._id
+ vld_connection_point_list.append(prop)
+ index_count += 1
+ if len(vld_connection_point_list) > 1:
+ vld_prop['vnfd-connection-point-ref'] = vld_connection_point_list
+ return vld_prop
+
+ def get_ip_profile_props(specs):
+ ip_profile_prop = {}
+ ip_profile_param = {}
+ if 'name' in specs:
+ ip_profile_prop['name'] = specs['name']
+ elif 'description' in specs:
+ ip_profile_prop['name'] = specs['description']
+
+ if 'description' in specs:
+ ip_profile_prop['description'] = specs['description']
+ if 'gateway_ip' in specs:
+ ip_profile_param['gateway-address'] = specs['gateway_ip']
+ if 'ip_version' in specs:
+ ip_profile_param['ip-version'] = 'ipv' + str(specs['ip_version'])
+ if 'ip_version' in specs:
+ ip_profile_param['subnet-address'] = specs['cidr']
+
+ ip_profile_prop['ip-profile-params'] = ip_profile_param
+ return ip_profile_prop
tosca_props = self.get_tosca_props()
-
- if 'cidr' in tosca_props.keys():
- self.log.warn(_("Support for subnet not yet "
- "available. Ignoring it"))
- net_props = {}
- for key, value in tosca_props.items():
- if key in self.NETWORK_PROPS:
- if key == 'network_name':
- net_props['name'] = value
- elif key == 'network_id':
- net_props['id'] = value
- else:
- net_props[key] = value
-
- net_props['type'] = self.get_type()
-
- if 'name' not in net_props:
- # Use the node name as network name
- net_props['name'] = self.name
-
- if 'short_name' not in net_props:
- # Use the node name as network name
- net_props['short-name'] = self.name
-
- if 'id' not in net_props:
- net_props['id'] = self.id
-
- if 'description' not in net_props:
- net_props['description'] = self.description
-
- if 'vendor' not in net_props:
- net_props['vendor'] = self.vendor
-
- if 'version' not in net_props:
- net_props['version'] = self.version
-
- self.log.debug(_("Network {0} properties: {1}").
- format(self.name, net_props))
- self.properties = net_props
+ self._vld = get_vld_props(tosca_props)
+ self._ip_profile = get_ip_profile_props(tosca_props)
def get_type(self):
"""Get the network type based on propery or type derived from"""
return "ELAN"
def generate_yang_model_gi(self, nsd, vnfds):
- props = convert_keys_to_python(self.properties)
+ props = convert_keys_to_python(self.properties)
+ vld_props = convert_keys_to_python(self._vld)
+ ip_profile_props = convert_keys_to_python(self._ip_profile)
try:
- nsd.vld.add().from_dict(props)
+ nsd.vld.add().from_dict(vld_props)
+ nsd.ip_profiles.add().from_dict(ip_profile_props)
except Exception as e:
err_msg = _("{0} Exception vld from dict {1}: {2}"). \
format(self, props, e)
metadata=metadata)
# Default order
self.order = 0
+ self.vnf = None
+ self.cp_name = None
pass
def handle_properties(self):
self.log.warn(err_msg)
raise ValidationError(message=err_msg)
+ self.cp_name = port_props['name']
self.properties = port_props
def handle_requirements(self, nodes):
tosca_reqs = self.get_tosca_reqs()
+ tosca_caps = self.get_tosca_caps()
self.log.debug("VNF {0} requirements: {1}".
format(self.name, tosca_reqs))
vnf = None # Need vnf ref to generate cp refs in vld
vld = None
+ '''
if len(tosca_reqs) != 2:
err_msg = _("Invalid configuration as incorrect number of "
"requirements for CP {0} are specified"). \
format(self)
self.log.error(err_msg)
raise ValidationError(message=err_msg)
-
+ '''
for req in tosca_reqs:
if 'virtualBinding' in req:
target = req['virtualBinding']['target']
node = self.get_node_with_name(target, nodes)
if node:
vnf = node.vnf
+ self.vnf = node._vnf
if not vnf:
err_msg = _("No vnfs linked to a VDU {0}"). \
format(node)
self.log.error(err_msg)
raise ValidationError(message=err_msg)
- if vnf and vld:
+ if 'sfc' in tosca_caps and vnf:
+ if 'sfc_type' in tosca_caps['sfc']:
+ vnf.properties['service-function-chain'] = tosca_caps['sfc']['sfc_type'].upper()
+ if 'sf_type' in tosca_caps['sfc']:
+ vnf.properties['service-function-type'] = tosca_caps['sfc']['sf_type']
+
+ if vnf:
cp_ref = {}
cp_ref['vnfd-connection-point-ref'] = self.properties['name']
cp_ref['vnfd-id-ref'] = vnf.properties['id']
cp_ref['member-vnf-index-ref'] = \
vnf._const_vnfd['member-vnf-index']
- if 'vnfd-connection-point-ref' not in vld.properties:
- vld.properties['vnfd-connection-point-ref'] = []
- vld.properties['vnfd-connection-point-ref'].append(cp_ref)
else:
- err_msg = _("CP {0}, VNF {1} or VL {2} not found"). \
+ err_msg = _("CP {0}, VNF {1} not found"). \
format(self, vnf, vld)
self.log.error(err_msg)
raise ValidationError(message=err_msg)
from rift.mano.tosca_translator.common.utils import _
from rift.mano.tosca_translator.common.utils import convert_keys_to_python
from rift.mano.tosca_translator.rwmano.syntax.mano_resource import ManoResource
+from toscaparser.functions import GetInput
from toscaparser.common.exception import ValidationError
'mgmt-interface']
OPTIONAL_PROPS = ['version', 'vendor', 'http-endpoint', 'monitoring-param',
'connection-point']
- IGNORE_PROPS = ['port']
+ IGNORE_PROPS = ['port', 'monitoring_param']
TOSCA_CAPS = ['mgmt_interface', 'http_endpoint', 'monitoring_param_0',
'monitoring_param_1', 'connection_point']
self._const_vnfd = {}
self._vnf_config = {}
self._vdus = []
+ self._policies = []
+ self._cps = []
+ self.vnf_type = nodetemplate.type
+ self._reqs = {}
def map_tosca_name_to_mano(self, name):
new_name = super().map_tosca_name_to_mano(name)
if 'start_by_default' in vnf_props:
self._const_vnfd['start-by-default'] = \
vnf_props.pop('start_by_default')
+ if 'logo' in self.metadata:
+ vnf_props['logo'] = self.metadata['logo']
self.log.debug(_("VNF {0} with constituent vnf: {1}").
format(self.name, self._const_vnfd))
self.log.debug(_("VDU {0} properties: {1}").
format(self.name, self.properties))
- def handle_requirements(self, nodes):
+ def handle_requirements(self, nodes, policies, vnf_type_to_vdus_map):
tosca_reqs = self.get_tosca_reqs()
- self.log.debug("VNF {0} requirements: {1}".
- format(self.name, tosca_reqs))
-
- try:
- for req in tosca_reqs:
- if 'vdus' in req:
- target = req['vdus']['target']
- node = self.get_node_with_name(target, nodes)
- if node:
- self._vdus.append(node)
- node._vnf = self
- # Add the VDU id to mgmt-intf
- if 'mgmt-interface' in self.properties:
- self.properties['mgmt-interface']['vdu-id'] = \
- node.id
- if 'vdu' in self.properties['mgmt-interface']:
- # Older yang
- self.properties['mgmt-interface'].pop('vdu')
- else:
- err_msg = _("VNF {0}, VDU {1} specified not found"). \
- format(self.name, target)
- self.log.error(err_msg)
- raise ValidationError(message=err_msg)
-
- except Exception as e:
- err_msg = _("Exception getting VDUs for VNF {0}: {1}"). \
- format(self.name, e)
- self.log.error(err_msg)
- raise e
-
- self.log.debug(_("VNF {0} properties: {1}").
- format(self.name, self.properties))
+ for req in tosca_reqs:
+ for key, value in req.items():
+ if 'target' in value:
+ self._reqs[key] = value['target']
+
+ for policy in policies:
+ if hasattr(policy, '_vnf_name') and policy._vnf_name == self.name:
+ self._policies.append(policy)
+
+
+ if self.vnf_type in vnf_type_to_vdus_map:
+ for vdu_node_name in vnf_type_to_vdus_map[self.vnf_type]:
+ node = self.get_node_with_name(vdu_node_name, nodes)
+ if node:
+ self._vdus.append(node)
+ node._vnf = self
+ # Add the VDU id to mgmt-intf
+ if 'mgmt-interface' in self.properties:
+ self.properties['mgmt-interface']['vdu-id'] = \
+ node.id
+ if 'vdu' in self.properties['mgmt-interface']:
+ # Older yang
+ self.properties['mgmt-interface'].pop('vdu')
+ else:
+ err_msg = _("VNF {0}, VDU {1} specified not found"). \
+ format(self.name, target)
+ self.log.error(err_msg)
+ raise ValidationError(message=err_msg)
def generate_yang_model_gi(self, nsd, vnfds):
vnfd_cat = RwVnfdYang.YangData_Vnfd_VnfdCatalog()
vnfd = vnfd_cat.vnfd.add()
props = convert_keys_to_python(self.properties)
+ for key in ToscaNfvVnf.IGNORE_PROPS:
+ if key in props:
+ props.pop(key)
try:
vnfd.from_dict(props)
except Exception as e:
# Update the VDU properties
for vdu in self._vdus:
vdu.generate_yang_submodel_gi(vnfd)
+ for policy in self._policies:
+ policy.generate_yang_submodel_gi(vnfd)
# Update constituent vnfd in nsd
try:
--- /dev/null
+#
+# Copyright 2016 RIFT.io Inc
+#
+# 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 rift.mano.tosca_translator.common.utils import _
+from rift.mano.tosca_translator.common.utils import convert_keys_to_python
+from rift.mano.tosca_translator.rwmano.syntax.mano_resource import ManoResource
+from toscaparser.functions import GetInput
+from rift.mano.tosca_translator.common.utils import convert_keys_to_python
+
+from toscaparser.common.exception import ValidationError
+
+
+# Name used to dynamically load appropriate map class.
+TARGET_CLASS_NAME = 'ToscaPlacementGroup'
+
+
+class ToscaPlacementGroup(ManoResource):
+ '''Translate TOSCA node type tosca.policies.Scaling.'''
+
+ toscatype = 'tosca.policies.nfv.riftio.placement'
+
+ IGNORE_PROPS = []
+
+ def __init__(self, log, policy, metadata=None, vnf_name=None):
+ self.log = log
+ self.name = policy.name
+ self.type_ = 'place-grp'
+ self.metadata = metadata
+ self.policy = policy
+ self.properties = {}
+ self._vnf_name = vnf_name
+
+ def __str__(self):
+ return "%s(%s)" % (self.name, self.type)
+
+ def handle_properties(self, nodes, groups):
+ tosca_props = self.get_policy_props()
+ self.properties['name'] = tosca_props['name']
+ self.properties['strategy'] = tosca_props['strategy']
+ self.properties['requirement'] = tosca_props['requirement']
+ if self._vnf_name is None:
+ self.properties['member-vnfd'] = []
+ index_count = 1
+ for node in self.policy.get_targets_list():
+ vnf_node = self.get_node_with_name(node.name, nodes)
+ prop = {}
+ prop['member-vnf-index-ref'] = index_count
+ prop['vnfd-id-ref'] = vnf_node.id
+ self.properties['member-vnfd'].append(prop)
+ index_count = index_count + 1
+ else:
+ self.properties['member-vdus'] = []
+ for node in self.policy.get_targets_list():
+ vdu_node = self.get_node_with_name(node.name, nodes)
+ prop = {}
+ prop['member-vdu-ref'] = vdu_node.name
+ self.properties['member-vdus'].append(prop)
+
+ def get_yang_model_gi(self, nsd, vnfds):
+ props = convert_keys_to_python(self.properties)
+ try:
+ if self._vnf_name is None:
+ nsd.placement_groups.add().from_dict(props)
+ except Exception as e:
+ err_msg = _("{0} Exception nsd placement-groups from dict {1}: {2}"). \
+ format(self, props, e)
+ self.log.error(err_msg)
+ raise e
+
+ def generate_yang_model(self, nsd, vnfds, use_gi=False):
+ if use_gi:
+ return self.get_yang_model_gi(nsd, vnfds)
+ if 'placement-groups' not in nsd:
+ nsd['placement-groups'] = []
+
+ for key, value in self.properties.items():
+ prim[key] = value
+ nsd['placement-groups'].append(prim)
+
+ def generate_yang_submodel_gi(self, vnfd):
+ if vnfd is None:
+ return None
+ try:
+ props = convert_keys_to_python(self.properties)
+ vnfd.placement_groups.add().from_dict(props)
+ except Exception as e:
+ err_msg = _("{0} Exception policy from dict {1}: {2}"). \
+ format(self, props, e)
+ self.log.error(err_msg)
+ raise e
+
+ def get_policy_props(self):
+ tosca_props = {}
+
+ for prop in self.policy.get_properties_objects():
+ if isinstance(prop.value, GetInput):
+ tosca_props[prop.name] = {'get_param': prop.value.input_name}
+ else:
+ tosca_props[prop.name] = prop.value
+ return tosca_props
from rift.mano.tosca_translator.common.utils import _
from rift.mano.tosca_translator.common.utils import convert_keys_to_python
from rift.mano.tosca_translator.rwmano.syntax.mano_resource import ManoResource
+from toscaparser.functions import GetInput
from toscaparser.common.exception import ValidationError
class ToscaScalingGroup(ManoResource):
'''Translate TOSCA node type tosca.policies.Scaling.'''
- toscatype = 'tosca.policies.riftio.ScalingGroup'
+ toscatype = 'tosca.groups.nfv.riftio.scaling'
IGNORE_PROPS = []
- def __init__(self, log, policy, metadata=None):
+ def __init__(self, log, group, metadata=None):
# TODO(Philip):Not inheriting for ManoResource, as there is no
# instance from parser
self.log = log
- for name, details in policy.items():
- self.name = name
- self.details = details
- break
+ self.name = group.name
+ #self.details = details
+ self.group = group
self.type_ = 'scale-grp'
self.metadata = metadata
self.properties = {}
def __str__(self):
return "%s(%s)" % (self.name, self.type)
+ def get_tosca_group_props(self):
+ tosca_props = {}
+ for prop in self.group.get_properties_objects():
+ if isinstance(prop.value, GetInput):
+ tosca_props[prop.name] = {'get_param': prop.value.input_name}
+ else:
+ tosca_props[prop.name] = prop.value
+ return tosca_props
def handle_properties(self, nodes, groups):
- tosca_props = self.details
+ tosca_props = self.get_tosca_group_props()
self.log.debug(_("{0} with tosca properties: {1}").
format(self, tosca_props))
- self.properties['name'] = tosca_props['name']
- self.properties['max-instance-count'] = \
- tosca_props['max_instance_count']
- self.properties['min-instance-count'] = \
- tosca_props['min_instance_count']
+ if 'name ' in tosca_props:
+ self.properties['name'] = tosca_props['name']
+ if 'max_instance_count' in tosca_props:
+ self.properties['max-instance-count'] = tosca_props['max_instance_count']
+ if 'min_instance_count' in tosca_props:
+ self.properties['min-instance-count'] = tosca_props['min_instance_count']
self.properties['vnfd-member'] = []
def _get_node(name):
for node in nodes:
if node.name == name:
return node
-
- for member, count in tosca_props['vnfd_members'].items():
- node = _get_node(member)
- if node:
- memb = {}
- memb['member-vnf-index-ref'] = node.get_member_vnf_index()
- memb['count'] = count
- self.properties['vnfd-member'].append(memb)
- else:
- err_msg = _("{0}: Did not find the member node {1} in "
- "resources list"). \
- format(self, member)
- self.log.error(err_msg)
- raise ValidationError(message=err_msg)
+ if 'vnfd_members' in tosca_props:
+ for member, count in tosca_props['vnfd_members'].items():
+ node = _get_node(member)
+ if node:
+ memb = {}
+ memb['member-vnf-index-ref'] = node.get_member_vnf_index()
+ memb['count'] = count
+ self.properties['vnfd-member'].append(memb)
+ else:
+ err_msg = _("{0}: Did not find the member node {1} in "
+ "resources list"). \
+ format(self, member)
+ self.log.error(err_msg)
+ raise ValidationError(message=err_msg)
def _validate_action(action):
for group in groups:
return False
self.properties['scaling-config-action'] = []
- for action, value in tosca_props['config_actions'].items():
- conf = {}
- if _validate_action(value):
- conf['trigger'] = action
- conf['ns-config-primitive-name-ref'] = value
- self.properties['scaling-config-action'].append(conf)
- else:
- err_msg = _("{0}: Did not find the action {1} in "
- "config primitives"). \
- format(self, action)
- self.log.error(err_msg)
- raise ValidationError(message=err_msg)
+ if 'config_actions' in tosca_props:
+ for action, value in tosca_props['config_actions'].items():
+ conf = {}
+ if _validate_action(value):
+ conf['trigger'] = action
+ conf['ns-config-primitive-name-ref'] = value
+ self.properties['scaling-config-action'].append(conf)
+ else:
+ err_msg = _("{0}: Did not find the action {1} in "
+ "config primitives"). \
+ format(self, action)
+ self.log.error(err_msg)
+ raise ValidationError(message=err_msg)
self.log.debug(_("{0} properties: {1}").format(self, self.properties))
def get_yang_model_gi(self, nsd, vnfds):
props = convert_keys_to_python(self.properties)
try:
- nsd.scaling_group_descriptor.add().from_dict(props)
+ if len(self.properties['vnfd-member']) > 0:
+ nsd.scaling_group_descriptor.add().from_dict(props)
except Exception as e:
err_msg = _("{0} Exception nsd scaling group from dict {1}: {2}"). \
format(self, props, e)
--- /dev/null
+#
+# Copyright 2016 RIFT.io Inc
+#
+# 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 rift.mano.tosca_translator.common.utils import _
+from rift.mano.tosca_translator.common.utils import convert_keys_to_python
+from rift.mano.tosca_translator.rwmano.syntax.mano_resource import ManoResource
+from toscaparser.functions import GetInput
+from rift.mano.tosca_translator.common.utils import convert_keys_to_python
+
+from toscaparser.common.exception import ValidationError
+
+
+# Name used to dynamically load appropriate map class.
+TARGET_CLASS_NAME = 'ToscaVnfConfiguration'
+
+
+class ToscaVnfConfiguration(ManoResource):
+ '''Translate TOSCA node type tosca.policies.Scaling.'''
+
+ toscatype = 'tosca.policies.nfv.riftio.vnf_configuration'
+
+ IGNORE_PROPS = []
+
+ def __init__(self, log, policy, metadata=None, vnf_name = None):
+ self.log = log
+ self.name = policy.name
+ self.type_ = 'place-grp'
+ self.metadata = metadata
+ self.policy = policy
+ self.properties = {}
+ self.linked_to_vnf = True
+ self._vnf_name = vnf_name
+
+ def __str__(self):
+ return "%s(%s)" % (self.name, self.type)
+
+ def handle_properties(self, nodes, groups):
+ tosca_props = self.get_policy_props()
+ self.properties["vnf-configuration"] = {}
+ prop = {}
+ prop["config-attributes"] = {}
+ prop["script"] = {}
+ if 'config' in tosca_props:
+ if 'config_delay' in tosca_props['config']:
+ prop["config-attributes"]['config-delay'] = tosca_props['config']['config_delay']
+ if 'config_priority' in tosca_props['config']:
+ prop["config-attributes"]['config-priority'] = tosca_props['config']['config_priority']
+ if 'config_template' in tosca_props['config']:
+ prop["config-template"] = tosca_props['config']['config_template']
+ if 'config_details' in tosca_props['config']:
+ if 'script_type' in tosca_props['config']['config_details']:
+ prop["script"]["script-type"] = tosca_props['config']['config_details']['script_type']
+ self.properties = prop
+
+ def generate_yang_submodel_gi(self, vnfd):
+ if vnfd is None:
+ return None
+ try:
+ props = convert_keys_to_python(self.properties)
+ vnfd.vnf_configuration.from_dict(props)
+ except Exception as e:
+ err_msg = _("{0} Exception vdu from dict {1}: {2}"). \
+ format(self, props, e)
+ self.log.error(err_msg)
+ raise e
+
+ def get_policy_props(self):
+ tosca_props = {}
+
+ for prop in self.policy.get_properties_objects():
+ if isinstance(prop.value, GetInput):
+ tosca_props[prop.name] = {'get_param': prop.value.input_name}
+ else:
+ tosca_props[prop.name] = prop.value
+ return tosca_props
\ No newline at end of file
for key in FIELDS_MAP:
if key in tosca_meta.keys():
metadata[FIELDS_MAP[key]] = str(tosca_meta[key])
+ if 'logo' in tosca_meta:
+ metadata['logo'] = os.path.basename(tosca_meta['logo'])
self.log.debug(_("Metadata {0}").format(metadata))
self.metadata = metadata
self.log.debug(_('Translating the node templates.'))
# Copy the TOSCA graph: nodetemplate
+ all_node_templates = []
+ node_to_artifact_map = {}
+ vnf_type_to_vnf_node = {}
+ vnf_type_to_vdus_map = {}
+ vnf_type_substitution_mapping = {}
+ vnf_type_to_capability_substitution_mapping = {}
tpl = self.tosca.tpl['topology_template']['node_templates']
+
for node in self.nodetemplates:
+ all_node_templates.append(node)
+ if node.parent_type.type == 'tosca.nodes.nfv.riftio.VNF1':
+ vnf_type_to_vnf_node[node.type] = node.name
+ for node_key in tpl:
+ if 'artifacts' in tpl[node_key]:
+ node_to_artifact_map[node_key] = tpl[node_key]['artifacts']
+ for template in self.tosca.nested_tosca_templates_with_topology:
+ tpl_node = template.tpl['node_templates']
+ vnf_type = template.substitution_mappings.node_type
+
+ vnf_type_to_vdus_map[vnf_type] = []
+ vnf_type_substitution_mapping[vnf_type] = []
+ vnf_type_to_capability_substitution_mapping[vnf_type] = []
+ vnf_type_to_capability_substitution_mapping[vnf_type] = []
+ policies = []
+ for node in template.nodetemplates:
+ all_node_templates.append(node)
+ for node_key in tpl_node:
+ if 'artifacts' in tpl_node[node_key]:
+ node_to_artifact_map[node_key] = tpl_node[node_key]['artifacts']
+ for node in template.nodetemplates:
+ if 'VDU' in node.type:
+ vnf_type_to_vdus_map[vnf_type].append(node.name)
+ for policy in template.policies:
+ policies.append(policy.name)
+ for req in template.substitution_mappings.requirements:
+ vnf_type_substitution_mapping[template.substitution_mappings.node_type].append(req)
+ for capability in template.substitution_mappings.capabilities:
+ sub_list = template.substitution_mappings.capabilities[capability]
+ if len(sub_list) > 0:
+ vnf_type_to_capability_substitution_mapping[vnf_type].append({capability: sub_list[0]})
+
+ for node in all_node_templates:
base_type = ManoResource.get_base_type(node.type_definition)
self.log.debug(_("Translate node %(name)s of type %(type)s with "
"base %(base)s") %
metadata=self.metadata)
# Currently tosca-parser does not add the artifacts
# to the node
- if mano_node.name in tpl:
- tpl_node = tpl[mano_node.name]
- self.log.debug("Check artifacts for {}".format(tpl_node))
- if 'artifacts' in tpl_node:
- mano_node.artifacts = tpl_node['artifacts']
+ if mano_node.name in node_to_artifact_map:
+ mano_node.artifacts = node_to_artifact_map[mano_node.name]
self.mano_resources.append(mano_node)
self.mano_lookup[node] = mano_node
# The parser currently do not generate the objects for groups
- if 'groups' in self.tosca.tpl['topology_template']:
- tpl = self.tosca.tpl['topology_template']['groups']
- self.log.debug("Groups: {}".format(tpl))
- for group, details in tpl.items():
- self.log.debug(_("Translate group {}: {}").
- format(group, details))
- group_type = details['type']
- if group_type:
- group_node = TranslateNodeTemplates. \
- TOSCA_TO_MANO_TYPE[group_type](
- self.log,
- group,
- details,
- metadata=self.metadata)
- self.mano_groups.append(group_node)
+ for group in self.tosca.topology_template.groups:
+ group_type = group.type
+ if group_type:
+ group_node = TranslateNodeTemplates. \
+ TOSCA_TO_MANO_TYPE[group_type](
+ self.log,
+ group,
+ metadata=self.metadata)
+ self.mano_groups.append(group_node)
# The parser currently do not generate the objects for policies
- if 'policies' in self.tosca.tpl['topology_template']:
- tpl = self.tosca.tpl['topology_template']['policies']
- # for policy in self.policies:
- for policy in tpl:
- self.log.debug(_("Translate policy {}").
- format(policy))
- policy_type = self._get_policy_type(policy)
- if policy_type:
- policy_node = TranslateNodeTemplates. \
- TOSCA_TO_MANO_TYPE[policy_type](
- self.log,
- policy,
- metadata=self.metadata)
- self.mano_policies.append(policy_node)
+
+ for policy in self.tosca.topology_template.policies:
+ policy_type = policy.type
+ if policy_type:
+ policy_node = TranslateNodeTemplates. \
+ TOSCA_TO_MANO_TYPE[policy_type](
+ self.log,
+ policy,
+ metadata=self.metadata)
+ self.mano_policies.append(policy_node)
+ for template in self.tosca.nested_tosca_templates_with_topology:
+ vnf_type = template.substitution_mappings.node_type
+ if vnf_type in vnf_type_to_vnf_node:
+ vnf_node = vnf_type_to_vnf_node[vnf_type]
+
+ for policy in template.policies:
+ policy_type = policy.type
+ if policy_type:
+ policy_node = TranslateNodeTemplates. \
+ TOSCA_TO_MANO_TYPE[policy_type](
+ self.log,
+ policy,
+ metadata=self.metadata,
+ vnf_name=vnf_node)
+ self.mano_policies.append(policy_node)
for node in self.mano_resources:
self.log.debug(_("Handle properties for {0} of type {1}").
self.log.debug(_("Handle requirements for {0} of "
"type {1}").
format(node.name, node.type_))
- node.handle_requirements(self.mano_resources)
+ node.handle_requirements(self.mano_resources, self.mano_policies, vnf_type_to_vdus_map)
+
except Exception as e:
self.log.error(_("Exception for {0} in requirements {1}").
format(node.name, node.type_))
format(node.name, node.type_))
self.log.exception(e)
+ for node in self.mano_resources:
+ if node.type == "vld":
+ node.handle_vld_properties(self.mano_resources, vnf_type_substitution_mapping)
+ elif node.type == 'forwarding_path':
+ node.handle_forwarding_path_dependencies(self.mano_resources, vnf_type_to_capability_substitution_mapping)
+
return self.mano_resources
def translate_groups(self):
for group in self.mano_groups:
- group.handle_properties(self.mano_resources)
+ group.handle_properties(self.mano_resources, self.mano_groups)
return self.mano_groups
def translate_policies(self):
http_ep = {'protocol': 'http'} # Required for TOSCA
http_ep[self.PATH] = ep.pop(self.PATH)
http_ep[self.PORT] = ep.pop(self.PORT)
- http_ep[self.POLL_INTVL] = ep.pop(self.POLL_INTVL_SECS)
+ if self.POLL_INTVL in http_ep:
+ http_ep[self.POLL_INTVL] = ep.pop(self.POLL_INTVL_SECS)
if len(ep):
self.log.warn(_("{0}, Did not process the following for "
"http ep {1}").format(self, ep))
type string;
}
- leaf polling_interval_secs {
+ leaf polling-interval-secs {
description "The HTTP polling interval in seconds";
type uint8;
default 2;