67e81c4286c2b79e4e23e78a7f25cc57ce45fbd6
[sfa.git] / sfa / util / config.py
1 #!/usr/bin/env python3
2
3 # pylint: disable=c0111, c0103, r0904, r1705, r0201
4
5 import sys
6 import os
7 import time
8 #import tempfile
9 from io import StringIO
10 from sfa.util.xml import XML
11 from sfa.util.py23 import ConfigParser
12
13 default_config = \
14     """
15 """
16
17
18 def isbool(val):
19     return val.lower() in ("true", "false")
20
21
22 def str2bool(v):
23     return v.lower() in ("true", "1")
24
25
26 class Config:
27
28     def __init__(self, config_file='/etc/sfa/sfa_config'):
29         self._files = []
30         self.config_path = os.path.dirname(config_file)
31         self.config = ConfigParser.ConfigParser()
32         self.filename = config_file
33         if not os.path.isfile(self.filename):
34             self.create(self.filename)
35         self.load(self.filename)
36
37     def _header(self):
38         header = """
39 DO NOT EDIT. This file was automatically generated at
40 %s from:
41
42 %s
43 """ % (time.asctime(), os.linesep.join(self._files))
44
45         # Get rid of the surrounding newlines
46         return header.strip().split(os.linesep)
47
48     def create(self, filename):
49         if not os.path.exists(os.path.dirname(filename)):
50             os.makedirs(os.path.dirname(filename))
51         configfile = open(filename, 'w')
52         configfile.write(default_config)
53         configfile.close()
54
55     def load(self, filename):
56         if filename:
57             try:
58                 self.config.read(filename)
59             except ConfigParser.MissingSectionHeaderError:
60                 if filename.endswith('.xml'):
61                     self.load_xml(filename)
62                 else:
63                     self.load_shell(filename)
64             self._files.append(filename)
65             self.set_attributes()
66
67     def load_xml(self, filename):
68         xml = XML(filename)
69         categories = xml.xpath('//configuration/variables/category')
70         for category in categories:
71             section_name = category.get('id')
72             if not self.config.has_section(section_name):
73                 self.config.add_section(section_name)
74             options = category.xpath('./variablelist/variable')
75             for option in options:
76                 option_name = option.get('id')
77                 value = option.xpath('./value')[0].text
78                 if not value:
79                     value = ""
80                 self.config.set(section_name, option_name, value)
81
82     def load_shell(self, filename):
83         f = open(filename, 'r')
84         for line in f:
85             try:
86                 if line.startswith('#'):
87                     continue
88                 parts = line.strip().split("=")
89                 if len(parts) < 2:
90                     continue
91                 option = parts[0]
92                 value = parts[1].replace('"', '').replace("'", "")
93                 section, var = self.locate_varname(option, strict=False)
94                 if section and var:
95                     self.set(section, var, value)
96             except:
97                 pass
98         f.close()
99
100     def locate_varname(self, varname, strict=True):
101         varname = varname.lower()
102         sections = self.config.sections()
103         section_name = ""
104         var_name = ""
105         for section in sections:
106             if varname.startswith(section.lower()) and len(section) > len(section_name):
107                 section_name = section.lower()
108                 var_name = varname.replace(section_name, "")[1:]
109         if strict and not self.config.has_option(section_name, var_name):
110             raise ConfigParser.NoOptionError(var_name, section_name)
111         return (section_name, var_name)
112
113     def set_attributes(self):
114         sections = self.config.sections()
115         for section in sections:
116             for item in self.config.items(section):
117                 name = "%s_%s" % (section, item[0])
118                 value = item[1]
119                 if isbool(value):
120                     value = str2bool(value)
121                 elif value.isdigit():
122                     value = int(value)
123                 setattr(self, name, value)
124                 setattr(self, name.upper(), value)
125
126     def variables(self):
127         """
128         Return all variables.
129
130         Returns:
131
132         variables = { 'category_id': (category, variablelist) }
133
134         category = { 'id': "category_identifier",
135                      'name': "Category name",
136                      'description': "Category description" }
137
138         variablelist = { 'variable_id': variable }
139
140         variable = { 'id': "variable_identifier",
141                      'type': "variable_type",
142                      'value': "variable_value",
143                      'name': "Variable name",
144                      'description': "Variable description" }
145         """
146
147         variables = {}
148         for section in self.config.sections():
149             category = {
150                 'id': section,
151                 'name': section,
152                 'description': section,
153             }
154             variable_list = {}
155             for item in self.config.items(section):
156                 var_name = item[0]
157                 name = "%s_%s" % (section, var_name)
158                 value = item[1]
159                 if isbool(value):
160                     value_type = bool
161                 elif value.isdigit():
162                     value_type = int
163                 else:
164                     value_type = str
165                 variable = {
166                     'id': var_name,
167                     'type': value_type,
168                     'value': value,
169                     'name': name,
170                     'description': name,
171                 }
172                 variable_list[name] = variable
173             variables[section] = (category, variable_list)
174         return variables
175
176     def verify(self, _config1, _config2, _validate_method):
177         return True
178
179     def validate_type(self, _var_type, _value):
180         return True
181
182     @staticmethod
183     def is_xml(config_file):
184         try:
185             _x = Xml(config_file)
186             return True
187         except:
188             return False
189
190     @staticmethod
191     def is_ini(config_file):
192         try:
193             c = ConfigParser.ConfigParser()
194             c.read(config_file)
195             return True
196         except ConfigParser.MissingSectionHeaderError:
197             return False
198
199     def dump(self, sections=None):
200         if sections is None:
201             sections = []
202         sys.stdout.write(self.output_python())
203
204     def output_python(self):
205         buf = StringIO()
206         buf.writelines(["# " + line + os.linesep for line in self._header()])
207
208         for section in self.sections():
209             buf.write("[%s]%s" % (section, os.linesep))
210             for (name, value) in self.items(section):
211                 buf.write("%s=%s%s" % (name, value, os.linesep))
212             buf.write(os.linesep)
213         return buf.getvalue()
214
215     def output_shell(self):
216         """
217         Return variables as a shell script.
218         """
219
220         buf = StringIO()
221         buf.writelines(["# " + line + os.linesep for line in self._header()])
222
223         for section in self.sections():
224             for (name, value) in self.items(section):
225                 # bash does not have the concept of NULL
226                 if value:
227                     option = "%s_%s" % (section.upper(), name.upper())
228                     if isbool(value):
229                         value = str(str2bool(value))
230                     elif not value.isdigit():
231                         value = '"%s"' % value
232                     buf.write(option + "=" + value + os.linesep)
233         return buf.getvalue()
234
235     def output_php(selfi):
236         """
237         Return variables as a PHP script.
238         """
239
240         buf = StringIO()
241         buf.write("<?php" + os.linesep)
242         buf.writelines(["// " + line + os.linesep for line in self._header()])
243
244         for section in self.sections():
245             for (name, value) in self.items(section):
246                 option = "%s_%s" % (section, name)
247                 buf.write(os.linesep)
248                 buf.write("// " + option + os.linesep)
249                 if value is None:
250                     value = 'NULL'
251                 buf.write("define('%s', %s);" % (option, value) + os.linesep)
252
253         buf.write("?>" + os.linesep)
254
255         return buf.getvalue()
256
257     def output_xml(self):
258         pass
259
260     def output_variables(self):
261         """
262         Return list of all variable names.
263         """
264
265         buf = StringIO()
266         for section in self.sections():
267             for (name, _value) in self.items(section):
268                 option = "%s_%s" % (section, name)
269                 buf.write(option + os.linesep)
270
271         return buf.getvalue()
272
273     def write(self, filename=None):
274         if not filename:
275             filename = self.filename
276         configfile = open(filename, 'w')
277         self.config.write(configfile)
278
279     def save(self, filename=None):
280         self.write(filename)
281
282     def get_trustedroots_dir(self):
283         return self.config_path + os.sep + 'trusted_roots'
284
285     def get_openflow_aggrMgr_info(self):
286         aggr_mgr_ip = 'localhost'
287         if hasattr(self, 'openflow_aggregate_manager_ip'):
288             aggr_mgr_ip = self.OPENFLOW_AGGREGATE_MANAGER_IP
289
290         aggr_mgr_port = 2603
291         if hasattr(self, 'openflow_aggregate_manager_port'):
292             aggr_mgr_port = self.OPENFLOW_AGGREGATE_MANAGER_PORT
293
294         return (aggr_mgr_ip, aggr_mgr_port)
295
296     def get_interface_hrn(self):
297         if hasattr(self, 'sfa_interface_hrn'):
298             return self.SFA_INTERFACE_HRN
299         else:
300             return "plc"
301
302     def __getattr__(self, attr):
303         return getattr(self.config, attr)
304
305 if __name__ == '__main__':
306     def main():
307         filename = None
308         if len(sys.argv) > 1:
309             filename = sys.argv[1]
310             config = Config(filename)
311         else:
312             config = Config()
313         config.dump()
314     main()