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.
21 from rift
.mano
.yang_translator
.common
.exception
import ValidationError
22 from rift
.mano
.yang_translator
.common
.utils
import _
23 from rift
.mano
.yang_translator
.rwmano
.syntax
.tosca_resource \
25 from rift
.mano
.yang_translator
.rwmano
.syntax
.tosca_template \
27 from rift
.mano
.yang_translator
.rwmano
.translate_descriptors \
28 import TranslateDescriptors
30 import rift
.package
.image
31 from rift
.package
.package
import TarPackageArchive
32 import rift
.package
.cloud_init
33 import rift
.package
.script
34 import rift
.package
.store
37 class YangTranslator(object):
38 '''Invokes translation methods.'''
40 def __init__(self
, log
, yangs
=None, files
=None, packages
=[]):
41 super(YangTranslator
, self
).__init
__()
48 self
.tosca_template
= ToscaTemplate(log
)
49 self
.node_translator
= None
51 log
.info(_('Initialized parameters for translation.'))
57 self
.node_translator
= TranslateDescriptors(self
.log
,
61 self
.tosca_template
.resources
= self
.node_translator
.translate()
63 return self
.tosca_template
.output_to_tosca()
66 '''Get the descriptors and convert to yang instances'''
67 for filename
in self
.files
:
68 self
.log
.debug(_("Load file {0}").format(filename
))
69 # Only one descriptor per file
70 if tarfile
.is_tarfile(filename
):
71 tar
= open(filename
, "r+b")
72 archive
= TarPackageArchive(self
.log
, tar
)
73 pkg
= archive
.create_package()
75 desc_type
= pkg
.descriptor_type
76 if desc_type
== TranslateDescriptors
.NSD
:
77 if TranslateDescriptors
.NSD
not in self
.yangs
:
78 self
.yangs
[TranslateDescriptors
.NSD
] = []
79 self
.yangs
[TranslateDescriptors
.NSD
]. \
80 append(pkg
.descriptor_msg
.as_dict())
81 elif desc_type
== TranslateDescriptors
.VNFD
:
82 if TranslateDescriptors
.VNFD
not in self
.yangs
:
83 self
.yangs
[TranslateDescriptors
.VNFD
] = []
84 self
.yangs
[TranslateDescriptors
.VNFD
]. \
85 append(pkg
.descriptor_msg
.as_dict())
87 raise ValidationError("Unknown descriptor type: {}".
90 def _create_csar_files(self
, output_dir
, name
, tmpl
,
92 if ToscaTemplate
.TOSCA
not in tmpl
:
93 self
.log
.error(_("Did not find TOSCA template for {0}").
97 # Create sub for each NS template
98 subdir
= os
.path
.join(output_dir
, name
)
99 if os
.path
.exists(subdir
):
100 shutil
.rmtree(subdir
)
103 # Create the definitions dir
104 def_dir
= os
.path
.join(subdir
, 'Definitions')
106 entry_file
= os
.path
.join(def_dir
, name
+'.yaml')
107 self
.log
.debug(_("Writing file {0}").
109 with
open(entry_file
, 'w+') as f
:
110 f
.write(tmpl
[ToscaTemplate
.TOSCA
])
112 # Create the Tosca meta
113 meta_dir
= os
.path
.join(subdir
, 'TOSCA-Metadata')
114 os
.makedirs(meta_dir
)
115 meta
= '''TOSCA-Meta-File-Version: 1.0
118 Entry-Definitions: Definitions/'''
119 meta_data
= "{}{}".format(meta
, name
+'.yaml')
120 meta_file
= os
.path
.join(meta_dir
, 'TOSCA.meta')
121 self
.log
.debug(_("Writing file {0}:\n{1}").
122 format(meta_file
, meta_data
))
123 with
open(meta_file
, 'w+') as f
:
126 # Copy other supporting files
127 if ToscaTemplate
.FILES
in tmpl
:
128 for f
in tmpl
[ToscaTemplate
.FILES
]:
129 self
.log
.debug(_("Copy supporting file {0}").format(f
))
131 # Search in source packages
133 for pkg
in self
.pkgs
:
134 # TODO(pjoseph): Need to add support for other file types
135 fname
= f
[ToscaResource
.NAME
]
136 dest_path
= os
.path
.join(subdir
, f
[ToscaResource
.DEST
])
137 ftype
= f
[ToscaResource
.TYPE
]
140 image_file_map
= rift
.package
.image
.get_package_image_files(pkg
)
142 if fname
in image_file_map
:
143 self
.log
.debug(_("Extracting image {0} to {1}").
144 format(fname
, dest_path
))
145 pkg
.extract_file(image_file_map
[fname
],
149 elif ftype
== 'script':
151 rift
.package
.script
.PackageScriptExtractor
.package_script_files(pkg
)
152 if fname
in script_file_map
:
153 self
.log
.debug(_("Extracting script {0} to {1}").
154 format(fname
, dest_path
))
155 pkg
.extract_file(script_file_map
[fname
],
159 elif ftype
== 'cloud_init':
161 rift
.package
.cloud_init
.PackageCloudInitExtractor
.package_script_files(pkg
)
162 if fname
in script_file_map
:
163 self
.log
.debug(_("Extracting script {0} to {1}").
164 format(fname
, dest_path
))
165 pkg
.extract_file(script_file_map
[fname
],
170 self
.log
.warn(_("Unknown file type {0}: {1}").
173 #TODO(pjoseph): Search in other locations
175 # Create the ZIP archive
181 zip_file
= name
+ '.zip'
182 zip_path
= os
.path
.join(output_dir
, zip_file
)
183 self
.log
.debug(_("Creating zip file {0}").format(zip_path
))
184 zip_cmd
= "zip -r {}.partial ."
185 subprocess
.check_call(zip_cmd
.format(zip_path
),
187 stdout
=subprocess
.DEVNULL
)
188 mv_cmd
= "mv {0}.partial {0}"
189 subprocess
.check_call(mv_cmd
.format(zip_path
),
191 stdout
=subprocess
.DEVNULL
)
192 shutil
.rmtree(subdir
)
195 except subprocess
.CalledProcessError
as e
:
196 self
.log
.error(_("Creating CSAR archive failed: {0}").
199 except Exception as e
:
200 self
.log
.exception(e
)
205 def write_output(self
, output
,
210 for key
in output
.keys():
212 zf
= self
._create
_csar
_files
(output_dir
,
218 print(_("TOSCA Template {0}:\n{1}").
219 format(key
, output
[key
]))