2 # Licensed under the Apache License, Version 2.0 (the "License"); you may
3 # not use this file except in compliance with the License. You may obtain
4 # a copy of the License at
6 # http://www.apache.org/licenses/LICENSE-2.0
8 # Unless required by applicable law or agreed to in writing, software
9 # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
10 # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
11 # License for the specific language governing permissions and limitations
14 # Copyright 2016 RIFT.io Inc
20 from rift
.mano
.tosca_translator
.common
.utils
import _
22 from rift
.mano
.tosca_translator
.common
.utils
import dict_convert_values_to_str
26 gi
.require_version('RwYang', '1.0')
27 gi
.require_version('RwNsdYang', '1.0')
28 gi
.require_version('NsdYang', '1.0')
30 from gi
.repository
import NsdYang
31 from gi
.repository
import RwNsdYang
32 from gi
.repository
import RwYang
35 except ValueError as e
:
39 class ManoTemplate(object):
40 '''Container for full RIFT.io MANO template.'''
42 YANG_NS
= (NSD
, VNFD
) = ('nsd', 'vnfd')
43 OUTPUT_FIELDS
= (NAME
, ID
, YANG
, FILES
) = ('name', 'id', 'yang', 'files')
45 def __init__(self
, log
):
50 self
.description
= "Translated from TOSCA"
55 def output_to_yang(self
, use_gi
=False, indent
=4):
56 self
.log
.debug(_('Converting translated output to yang model.'))
59 nsd_id
= str(uuid
.uuid1())
64 nsd_cat
= RwNsdYang
.YangData_Nsd_NsdCatalog()
65 nsd
= nsd_cat
.nsd
.add()
67 nsd
.name
= self
.metadata
['name']
68 nsd
.description
= self
.description
69 nsd
.vendor
= self
.metadata
['vendor']
70 nsd
.short_name
= self
.metadata
['name']
71 nsd
.version
= self
.metadata
['version']
72 if 'logo' in self
.metadata
:
73 nsd
.logo
= self
.metadata
['logo']
74 except Exception as e
:
75 self
.log
.warning(_("Unable to use YANG GI to generate "
76 "descriptors, falling back to alternate "
77 "method: {}").format(e
))
84 'name': self
.metadata
['name'],
85 'description': self
.description
,
86 'vendor': self
.metadata
['vendor'],
87 'short-name': self
.metadata
['name'],
88 'version': self
.metadata
['version'],
91 for resource
in self
.resources
:
93 if resource
.type == 'vld':
94 resource
.generate_yang_model(nsd
, vnfds
, use_gi
=use_gi
)
96 vnf_type_duplicate
= []
98 vnfd_duplicate_resource_list
= []
99 for resource
in self
.resources
:
100 if resource
.type == 'vnfd':
101 vnfd_resources
.append(resource
)
103 vnfd_resources
.sort(key
=lambda x
: x
.member_vnf_id
, reverse
=False)
104 vnf_type_to_vnf_id
= {}
105 for resource
in vnfd_resources
:
106 if resource
.vnf_type
not in vnf_type_duplicate
:
107 resource
.generate_yang_model(nsd
, vnfds
, use_gi
=use_gi
)
108 vnf_type_to_vnf_id
[resource
.vnf_type
] = resource
.id
109 vnf_type_duplicate
.append(resource
.vnf_type
)
111 vnfd_duplicate_resource_list
.append(resource
)
113 for resource
in vnfd_duplicate_resource_list
:
114 resource
.generate_nsd_constiuent(nsd
, vnf_type_to_vnf_id
[resource
.vnf_type
])
116 for resource
in self
.resources
:
118 if resource
.type != 'vnfd' and resource
.type != 'vld':
119 resource
.generate_yang_model(nsd
, vnfds
, use_gi
=use_gi
)
121 for group
in self
.groups
:
122 group
.generate_yang_model(nsd
, vnfds
, use_gi
=use_gi
)
124 for policy
in self
.policies
:
125 policy
.generate_yang_model(nsd
, vnfds
, use_gi
=use_gi
)
127 # Add input params to nsd
129 for param
in self
.parameters
:
130 nsd
.input_parameter_xpath
.append(
131 NsdYang
.YangData_Nsd_NsdCatalog_Nsd_InputParameterXpath(
132 xpath
=param
.get_xpath(),
136 nsd
['input-parameter-xpath'] = []
137 for param
in self
.parameters
:
138 nsd
['input-parameter-xpath'].append(
139 {'xpath': param
.get_xpath()})
141 # Get list of supporting files referred in template
142 # Returned format is {desc_id: [{type: type, name: filename}]}
143 # TODO (pjoseph): Currently only images and scripts are retrieved.
144 # Need to add support to get script names, charms, etc.
146 for resource
in self
.resources
:
147 resource
.get_supporting_files(other_files
, desc_id
=nsd_id
)
149 for policy
in self
.policies
:
150 policy
.get_supporting_files(other_files
, desc_id
=nsd_id
)
152 self
.log
.debug(_("List of other files: {}".format(other_files
)))
154 # Do the final processing and convert each descriptor to yaml string
159 nsd_pf
= self
.get_yaml(['nsd', 'rw-nsd'], nsd_cat
)
160 nsd_id
= nsd_cat
.nsd
[0].id
161 nsd_name
= nsd_cat
.nsd
[0].name
164 nsd_name
= nsd
['name']
166 # In case of non gi proecssing,
167 # - convert all values to string
168 # - enclose in a catalog dict
169 # - prefix all keys with nsd or vnfd
170 # - Convert to YAML string
173 self
.add_cat(dict_convert_values_to_str(nsd
),
176 default_flow_style
=False)
184 if nsd_id
in other_files
:
185 nsd_out
[self
.FILES
] = other_files
[nsd_id
]
187 tpl
[self
.NSD
] = [nsd_out
]
194 vnfd_pf
= self
.get_yaml(['vnfd', 'rw-vnfd'], vnfd
)
195 vnfd_id
= vnfd
.vnfd
[0].id
196 vnfd_name
= vnfd
.vnfd
[0].name
200 vnfd_name
= vnfd
['name']
202 # In case of non gi proecssing,
203 # - convert all values to string
204 # - enclose in a catalog dict
205 # - prefix all keys with nsd or vnfd
206 # - Convert to YAML string
209 self
.add_cat(dict_convert_values_to_str(vnfd
),
212 default_flow_style
=False)
215 self
.NAME
: vnfd_name
,
220 if vnfd_id
in other_files
:
221 vnfd_out
[self
.FILES
] = other_files
[vnfd_id
]
223 tpl
[self
.VNFD
].append(vnfd_out
)
225 self
.log
.debug(_("NSD: {0}").format(tpl
[self
.NSD
]))
226 self
.log
.debug(_("VNFDs:"))
227 for vnfd
in tpl
[self
.VNFD
]:
228 self
.log
.debug(_("{0}").format(vnfd
))
232 def _get_field(self
, d
, pf
, field
='name'):
233 '''Get the name given for the descriptor'''
234 # Search within the desc for a key pf:name
236 if isinstance(d
, dict):
237 # If it is a dict, search for pf:name
241 for k
, v
in d
.items():
242 result
= self
._get
_field
(v
, pf
, field
)
245 elif isinstance(d
, list):
247 result
= self
._get
_field
(memb
, pf
, field
)
251 def prefix_dict(self
, d
, pf
):
252 '''Prefix all keys of a dict with a specific prefix:'''
253 if isinstance(d
, dict):
256 # Only prefix keys without any prefix
257 # so later we can do custom prefixing
258 # which will not get overwritten here
260 dic
[pf
+':'+key
] = self
.prefix_dict(d
[key
], pf
)
262 dic
[key
] = self
.prefix_dict(d
[key
], pf
)
264 elif isinstance(d
, list):
267 arr
.append(self
.prefix_dict(memb
, pf
))
272 def add_cat(self
, desc
, pf
):
273 return {pf
+'-catalog': {pf
: [desc
]}}
275 def get_yaml(self
, module_list
, desc
):
276 model
= RwYang
.Model
.create_libncx()
277 for module
in module_list
:
278 model
.load_module(module
)
279 return desc
.to_yaml(model
)