1 # Copyright 2016 RIFT.io Inc
3 # Licensed under the Apache License, Version 2.0 (the "License");
4 # you may not use this file except in compliance with the License.
5 # You may obtain a copy of the License at
7 # http://www.apache.org/licenses/LICENSE-2.0
9 # Unless required by applicable law or agreed to in writing, software
10 # distributed under the License is distributed on an "AS IS" BASIS,
11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 # See the License for the specific language governing permissions and
13 # limitations under the License.
16 from copy
import deepcopy
19 from rift
.mano
.yang_translator
.common
.exception
import ValidationError
20 from rift
.mano
.yang_translator
.common
.utils
import _
21 from rift
.mano
.yang_translator
.rwmano
.syntax
.tosca_resource \
23 from rift
.mano
.yang_translator
.rwmano
.yang
.yang_vld
import YangVld
24 from collections
import OrderedDict
26 TARGET_CLASS_NAME
= 'YangNsd'
29 class YangNsd(ToscaResource
):
30 '''Class for RIFT.io YANG NS descriptor translation to TOSCA type.'''
34 OTHER_FIELDS
= (SCALE_GRP
, CONF_PRIM
,
35 USER_DEF_SCRIPT
, SCALE_ACT
,
36 TRIGGER
, NS_CONF_PRIM_REF
,
37 CONST_VNFD
, VNFD_MEMBERS
,
38 MIN_INST_COUNT
, MAX_INST_COUNT
,
39 INPUT_PARAM_XPATH
, CONFIG_ACTIONS
,
41 ('scaling_group_descriptor', 'service_primitive',
42 'user_defined_script', 'scaling_config_action',
43 'trigger', 'ns_config_primitive_name_ref',
44 'constituent_vnfd', 'vnfd_member',
45 'min_instance_count', 'max_instance_count',
46 'input_parameter_xpath', 'config_actions',
47 'initial_config_primitive',)
55 super(YangNsd
, self
).__init
__(log
,
66 self
.placement_groups
= []
67 self
.vnf_id_to_vnf_map
= {}
68 self
.vnfd_files
= vnfd_files
69 self
.vld_to_vnf_map
= {}
70 self
.vnf_to_vld_map
= {}
71 self
._vnf
_vld
_conn
_point
_map
= {}
73 self
.forwarding_paths
= {}
74 self
.substitution_mapping_forwarder
= []
75 self
.vnfd_sfc_map
= None
77 def handle_yang(self
, vnfds
):
78 self
.log
.debug(_("Process NSD desc {0}: {1}").
79 format(self
.name
, self
.yang
))
81 def process_input_param(param
):
82 if self
.XPATH
in param
:
83 val
= param
.pop(self
.XPATH
)
84 # Strip namesapce, catalog and nsd part
87 self
.map_yang_name_to_tosca(
88 val
.replace('/rw-project:project/project-nsd:nsd-catalog/project-nsd:nsd/nsd:', ''))})
90 self
.log
.warn(_("{0}, Did not process the following for "
91 "input param {1}: {2}").
92 format(self
, self
.inputs
, param
))
93 self
.log
.debug(_("{0}, inputs: {1}").format(self
, self
.inputs
[-1]))
95 def process_const_vnfd(cvnfd
):
96 # Get the matching VNFD
97 vnfd_id
= cvnfd
.pop(self
.VNFD_ID_REF
)
99 if vnfd
.type == self
.VNFD
and vnfd
.id == vnfd_id
:
100 self
.vnf_id_to_vnf_map
[vnfd_id
] = vnfd
.name
101 self
.vnfds
[cvnfd
.pop(self
.MEM_VNF_INDEX
)] = vnfd
102 if self
.START_BY_DFLT
in cvnfd
:
103 vnfd
.props
[self
.START_BY_DFLT
] = \
104 cvnfd
.pop(self
.START_BY_DFLT
)
108 self
.log
.warn(_("{0}, Did not process the following for "
109 "constituent vnfd {1}: {2}").
110 format(self
, vnfd_id
, cvnfd
))
111 self
.log
.debug(_("{0}, VNFD: {1}").format(self
, self
.vnfds
))
113 def process_scale_grp(dic
):
115 self
.log
.debug(_("{0}, scale group: {1}").format(self
, dic
))
116 fields
= [self
.NAME
, self
.MIN_INST_COUNT
, self
.MAX_INST_COUNT
]
119 sg
[key
] = dic
.pop(key
)
122 for vnfd_memb
in dic
.pop(self
.VNFD_MEMBERS
):
123 vnfd_idx
= vnfd_memb
[self
.MEM_VNF_INDEX_REF
]
124 if vnfd_idx
in self
.vnfds
:
125 membs
[self
.vnfds
[vnfd_idx
].name
] = \
126 vnfd_memb
[self
.COUNT
]
127 sg
['vnfd_members'] = membs
130 if self
.SCALE_ACT
in dic
:
131 for sg_act
in dic
.pop(self
.SCALE_ACT
):
132 # Validate the primitive
133 prim
= sg_act
.pop(self
.NS_CONF_PRIM_REF
)
134 for cprim
in self
.conf_prims
:
135 if cprim
[self
.NAME
] == prim
:
136 trigs
[sg_act
.pop(self
.TRIGGER
)] = prim
139 err_msg
= (_("{0}, Did not find config-primitive {1}").
141 self
.log
.error(err_msg
)
142 raise ValidationError(message
=err_msg
)
143 sg
[self
.CONFIG_ACTIONS
] = trigs
146 self
.log
.warn(_("{0}, Did not process all fields for {1}").
148 self
.log
.debug(_("{0}, Scale group {1}").format(self
, sg
))
149 self
.scale_grps
.append(sg
)
151 def process_initial_config(dic
):
153 self
.log
.debug(_("{0}, initial config: {1}").format(self
, dic
))
154 for key
in [self
.NAME
, self
.SEQ
, self
.USER_DEF_SCRIPT
]:
156 icp
[key
] = dic
.pop(key
)
159 if self
.PARAM
in dic
:
160 for p
in dic
.pop(self
.PARAM
):
161 if (self
.NAME
in p
and
163 params
[p
[self
.NAME
]] = p
[self
.VALUE
]
165 # TODO (pjoseph): Need to add support to read the
166 # config file and get the value from that
167 self
.log
.warn(_("{0}, Got parameter without value: {1}").
170 icp
[self
.PARAM
] = params
173 self
.log
.warn(_("{0}, Did not process all fields for {1}").
175 self
.log
.debug(_("{0}, Initial config {1}").format(self
, icp
))
176 self
.initial_cfg
.append({self
.PROPERTIES
: icp
})
178 def process_vld(vld
, dic
):
181 ip_profile_vld
= None
183 if 'ip_profile_ref' in vld
:
184 ip_profile_name
= vld
['ip_profile_ref']
185 if 'ip_profiles' in dic
:
186 for ip_prof
in dic
['ip_profiles']:
187 if ip_profile_name
== ip_prof
['name']:
188 ip_profile_vld
= ip_prof
190 vld_name
= vld
['name'].replace('-','_').replace(' ','')
191 if 'description' in vld
:
192 vld_conf
['description'] = vld
['description']
194 vld_conf
['vendor'] = vld
['vendor']
196 if 'ip_profile_params' in ip_profile_vld
:
197 ip_param
= ip_profile_vld
['ip_profile_params']
198 if 'gateway_address' in ip_param
:
199 vld_conf
['gateway_ip'] = ip_param
['gateway_address']
200 if 'subnet_address' in ip_param
:
201 vld_conf
['cidr'] = ip_param
['subnet_address']
202 if 'ip_version' in ip_param
:
203 vld_conf
['ip_version'] = ip_param
['ip_version'].replace('ipv','')
206 vld_prop
= {vld_name
:
209 self
.PROPERTIES
: vld_conf
211 self
.vlds
[vld_name
] = { 'type': self
.T_ELAN
,
212 self
.PROPERTIES
: vld_conf
215 self
.vld_to_vnf_map
[vld_name
] = []
216 if 'vnfd_connection_point_ref' in vld
:
217 for vnfd_ref
in vld
['vnfd_connection_point_ref']:
218 vnf_name
= self
.vnf_id_to_vnf_map
[vnfd_ref
['vnfd_id_ref']]
219 if vnf_name
in self
.vnf_to_vld_map
:
220 self
.vnf_to_vld_map
[vnf_name
].append(vld_name
)
221 self
._vnf
_vld
_conn
_point
_map
[vnf_name
].\
222 append((vld_name
,vnfd_ref
['vnfd_connection_point_ref']))
224 self
.vnf_to_vld_map
[vnf_name
] = []
225 self
._vnf
_vld
_conn
_point
_map
[vnf_name
] = []
226 self
.vnf_to_vld_map
[vnf_name
].append(vld_name
)
227 self
._vnf
_vld
_conn
_point
_map
[vnf_name
].\
228 append((vld_name
,vnfd_ref
['vnfd_connection_point_ref']))
230 def process_placement_group(placement_groups
):
231 for i
in range(0, len(placement_groups
)):
232 placement_group
= placement_groups
[i
]
233 pg_name
= "placement_{0}".format(i
)
236 if 'name' in placement_group
:
237 pg_config
['name'] = placement_group
['name']
238 if 'requirement' in placement_group
:
239 pg_config
['requirement'] = placement_group
['requirement']
240 if 'strategy' in placement_group
:
241 pg_config
['strategy'] = placement_group
['strategy']
242 if 'member_vnfd' in placement_group
:
243 for member_vnfd
in placement_group
['member_vnfd']:
244 targets
.append(self
.vnf_id_to_vnf_map
[member_vnfd
['vnfd_id_ref']])
245 placement
= { pg_name
: {
246 'type': self
.T_PLACEMENT
,
247 self
.PROPERTIES
: pg_config
,
248 self
.TARGETS
: str(targets
)
251 self
.placement_groups
.append(placement
)
253 def process_vnffgd(vnffgs
, dic
):
254 associated_cp_names
= []
258 conn_point_to_conection_node
= {}
259 conn_point_to_vnf_name_map
= {}
261 unigue_id_forwarder_path_map
= OrderedDict()
262 forwarder_name_to_constitent_vnf_map
= OrderedDict()
263 unique_id_classifier_map
= OrderedDict()
267 vnffg_to_unique_id_rsp_map
= OrderedDict()
268 vnffg_to_unique_id_classifier_map
= OrderedDict()
269 vnffg_to_associated_cp_names
= OrderedDict()
270 rsp_associated_cp_names
= OrderedDict()
271 vnffg_to_forwarder_map
= OrderedDict()
273 unique_id_rsp_map
= {}
274 for rs
in vnffg
['rsp']:
275 unique_id_rsp_map
[str(rs
['id'])] = rs
276 for class_identifier
in vnffg
['classifier']:
277 unique_id_classifier_map
[str(class_identifier
['rsp_id_ref'])] = class_identifier
278 associated_cp_names
.append(class_identifier
['vnfd_connection_point_ref'])
279 all_cp_names
.append(class_identifier
['vnfd_connection_point_ref'])
280 conn_point_to_vnf_name_map
[class_identifier
['vnfd_connection_point_ref']] = self
.vnf_id_to_vnf_map
[class_identifier
['vnfd_id_ref']]
281 vnfd_sfc_map
[self
.vnf_id_to_vnf_map
[class_identifier
['vnfd_id_ref']]] = class_identifier
['vnfd_connection_point_ref']
283 rsp_associated_cp_names
[str(class_identifier
['rsp_id_ref'])] = class_identifier
['vnfd_connection_point_ref']
285 vnffg_to_unique_id_rsp_map
[vnffg
['name']] = unique_id_rsp_map
286 vnffg_to_forwarder_map
[vnffg
['name']] = []
293 prop
['type'] = self
.T_VNFFG
294 prop
[self
.DESC
] = "Test"
295 prop
[self
.PROPERTIES
] = {}
296 if 'vendor' in vnffg
:
297 prop
[self
.PROPERTIES
]['vendor'] = vnffg
['vendor']
299 self
.vnffgds
[vnffg
['name']] = prop
301 for rs_id
, rs
in vnffg_to_unique_id_rsp_map
[vnffg
['name']].items():
302 associated_cp_node_names
= []
303 associated_vnf_names
= []
304 number_of_endpoints
= 0
305 if 'vnfd_connection_point_ref' in rs
:
306 number_of_endpoints
= number_of_endpoints
+ len(rs
['vnfd_connection_point_ref'])
307 for vnf
in rs
['vnfd_connection_point_ref']:
308 associated_vnf_names
.append(str(self
.vnf_id_to_vnf_map
[vnf
['vnfd_id_ref']]))
309 associated_cp_names
.append(vnf
['vnfd_connection_point_ref'])
310 all_cp_names
.append(vnf
['vnfd_connection_point_ref'])
311 conn_point_to_vnf_name_map
[vnf
['vnfd_connection_point_ref']] = self
.vnf_id_to_vnf_map
[vnf
['vnfd_id_ref']]
312 if "forwarder{}".format(fp_path_count
) not in forwarder_name_to_constitent_vnf_map
:
313 forwarder_name_to_constitent_vnf_map
["forwarder{}".format(fp_path_count
)] = associated_vnf_names
314 vnffg_to_forwarder_map
[vnffg
['name']].append("forwarder{}".format(fp_path_count
))
315 fp_path_count
= fp_path_count
+ 1
317 associated_cp_names
= list(set(associated_cp_names
))
318 for cp_name
in associated_cp_names
:
319 for idx
, vnfd
in self
.vnfds
.items():
320 for vdu
in vnfd
.vdus
:
321 if cp_name
== rsp_associated_cp_names
[rs_id
]:
322 if cp_name
in vdu
.conn_point_to_conection_node
:
323 associated_cp_node_names
.append(vdu
.conn_point_to_conection_node
[cp_name
])
324 #conn_point_to_conection_node[cp_name] = vdu.conn_point_to_conection_node[cp_name]
326 for cp_name
in all_cp_names
:
327 for idx
, vnfd
in self
.vnfds
.items():
328 for vdu
in vnfd
.vdus
:
329 if cp_name
in vdu
.conn_point_to_conection_node
:
330 conn_point_to_conection_node
[cp_name
] = vdu
.conn_point_to_conection_node
[cp_name
]
332 if len(associated_vnf_names
) > 0:
333 associated_vnf_names
= list(set(associated_vnf_names
))
334 vnf_str
= ", ".join(associated_vnf_names
)
335 prop
[self
.PROPERTIES
]['constituent_vnfs'] = "[{}]".format(vnf_str
)
336 if len(associated_cp_node_names
) > 0:
337 associated_cp_node_names
= list(set(associated_cp_node_names
))
338 connection_point_str
= ", ".join(associated_cp_node_names
)
339 prop
[self
.PROPERTIES
]['connection_point'] = "[{}]".format(", ".join(associated_cp_node_names
))
341 prop
[self
.PROPERTIES
]['number_of_endpoints'] = number_of_endpoints
342 fp_name
= "Forwarding_path{}".format(forwarder_count
)
343 unigue_id_forwarder_path_map
[fp_name
] = rs_id
344 fp_members
.append(fp_name
)
345 forwarder_count
= forwarder_count
+ 1
347 if len(fp_members
) > 0:
349 for fp
in fp_members
:
350 prop
['members'].append(fp
)
353 for fp
, idx
in unigue_id_forwarder_path_map
.items():
354 for vnffg_name
, unique_id_rsp_map
in vnffg_to_unique_id_rsp_map
.items():
355 if idx
in unique_id_rsp_map
:
357 prop
['type'] = self
.T_FP
358 prop
[self
.PROPERTIES
] = {}
359 prop
[self
.PROPERTIES
][self
.DESC
] = "Forwarder"
360 prop
[self
.PROPERTIES
]['policy'] = {}
361 prop
[self
.PROPERTIES
]['policy']['type'] = 'ACL'
362 prop
[self
.PROPERTIES
]['policy']['criteria'] = []
364 prop
[self
.PROPERTIES
]['path'] = []
366 rsp
= unique_id_rsp_map
[idx
]
367 classifier
= unique_id_classifier_map
[idx
]
369 for match
in classifier
['match_attributes']:
371 if 'source_port' in match
:
372 port
= "'{}'".format((match
['source_port']))
373 prop
[self
.PROPERTIES
]['policy']['criteria'].append({'source_port_range': port
})
374 if 'destination_port' in match
:
375 port
= "'f'{}''".format((match
['destination_port']))
376 prop
[self
.PROPERTIES
]['policy']['criteria'].append({'destination_port_range': '5006'})
377 if 'ip_proto' in match
:
378 port
= match
['ip_proto']
379 prop
[self
.PROPERTIES
]['policy']['criteria'].append({'ip_proto': port
})
380 if 'destination_ip_address' in match
:
381 port
= "'{}'".format((match
['destination_ip_address']))
382 prop
[self
.PROPERTIES
]['policy']['criteria'].append({'ip_dst_prefix': port
})
384 if 'vnfd_connection_point_ref' in classifier
:
385 if classifier
['vnfd_connection_point_ref'] in conn_point_to_vnf_name_map
:
386 if 'cp' not in prop
[self
.PROPERTIES
]:
387 prop
[self
.PROPERTIES
]['cp'] = {}
388 prop
[self
.PROPERTIES
]['cp']['forwarder'] = conn_point_to_vnf_name_map
[classifier
['vnfd_connection_point_ref']]
389 prop
[self
.PROPERTIES
]['cp']['capability'] = conn_point_to_conection_node
[classifier
['vnfd_connection_point_ref']]
391 for fp
, vnf_list
in forwarder_name_to_constitent_vnf_map
.items():
393 for cp
, vnf_name
in conn_point_to_vnf_name_map
.items():
395 self
.substitution_mapping_forwarder
.append((vnf
, fp
, conn_point_to_conection_node
[cp
]))
397 visited_forwarder
= []
399 for path
, vnfs
in forwarder_name_to_constitent_vnf_map
.items():
401 if (vnf
not in visited_forwarder
) and (path
in vnffg_to_forwarder_map
[vnffg_name
]):
403 path_prop
['forwarder'] = vnf
404 path_prop
['capability'] = path
405 prop
[self
.PROPERTIES
]['path'].append(path_prop
)
406 visited_forwarder
.append(vnf
)
408 forwarder_name_to_constitent_vnf_map
.pop(visited_path
)
410 self
.forwarding_paths
["Forwarding_path{}".format(fp_count
)] = prop
411 fp_count
= fp_count
+1
413 self
.vnfd_sfc_map
= vnfd_sfc_map
415 dic
= deepcopy(self
.yang
)
417 for key
in self
.REQUIRED_FIELDS
:
418 self
.props
[key
] = dic
.pop(key
)
420 self
.id = self
.props
[self
.ID
]
422 # Process constituent VNFDs
423 if self
.CONST_VNFD
in dic
:
424 for cvnfd
in dic
.pop(self
.CONST_VNFD
):
425 process_const_vnfd(cvnfd
)
429 for vld_dic
in dic
.pop(self
.VLD
):
430 process_vld(vld_dic
, dic
)
431 #self.vlds.append(vld)
434 if self
.VNFFGD
in dic
:
435 process_vnffgd(dic
[self
.VNFFGD
], dic
)
440 # Process config primitives
441 if self
.CONF_PRIM
in dic
:
442 for cprim
in dic
.pop(self
.CONF_PRIM
):
443 conf_prim
= {self
.NAME
: cprim
.pop(self
.NAME
), self
.DESC
: 'TestDescription'}
444 if self
.USER_DEF_SCRIPT
in cprim
:
445 conf_prim
[self
.USER_DEF_SCRIPT
] = \
446 cprim
.pop(self
.USER_DEF_SCRIPT
)
447 self
.conf_prims
.append(conf_prim
)
449 err_msg
= (_("{0}, Only user defined script supported "
450 "in config-primitive for now {}: {}").
451 format(self
, conf_prim
, cprim
))
452 self
.log
.error(err_msg
)
453 raise ValidationError(message
=err_msg
)
455 # Process scaling group
456 if self
.SCALE_GRP
in dic
:
457 for sg_dic
in dic
.pop(self
.SCALE_GRP
):
458 process_scale_grp(sg_dic
)
460 # Process initial config primitives
461 if self
.INITIAL_CFG
in dic
:
462 for icp_dic
in dic
.pop(self
.INITIAL_CFG
):
463 process_initial_config(icp_dic
)
465 # Process the input params
466 if self
.INPUT_PARAM_XPATH
in dic
:
467 for param
in dic
.pop(self
.INPUT_PARAM_XPATH
):
468 process_input_param(param
)
470 if 'placement_groups' in dic
:
471 process_placement_group(dic
['placement_groups'])
474 self
.remove_ignored_fields(dic
)
476 self
.log
.warn(_("{0}, Did not process the following for "
478 format(self
, self
.props
, dic
))
479 self
.log
.debug(_("{0}, NSD: {1}").format(self
, self
.props
))
480 except Exception as e
:
481 err_msg
= _("Exception processing NSD {0} : {1}"). \
483 self
.log
.error(err_msg
)
484 self
.log
.exception(e
)
485 raise ValidationError(message
=err_msg
)
487 def generate_tosca_type(self
):
489 self
.log
.debug(_("{0} Generate tosa types").
493 #tosca[self.DATA_TYPES] = {}
494 #tosca[self.NODE_TYPES] = {}
496 for idx
, vnfd
in self
.vnfds
.items():
497 tosca
= vnfd
.generate_tosca_type(tosca
)
499 for vld
in self
.vlds
:
500 tosca
= vld
.generate_tosca_type(tosca
)
502 # Generate type for config primitives
503 if self
.GROUP_TYPES
not in tosca
:
504 tosca
[self
.GROUP_TYPES
] = {}
505 if self
.T_CONF_PRIM
not in tosca
[self
.GROUP_TYPES
]:
506 tosca
[self
.GROUP_TYPES
][self
.T_CONF_PRIM
] = {
507 self
.DERIVED_FROM
: 'tosca.policies.Root',
509 'primitive': self
.MAP
512 # Generate type for scaling group
513 if self
.POLICY_TYPES
not in tosca
:
514 tosca
[self
.POLICY_TYPES
] = {}
515 if self
.T_SCALE_GRP
not in tosca
[self
.POLICY_TYPES
]:
516 tosca
[self
.POLICY_TYPES
][self
.T_SCALE_GRP
] = {
517 self
.DERIVED_FROM
: 'tosca.policies.Root',
520 {self
.TYPE
: self
.STRING
},
522 {self
.TYPE
: self
.INTEGER
},
524 {self
.TYPE
: self
.INTEGER
},
526 {self
.TYPE
: self
.MAP
},
528 {self
.TYPE
: self
.MAP
}
531 if self
.T_INITIAL_CFG
not in tosca
[self
.POLICY_TYPES
]:
532 tosca
[self
.POLICY_TYPES
][self
.T_INITIAL_CFG
] = {
533 self
.DERIVED_FROM
: 'tosca.policies.Root',
536 {self
.TYPE
: self
.STRING
},
538 {self
.TYPE
: self
.INTEGER
},
539 self
.USER_DEF_SCRIPT
:
540 {self
.TYPE
: self
.STRING
},
542 {self
.TYPE
: self
.MAP
},
547 def generate_tosca_template(self
, tosca
):
548 self
.log
.debug(_("{0}, Generate tosca template").
550 # Add the standard entries
551 tosca
['tosca_definitions_version'] = \
552 'tosca_simple_profile_for_nfv_1_0'
553 tosca
[self
.DESC
] = self
.props
[self
.DESC
]
554 tosca
[self
.METADATA
] = {
556 self
.VENDOR
: self
.props
[self
.VENDOR
],
557 self
.VERSION
: self
.props
[self
.VERSION
],
559 if len(self
.vnfd_files
) > 0:
560 tosca
[self
.IMPORT
] = []
562 for vnfd_file
in self
.vnfd_files
:
563 tosca
[self
.IMPORT
].append('"{0}.yaml"'.format(vnfd_file
))
565 tosca
[self
.TOPOLOGY_TMPL
] = {}
570 if self.INPUTS not in tosca[self.TOPOLOGY_TMPL]:
571 tosca[self.TOPOLOGY_TMPL][self.INPUTS] = {}
572 for inp in self.inputs:
573 entry = {inp[self.NAME]: {self.TYPE: self.STRING,
575 'Translated from YANG'}}
576 tosca[self.TOPOLOGY_TMPL][self.INPUTS] = entry
578 tosca
[self
.TOPOLOGY_TMPL
][self
.NODE_TMPL
] = {}
580 # Add the VNFDs and VLDs
581 for idx
, vnfd
in self
.vnfds
.items():
582 #vnfd.generate_vnf_template(tosca, idx)
584 'type' : vnfd
.vnf_type
,
587 self
.VENDOR
: self
.props
[self
.VENDOR
],
588 self
.VERSION
: self
.props
[self
.VERSION
]
591 if vnfd
.name
in self
.vnf_to_vld_map
:
592 vld_list
= self
.vnf_to_vld_map
[vnfd
.name
]
593 node
[self
.REQUIREMENTS
] = []
594 for vld_idx
in range(0, len(vld_list
)):
595 vld_link_name
= "{0}{1}".format("virtualLink", vld_idx
+ 1)
597 vld_prop
[vld_link_name
] = vld_list
[vld_idx
]
598 node
[self
.REQUIREMENTS
].append(vld_prop
)
599 if vnfd
.name
in self
._vnf
_vld
_conn
_point
_map
:
600 vnf_vld_list
= self
._vnf
_vld
_conn
_point
_map
[vnfd
.name
]
601 for vnf_vld
in vnf_vld_list
:
602 vnfd
.generate_vld_link(vld_link_name
, vnf_vld
[1])
604 for sub_mapping
in self
.substitution_mapping_forwarder
:
605 if sub_mapping
[0] == vnfd
.name
:
606 vnfd
.generate_forwarder_sub_mapping(sub_mapping
)
608 for vnfd_name
, cp_name
in self
.vnfd_sfc_map
.items():
609 if vnfd
.name
== vnfd_name
:
610 vnfd
.generate_sfc_link(cp_name
)
614 tosca
[self
.TOPOLOGY_TMPL
][self
.NODE_TMPL
][vnfd
.name
] = node
616 for vld_node_name
in self
.vlds
:
617 tosca
[self
.TOPOLOGY_TMPL
][self
.NODE_TMPL
][vld_node_name
] = self
.vlds
[vld_node_name
]
619 for fp_name
, fp
in self
.forwarding_paths
.items():
620 tosca
[self
.TOPOLOGY_TMPL
][self
.NODE_TMPL
][fp_name
] = fp
622 # add the config primitives
623 if len(self
.conf_prims
):
624 if self
.GROUPS
not in tosca
[self
.TOPOLOGY_TMPL
]:
625 tosca
[self
.TOPOLOGY_TMPL
][self
.GROUPS
] = {}
628 self
.TYPE
: self
.T_CONF_PRIM
630 conf_prims
[self
.MEMBERS
] = [vnfd
.name
for vnfd
in
633 for confp
in self
.conf_prims
:
634 prims
[confp
[self
.NAME
]] = {
635 self
.USER_DEF_SCRIPT
: confp
[self
.USER_DEF_SCRIPT
]
637 conf_prims
[self
.PROPERTIES
] = {
638 self
.PRIMITIVES
: prims
640 conf_prims
[self
.DESC
] = 'Test'
641 #tosca[self.TOPOLOGY_TMPL][self.GROUPS][self.CONF_PRIM] = conf_prims
644 # Add the scale group
645 if len(self
.scale_grps
):
646 if self
.POLICIES
not in tosca
[self
.TOPOLOGY_TMPL
]:
647 tosca
[self
.TOPOLOGY_TMPL
][self
.POLICIES
] = []
649 for sg
in self
.scale_grps
:
651 self
.TYPE
: self
.T_SCALE_GRP
,
654 tosca
[self
.TOPOLOGY_TMPL
][self
.POLICIES
].append({
658 # Add initial configs
659 if len(self
.initial_cfg
):
660 if self
.POLICIES
not in tosca
[self
.TOPOLOGY_TMPL
]:
661 tosca
[self
.TOPOLOGY_TMPL
][self
.POLICIES
] = []
663 for icp
in self
.initial_cfg
:
664 if len(tosca
[self
.TOPOLOGY_TMPL
][self
.NODE_TMPL
]) > 0:
665 node_name
= list(tosca
[self
.TOPOLOGY_TMPL
][self
.NODE_TMPL
].keys())[0]
667 self
.TYPE
: self
.T_INITIAL_CFG
,
668 self
.TARGETS
: "[{0}]".format(node_name
)
671 tosca
[self
.TOPOLOGY_TMPL
][self
.POLICIES
].append({
672 self
.INITIAL_CFG
: icpt
675 if len(self
.placement_groups
) > 0:
676 if self
.POLICIES
not in tosca
[self
.TOPOLOGY_TMPL
]:
677 tosca
[self
.TOPOLOGY_TMPL
][self
.POLICIES
] = []
679 for placment_group
in self
.placement_groups
:
680 tosca
[self
.TOPOLOGY_TMPL
][self
.POLICIES
].append(placment_group
)
682 if len(self
.vnffgds
) > 0:
683 if self
.GROUPS
not in tosca
[self
.TOPOLOGY_TMPL
]:
684 tosca
[self
.TOPOLOGY_TMPL
][self
.GROUPS
] = {}
685 for vnffgd_name
in self
.vnffgds
:
686 tosca
[self
.TOPOLOGY_TMPL
][self
.GROUPS
][vnffgd_name
] = self
.vnffgds
[vnffgd_name
]
691 def get_supporting_files(self
):
693 # Get the config files for initial config
694 for icp
in self
.initial_cfg
:
695 if 'properties' in icp
:
696 if 'user_defined_script' in icp
['properties']:
697 script
= os
.path
.basename(icp
['properties']['user_defined_script'])
701 self
.DEST
: "{}/{}".format(self
.SCRIPT_DIR
, script
),
704 # TODO (pjoseph): Add support for config scripts,
707 self
.log
.debug(_("{0}, supporting files: {1}").format(self
, files
))