adding new config variables to config utility
[sfa.git] / config / sfa-config-tty
1 #!/usr/bin/python
2
3 # Interactively prompts for variable values
4 # expected arguments are
5 # command -d [default-xml [custom-xml [ consolidated-xml ]]]
6 #
7 # -d is for the myplc-devel package
8
9 # we use 3 instances of PLCConfiguration throughout:
10 # cdef : models the defaults, from plc_default.xml
11 # cread : merged from plc_default & configs/site.xml
12 # cwrite : site.xml + pending changes
13
14 import sys
15 import os
16 import re
17 import readline
18 import distutils.file_util
19 from optparse import OptionParser
20
21 from sfa.util.config import Config
22 from sfa.trust.hierarchy import *
23 from sfa.util.misc import *
24
25
26 all_variables   = ["SFA_REGISTRY_ROOT_AUTH",
27                    "SFA_REGISTRY_LEVEL1_AUTH",
28                    "SFA_REGISTRY_ENABLED",
29                    "SFA_REGISTRY_HOST", 
30                    "SFA_REGISTRY_PORT",
31                    "SFA_REGISTRY_TYPE",
32                    "SFA_AGGREGATE_ENABLED",
33                    "SFA_AGGREGATE_HOST",
34                    "SFA_AGGREGATE_PORT",
35                    "SFA_AGGREGATE_TYPE",
36                    "SFA_SM_ENABLED",
37                    "SFA_SM_HOST",
38                    "SFA_SM_PORT",
39                    "SFA_SM_TYPE",
40                    "SFA_PLC_USER",
41                    "SFA_PLC_PASSWORD",    
42                    "SFA_PLC_URL",
43                    "SFA_PLC_DB_NAME",
44                    "SFA_PLC_DB_HOST",
45                    "SFA_PLC_DB_PORT",
46                    "SFA_PLC_DB_USER",
47                    "SFA_PLC_DB_PASSWORD",
48                    ]
49 usual_variables = ["SFA_REGISTRY_ROOT_AUTH",
50                    "SFA_REGISTRY_LEVEL1_AUTH",
51                    "SFA_PLC_USER",
52                    "SFA_PLC_PASSWORD",
53                    "SFA_PLC_DB_HOST",
54                    "SFA_PLC_DB_USER",
55                    "SFA_PLC_DB_PASSWORD",
56                    ]
57
58
59 mainloop_usage= """Available commands:
60  u/U\t\t\tEdit usual variables
61  w/W\t\t\tWrite / Write & reload
62  q\t\t\tQuit (without saving)
63  h/?\t\t\tThis help
64 ---
65  l/L [<var>]\tShow Locally modified variables/values
66  s/S [<var>]\tShow all current variables/values 
67  e/E [<var>]\tEdit variables (all, in category, single)
68 ---
69 """ 
70
71 command_usage="%prog [options]"
72 command_usage += """
73   Unless you specify the -d option, meaning you want to configure
74   using defaults without interactive prompts""" 
75
76 variable_usage= """Edit Commands :
77 .\tStops prompting, return to mainloop
78 =\tShows default value
79 ?\tThis help    
80 """
81
82 def save_config(changes, config_file):
83     # always validate before saving
84     changes = validate(changes) 
85     
86     cfile = open(config_file, 'r')
87     lines = cfile.readlines()
88     cfile.close()
89     newlines = []
90     for line in lines:
91         added = False
92         for variable in changes:
93             if line.startswith(variable+'='):
94                 try:
95                     value = int(changes[variable])
96                     newline = '%s=%s\n' % (variable, value)
97                     newlines.append(newline)
98                 except:
99                     value = changes[variable]
100                     newline = '%s="%s"\n' % (variable, value)
101                     newlines.append(newline)
102                 added = True
103                 break
104         if not added:
105             newlines.append(line) 
106     
107     cfile = open(config_file, 'w')
108     cfile.writelines(newlines)
109     cfile.close()
110     print 'updated config file',config_file
111
112 def validate(changes):
113
114     if not changes:
115         return {}
116
117     defaults = get_defaults()
118     
119     # SFA_INTERFACE_HRN is SFA_REGISTRY_LEVEL1_AUTH, if thats blank it
120     # then defaults to SFA_REGISTRY_ROOT_AUTH 
121     # SFA_REGISTRY_LEVEL1_AUTH, so if either of these are present we must 
122     # update SFA_INTERFACE_HRN
123     if 'SFA_REGISTRY_ROOT_AUTH' in changes:
124         root_auth = changes['SFA_REGISTRY_ROOT_AUTH']
125     else:
126         root_auth = defaults['SFA_REGISTRY_ROOT_AUTH']
127              
128     if 'SFA_REGISTRY_LEVEL1_AUTH' in changes:
129         level1_auth = changes['SFA_REGISTRY_LEVEL1_AUTH']
130     else:
131         level1_auth = defaults['SFA_REGISTRY_LEVEL1_AUTH']
132                 
133     if level1_auth:
134         interface_hrn = level1_auth
135     else:
136         interface_hrn = root_auth
137     changes['SFA_INTERFACE_HRN'] = interface_hrn
138     return changes                            
139
140 def get_defaults():
141     sfa_config = Config()
142     
143     defaults = {}
144     for var in dir(sfa_config):
145         if var.startswith('SFA'):
146             value = eval("sfa_config.%s" % var)
147             defaults[var] = value
148
149     return defaults       
150
151 def prompt_variable(variable, default_config):
152     if variable in default_config:
153         default_value = default_config[variable]
154     else:
155         default_value = ""  
156    
157     while True:
158         prompt = "%(variable)s : [%(default_value)s] " % locals()
159         try: 
160             answer = raw_input(prompt).strip()
161         except EOFError:
162             raise Exception ('BailOut')
163         except KeyboardInterrupt:
164             print "\n"
165             raise Exception ('BailOut')
166
167         if (answer == "") or (answer == default_value):
168             return default_value
169         elif answer in ['""', "''"]:
170             return ""
171         elif (answer == "."):
172             raise Exception ('BailOut')
173         elif (answer == "?"):
174             print variable_usage.strip()
175         elif (answer == "="):
176             print ("%s defaults to %s" %(variable,default_value))
177         else:
178             return answer
179
180 def show_variable(variable, value_dict):
181     print "%s=%s" % (variable, value_dict[variable])                    
182     
183 def mainloop (default_config, config_file):
184     changes = {}
185     while True:
186         try:
187             answer = raw_input("Enter command (u for usual changes, w to save, ? for help) ").strip()
188         except EOFError:
189             answer =""
190         except KeyboardInterrupt:
191             print "\nBye"
192             sys.exit()
193
194         if (answer == "") or (answer in "?hH"):
195             print mainloop_usage
196             continue
197         if answer in ['?']:
198             print "help"  
199
200         if (answer in ["q","Q"]):
201             break
202         elif (answer == "w"):
203             save_config(changes, config_file)
204         elif (answer == "u"):
205             try: 
206                 for varname in usual_variables:
207                     changes[varname] = prompt_variable(varname, default_config)
208             except Exception, inst:
209                 if (str(inst) != 'BailOut'):
210                     raise
211         elif (answer in ["e","E"]):
212             try:
213                 for varname in all_variables:
214                     changes[varname] = prompt_variable(varname, default_config)
215             except Exception, inst:
216                 if (str(inst) != 'BailOut'):
217                     raise
218         elif (answer in "sS"):
219             for varname in usual_variables:
220                 show_variable (varname, default_config)
221         elif (answer in "lL"):
222             if not changes:
223                 print "No changes to display"
224             else:
225                 for varname in changes:
226                     show_variable(varname, changes)
227         else:
228             print ("Unknown command >%s< -- use h for help" % answer)
229
230     result = {}
231     result.update(default_config)
232     result.update(changes)
233     return result
234     
235 def setup_server_key(config_dict):
236     hrn = config_dict.get('SFA_INTERFACE_HRN')
237     if not hrn: return
238    
239     # Get the path to the authorities directory hierarchy
240     hierarchy = Hierarchy()
241     path = hierarchy.basedir
242     auth_path = hrn.replace(".", os.sep)
243  
244     # define some useful variables   
245     key = 'server.key'
246     cert = 'server.cert'
247     hrn_leaf = get_leaf(hrn)
248     if not hrn_leaf:
249         hrn_leaf = hrn
250     new_server_key = os.sep.join([path, auth_path, hrn_leaf]) + ".pkey"
251     old_server_key = os.sep.join([path, key])
252     old_server_cert = os.sep.join([path, cert])
253
254     # remove old key/cert
255     for fd in [old_server_key, old_server_cert]:
256         if os.path.isfile(fd):
257             os.remove(fd)
258
259     # create new server.key
260     try:
261         distutils.file_util.copy_file(src=new_server_key, dst=old_server_key, verbose=1)
262         print "\t\t%(old_server_key)s\ncopied from\t%(new_server_key)s" % locals()
263     # this is expected when running this tool for the first time (before sfa-import-plc.py)
264     except:
265         print "Could not create %(old_server_key)s - ignore if you haven't run sfa-import-plc.py yet"%locals()
266     
267     
268
269 ####################
270 def main ():
271
272     command=sys.argv[0]
273     argv = sys.argv[1:]
274     save = True
275     parser = OptionParser(usage=command_usage, version="%prog 1.0")
276     parser.set_defaults(config_dir="/etc/sfa",
277                         usual_variables=[])
278     parser.add_option("","--configdir",dest="config_dir",action="append", help="specify configuration directory")
279     parser.add_option("","--usual_variable",dest="usual_variables",action="append", help="add a usual variable")
280     parser.add_option("-d", "--default", action="count", help="dont prompt for values, just use defaults")
281     (config,args) = parser.parse_args()
282     if len(args)>3:
283         parser.error("too many arguments")
284
285     config_dir = parser.values.config_dir
286     config_file = os.sep.join([config_dir, 'sfa_config'])
287     defaults = get_defaults()
288     # if -d is specified dont prompt, just configure with defaults
289     if '-d' in argv:
290         save_config(defaults, config_file)
291         results = defaults
292     else:        
293         results = mainloop (defaults, config_file)
294     setup_server_key(results)
295     return 0
296
297 if __name__ == '__main__':
298     main()