Merge branch 'master' of ssh://git.onelab.eu/git/sfa
[sfa.git] / sfa / util / config.py
1 #!/usr/bin/python
2 import sys
3 import os
4 import time
5 import ConfigParser
6 import tempfile
7 import codecs
8 from StringIO import StringIO
9 from sfa.util.xml import XML
10
11 default_config = \
12 """
13 """
14
15 class Config:
16   
17     def __init__(self, config_file='/etc/sfa/sfa_config'):
18         self._files = []
19         self.config_path = os.path.dirname(config_file)
20         self.config = ConfigParser.ConfigParser()  
21         self.filename = config_file
22         if not os.path.isfile(self.filename):
23             self.create(self.filename)
24         self.load(self.filename)
25         
26
27     def _header(self):
28         header = """
29 DO NOT EDIT. This file was automatically generated at
30 %s from:
31
32 %s
33 """ % (time.asctime(), os.linesep.join(self._files))
34
35         # Get rid of the surrounding newlines
36         return header.strip().split(os.linesep)
37
38     def create(self, filename):
39         if not os.path.exists(os.path.dirname(filename)):
40             os.makedirs(os.path.dirname(filename))
41         configfile = open(filename, 'w')
42         configfile.write(default_config)
43         configfile.close()
44         
45
46     def load(self, filename):
47         if filename:
48             try:
49                 self.config.read(filename)
50             except:
51                 print "normal read failed" 
52                 if filename.endswith('.xml'):
53                     self.load_xml(filename)
54                 else:
55                     print "loading shell"
56                     self.load_shell(filename)
57             self._files.append(filename)
58             self.set_attributes()
59
60     def load_xml(self, filename):
61         xml = XML(filename)
62         categories = xml.xpath('//configuration/variables/category')
63         for category in categories:
64             section_name = category.get('id')
65             if not self.config.has_section(section_name):
66                 self.config.add_section(section_name)
67             options = category.xpath('./variablelist/variable')
68             for option in options:
69                 option_name = option.get('id')
70                 value = option.xpath('./value')[0].text
71                 if not value:
72                     value = ""
73                 self.config.set(section_name, option_name, value)
74          
75     def load_shell(self, filename):
76         f = open(filename, 'r')
77         for line in f:
78             try:
79                 if line.startswith('#'):
80                     continue
81                 parts = line.strip().split("=")
82                 if len(parts) < 2:
83                     continue
84                 option = parts[0]
85                 value = parts[1].replace('"', '').replace("'","")
86                 section, var = self.locate_varname(option, strict=False)
87                 if section and var:
88                     self.set(section, var, value)
89             except:
90                 pass
91         f.close()               
92
93     def locate_varname(self, varname, strict=True):
94         varname = varname.lower()
95         sections = self.config.sections()
96         section_name = ""
97         var_name = ""
98         for section in sections:
99             if varname.startswith(section.lower()) and len(section) > len(section_name):
100                 section_name = section.lower()
101                 var_name = varname.replace(section_name, "")[1:]
102         if strict and not self.config.has_option(section_name, var_name):
103             raise ConfigParser.NoOptionError(var_name, section_name)
104         return (section_name, var_name)             
105
106     def set_attributes(self):
107         sections = self.config.sections()
108         for section in sections:
109             for item in self.config.items(section):
110                 name = "%s_%s" % (section, item[0])
111                 value = item[1]
112                 setattr(self, name, value)
113                 setattr(self, name.upper(), value)
114         
115
116     def verify(self, config1, config2, validate_method):
117         return True
118
119     def validate_type(self, var_type, value):
120         return True
121
122     @staticmethod
123     def is_xml(config_file):
124         try:
125             x = Xml(config_file)
126             return True     
127         except:
128             return False
129
130     @staticmethod
131     def is_ini(config_file):
132         try:
133             c = ConfigParser.ConfigParser()
134             c.read(config_file)
135             return True
136         except:
137             return False
138
139
140     def dump(self, sections = []):
141         sys.stdout.write(output_python())
142
143     def output_python(self, encoding = "utf-8"):
144         buf = codecs.lookup(encoding)[3](StringIO())
145         buf.writelines(["# " + line + os.linesep for line in self._header()]) 
146         
147         for section in self.sections():
148             buf.write("[%s]%s" % (section, os.linesep))
149             for (name,value) in self.items(section):
150                 buf.write("%s=%s%s" % (name,value,os.linesep))
151             buf.write(os.linesep)
152         return buf.getvalue()
153                 
154     def output_shell(self, show_comments = True, encoding = "utf-8"):
155         """
156         Return variables as a shell script.
157         """
158
159         buf = codecs.lookup(encoding)[3](StringIO())
160         buf.writelines(["# " + line + os.linesep for line in self._header()])
161
162         for section in self.sections():
163             for (name,value) in self.items(section):
164                 # bash does not have the concept of NULL
165                 if value:
166                     option = "%s_%s" % (section.upper(), name.upper())
167                     if not value.isdigit() and not bool(value):
168                         value = "'%s'" % value  
169                     buf.write(option + "=" + value + os.linesep)
170         return buf.getvalue()        
171
172     def output_php(selfi, encoding = "utf-8"):
173         """
174         Return variables as a PHP script.
175         """
176
177         buf = codecs.lookup(encoding)[3](StringIO())
178         buf.write("<?php" + os.linesep)
179         buf.writelines(["// " + line + os.linesep for line in self._header()])
180
181         for section in self.sections():
182             for (name,value) in self.items(section):
183                 option = "%s_%s" % (section, name)
184                 buf.write(os.linesep)
185                 buf.write("// " + option + os.linesep)
186                 if value is None:
187                     value = 'NULL'
188                 buf.write("define('%s', %s);" % (option, value) + os.linesep)
189
190         buf.write("?>" + os.linesep)
191
192         return buf.getvalue()    
193
194     def output_xml(self, encoding = "utf-8"):
195         pass
196
197     def output_variables(self, encoding="utf-8"):
198         """
199         Return list of all variable names.
200         """
201
202         buf = codecs.lookup(encoding)[3](StringIO())
203         for section in self.sections():
204             for (name,value) in self.items(section):
205                 option = "%s_%s" % (section,name) 
206                 buf.write(option + os.linesep)
207
208         return buf.getvalue()
209         pass 
210         
211     def write(self, filename=None):
212         if not filename:
213             filename = self.filename
214         configfile = open(filename, 'w') 
215         self.config.write(configfile)
216     
217     def save(self, filename=None):
218         self.write(filename)
219
220
221     def get_trustedroots_dir(self):
222         return self.config_path + os.sep + 'trusted_roots'
223
224     def get_openflow_aggrMgr_info(self):
225         aggr_mgr_ip = 'localhost'
226         if (hasattr(self,'openflow_aggregate_manager_ip')):
227             aggr_mgr_ip = self.OPENFLOW_AGGREGATE_MANAGER_IP
228
229         aggr_mgr_port = 2603
230         if (hasattr(self,'openflow_aggregate_manager_port')):
231             aggr_mgr_port = self.OPENFLOW_AGGREGATE_MANAGER_PORT
232
233         return (aggr_mgr_ip,aggr_mgr_port)
234
235     def get_interface_hrn(self):
236         if (hasattr(self,'sfa_interface_hrn')):
237             return self.SFA_INTERFACE_HRN
238         else:
239             return "plc"
240
241     def __getattr__(self, attr):
242         return getattr(self.config, attr)
243
244 if __name__ == '__main__':
245     filename = None
246     if len(sys.argv) > 1:
247         filename = sys.argv[1]
248         config = Config(filename)
249     else:    
250         config = Config()
251     config.dump()
252