added load_shell(). updated load(). Added 'strict' param to locate_varname()
[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                 if filename.endswith('.xml'):
52                     self.load_xml(filename)
53                 else:
54                     self.load_shell(filename)
55             self._files.append(filename)
56             self.set_attributes()
57
58     def load_xml(self, filename):
59         xml = XML(filename)
60         categories = xml.xpath('//configuration/variables/category')
61         for category in categories:
62             section_name = category.get('id')
63             if not self.config.has_section(section_name):
64                 self.config.add_section(section_name)
65             options = category.xpath('./variablelist/variable')
66             for option in options:
67                 option_name = option.get('id')
68                 value = option.xpath('./value')[0].text
69                 if not value:
70                     value = ""
71                 self.config.set(section_name, option_name, value)
72          
73     def load_shell(self, filename):
74         f = open(filename, 'r')
75         for line in f:
76             try:
77                 if line.startswith('#'):
78                     continue
79                 parts = line.strip().split("=")
80                 if len(parts) < 2:
81                     continue
82                 option = parts[0]
83                 value = parts[1].replace('"', '').replace("'","")
84                 section, var = self.locate_varname(option, strict=False)
85                 if section and var:
86                     self.set(section, var, value)
87             except:
88                 pass
89         f.close()               
90
91     def locate_varname(self, varname, strict=True):
92         varname = varname.lower()
93         sections = self.config.sections()
94         section_name = ""
95         var_name = ""
96         for section in sections:
97             if varname.startswith(section.lower()) and len(section) > len(section_name):
98                 section_name = section.lower()
99                 var_name = varname.replace(section_name, "")[1:]
100         if strict and not self.config.has_option(section_name, var_name):
101             raise ConfigParser.NoOptionError(var_name, section_name)
102         return (section_name, var_name)             
103
104     def set_attributes(self):
105         sections = self.config.sections()
106         for section in sections:
107             for item in self.config.items(section):
108                 name = "%s_%s" % (section, item[0])
109                 value = item[1]
110                 setattr(self, name, value)
111                 setattr(self, name.upper(), value)
112         
113
114     def verify(self, config1, config2, validate_method):
115         return True
116
117     def validate_type(self, var_type, value):
118         return True
119
120     def dump(self, sections = []):
121         sys.stdout.write(output_python())
122
123     def output_python(self, encoding = "utf-8"):
124         buf = codecs.lookup(encoding)[3](StringIO())
125         buf.writelines(["# " + line + os.linesep for line in self._header()]) 
126         
127         for section in self.sections():
128             buf.write("[%s]%s" % (section, os.linesep))
129             for (name,value) in self.items(section):
130                 buf.write("%s=%s%s" % (name,value,os.linesep))
131             buf.write(os.linesep)
132         return buf.getvalue()
133                 
134     def output_shell(self, show_comments = True, encoding = "utf-8"):
135         """
136         Return variables as a shell script.
137         """
138
139         buf = codecs.lookup(encoding)[3](StringIO())
140         buf.writelines(["# " + line + os.linesep for line in self._header()])
141
142         for section in self.sections():
143             for (name,value) in self.items(section):
144                 # bash does not have the concept of NULL
145                 if value:
146                     option = "%s_%s" % (section.upper(), name.upper())
147                     if not value.isdigit() and not bool(value):
148                         value = "'%s'" % value  
149                     buf.write(option + "=" + value + os.linesep)
150         return buf.getvalue()        
151
152     def output_php(selfi, encoding = "utf-8"):
153         """
154         Return variables as a PHP script.
155         """
156
157         buf = codecs.lookup(encoding)[3](StringIO())
158         buf.write("<?php" + os.linesep)
159         buf.writelines(["// " + line + os.linesep for line in self._header()])
160
161         for section in self.sections():
162             for (name,value) in self.items(section):
163                 option = "%s_%s" % (section, name)
164                 buf.write(os.linesep)
165                 buf.write("// " + option + os.linesep)
166                 if value is None:
167                     value = 'NULL'
168                 buf.write("define('%s', %s);" % (option, value) + os.linesep)
169
170         buf.write("?>" + os.linesep)
171
172         return buf.getvalue()    
173
174     def output_xml(self, encoding = "utf-8"):
175         pass
176
177     def output_variables(self):
178         """
179         Return list of all variable names.
180         """
181
182         buf = codecs.lookup(encoding)[3](StringIO())
183         for section in self.sections():
184             for (name,value) in self.items(section):
185                 option = "%s_%s" % (section,name) 
186                 buf.write(option + os.linesep)
187
188         return buf.getvalue()
189         pass 
190         
191     def write(self, filename=None):
192         if not filename:
193             filename = self.filename
194         configfile = open(filename, 'w') 
195         self.config.write(configfile)
196     
197     def save(self, filename=None):
198         self.write(filename)
199
200
201     def get_trustedroots_dir(self):
202         return self.config_path + os.sep + 'trusted_roots'
203
204     def get_openflow_aggrMgr_info(self):
205         aggr_mgr_ip = 'localhost'
206         if (hasattr(self,'openflow_aggregate_manager_ip')):
207             aggr_mgr_ip = self.OPENFLOW_AGGREGATE_MANAGER_IP
208
209         aggr_mgr_port = 2603
210         if (hasattr(self,'openflow_aggregate_manager_port')):
211             aggr_mgr_port = self.OPENFLOW_AGGREGATE_MANAGER_PORT
212
213         return (aggr_mgr_ip,aggr_mgr_port)
214
215     def get_interface_hrn(self):
216         if (hasattr(self,'sfa_interface_hrn')):
217             return self.SFA_INTERFACE_HRN
218         else:
219             return "plc"
220
221     def __getattr__(self, attr):
222         return getattr(self.config, attr)
223
224 if __name__ == '__main__':
225     filename = None
226     if len(sys.argv) > 1:
227         filename = sys.argv[1]
228         config = Config(filename)
229     else:    
230         config = Config()
231     config.dump()
232