* YANG to TOSCA translator
[osm/SO.git] / common / python / rift / mano / yang_translator / shell.py
1 #
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
5 #
6 # http://www.apache.org/licenses/LICENSE-2.0
7 #
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
12 # under the License.
13
14 # Copyright 2016 RIFT.io Inc
15
16
17 import argparse
18 import logging
19 import logging.config
20 import os
21
22 import magic
23
24 from rift.mano.yang_translator.common.utils import _
25 from rift.mano.yang_translator.rwmano.yang_translator import YangTranslator
26
27
28 """
29 Test the yang translation from command line as:
30 #translator
31 --template-file=<path to the JSON template or tar.gz>
32 --template-type=<type of template e.g. yang>
33 --parameters="purpose=test"
34 --output_dir=<output directory>
35 --validate_only
36 Takes four user arguments,
37 1. type of translation (e.g. yang) (required)
38 2. Path to the file that needs to be translated (required)
39 3. Input parameters (optional)
40 4. Write to output files in a dir (optional), else print on screen
41
42 In order to use translator to only validate template,
43 without actual translation, pass --validate-only along with
44 other required arguments.
45
46 """
47
48
49 class TranslatorShell(object):
50
51 SUPPORTED_TYPES = ['yang']
52 COPY_DIRS = ['images']
53 SUPPORTED_INPUTS = (TAR, JSON, XML, YAML) = ('tar', 'json', 'xml', 'yaml')
54
55 def _parse_args(self, raw_args=None):
56 parser = argparse.ArgumentParser(
57 description='RIFT.io YANG translator for descriptors')
58 parser.add_argument(
59 "-f",
60 "--template-file",
61 nargs="+",
62 required=True,
63 action="append",
64 help="Template file to translate")
65 parser.add_argument(
66 "-o",
67 "--output-dir",
68 default=None,
69 help="Directory to output")
70 parser.add_argument(
71 "-p", "--parameters",
72 help="Input parameters")
73 parser.add_argument(
74 "--archive",
75 help="Create a ZIP archive",
76 action="store_true")
77 parser.add_argument(
78 "--debug",
79 help="Enable debug logging",
80 action="store_true")
81 if raw_args:
82 args = parser.parse_args(raw_args)
83 else:
84 args = parser.parse_args()
85 return args
86
87 def main(self, raw_args=None, log=None):
88 args = self._parse_args(raw_args)
89 if log is None:
90 if args.debug:
91 logging.basicConfig(level=logging.DEBUG)
92 else:
93 logging.basicConfig(level=logging.ERROR)
94 log = logging.getLogger("yang-translator")
95
96 log.debug(_("Args passed is {}").format(args))
97 self.log = log
98 self.in_files = []
99 self.ftype = None
100 for f in args.template_file:
101 path = os.path.abspath(f[0])
102 if not os.path.isfile(path):
103 msg = _("The path %(path)s is not a valid file.") % {
104 'path': path}
105 log.error(msg)
106 raise ValueError(msg)
107 # Get the file type
108 ftype = self._get_file_type(path)
109 if self.ftype is None:
110 self.ftype = ftype
111 elif self.ftype != ftype:
112 msg = (_("All input files hould be of same type"))
113 log.error(msg)
114 raise ValueError(msg)
115 self.in_files.append(path)
116
117 self.log.debug(_("Input files are of type {0}").
118 format(self.ftype))
119
120 self.archive = None
121 self._translate(output_dir=args.output_dir,
122 archive=args.archive)
123
124 def _translate(self, output_dir=None, archive=False):
125 output = None
126 self.log.debug(_('Loading the yang template for {0}.').
127 format(self.in_files))
128 translator = YangTranslator(self.log, files=self.in_files)
129 self.log.debug(_('Translating the yang template for {0}.').
130 format(self.in_files))
131 output = translator.translate()
132 if output:
133 if output_dir:
134 translator.write_output(output,
135 output_dir=output_dir,
136 archive=archive)
137 else:
138 for key in output.keys():
139 print(_("TOSCA Template {0}:\n{1}").
140 format(key, output[key]))
141 else:
142 self.log.error(_("Did not get any translated output!!"))
143
144
145 def _get_file_type(self, path):
146 m = magic.open(magic.MAGIC_MIME)
147 m.load()
148 typ = m.file(path)
149 if typ.startswith('text/plain'):
150 # Assume to be yaml
151 return self.YAML
152 # On Fedora 20, it return x-gzip, while on Ubuntu 16 it is gzip
153 elif typ.startswith('application/x-gzip') or \
154 typ.startswith('application/gzip') :
155 return self.TAR
156 else:
157 msg = _("The file {0} is not a supported type: {1}"). \
158 format(path, typ)
159 self.log.error(msg)
160 raise ValueError(msg)
161
162
163 def main(args=None, log=None):
164 TranslatorShell().main(raw_args=args, log=log)
165
166
167 if __name__ == '__main__':
168 main()