Install default configuration files
[cascardo/ipsilon.git] / ipsilon / install / server.py
1 #!/usr/bin/python
2 #
3 # Copyright (C) 2014  Simo Sorce <simo@redhat.com>
4 #
5 # see file 'COPYING' for use and warranty information
6 #
7 # This program is free software; you can redistribute it and/or modify
8 # it under the terms of the GNU General Public License as published by
9 # the Free Software Foundation, either version 3 of the License, or
10 # (at your option) any later version.
11 #
12 # This program is distributed in the hope that it will be useful,
13 # but WITHOUT ANY WARRANTY; without even the implied warranty of
14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 # GNU General Public License for more details.
16 #
17 # You should have received a copy of the GNU General Public License
18 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
19
20 from ipsilon.login.common import LoginMgrsInstall
21 from ipsilon.providers.common import ProvidersInstall
22 import argparse
23 import logging
24 import os
25 import shutil
26 import sys
27 import time
28
29
30 TEMPLATES = '/usr/share/ipsilon/templates/install'
31 CONFDIR = '/etc/ipsilon'
32 HTTPDCONFD = '/etc/httpd/conf.d'
33
34
35 class ConfigurationError(Exception):
36
37     def __init__(self, message):
38         super(ConfigurationError, self).__init__(message)
39         self.message = message
40
41     def __str__(self):
42         return repr(self.message)
43
44
45 LOGFILE = '/var/log/ipsilon-install.log'
46 logger = logging.getLogger()
47
48
49 def openlogs():
50     global logger  # pylint: disable=W0603
51     if os.path.isfile(LOGFILE):
52         try:
53             created = '%s' % time.ctime(os.path.getctime(LOGFILE))
54             shutil.move(LOGFILE, '%s.%s' % (LOGFILE, created))
55         except IOError:
56             pass
57     logger = logging.getLogger()
58     try:
59         lh = logging.FileHandler(LOGFILE)
60     except IOError, e:
61         print >> sys.stderr, 'Unable to open %s (%s)' % (LOGFILE, str(e))
62         lh = logging.StreamHandler(sys.stderr)
63     formatter = logging.Formatter('[%(asctime)s] %(message)s')
64     lh.setFormatter(formatter)
65     logger.addHandler(lh)
66
67
68 def install(plugins, args):
69     logger.info('Installation initiated')
70     now = time.strftime("%Y%m%d%H%M%S", time.gmtime())
71
72     logger.info('Installing default config files')
73     ipsilon_conf = os.path.join(CONFDIR, 'ipsilon.conf')
74     idp_conf = os.path.join(CONFDIR, 'idp.conf')
75     httpd_conf = os.path.join(HTTPDCONFD, 'idp.conf')
76     if os.path.exists(ipsilon_conf):
77         shutil.move(ipsilon_conf, '%s.bakcup.%s' % (ipsilon_conf, now))
78     if os.path.exists(idp_conf):
79         shutil.move(idp_conf, '%s.backup.%s' % (idp_conf, now))
80     shutil.copy(os.path.join(TEMPLATES, 'ipsilon.conf'), CONFDIR)
81     shutil.copy(os.path.join(TEMPLATES, 'idp.conf'), CONFDIR)
82     if not os.path.exists(httpd_conf):
83         os.symlink(idp_conf, httpd_conf)
84     # Load the cherrypy config from the newly installed file so
85     # that db paths and all is properly set before configuring
86     # components
87     cherrypy.config.update(ipsilon_conf)
88
89     # Move pre-existing admin db away
90     admin_db = cherrypy.config['admin.config.db']
91     if os.path.exists(admin_db):
92         shutil.move(admin_db, '%s.backup.%s' % (admin_db, now))
93
94     logger.info('Configuring login managers')
95     for plugin_name in args['lm_order']:
96         plugin = plugins['Login Managers'][plugin_name]
97         plugin.configure(args)
98
99     logger.info('Configuring Authentication Providers')
100     for plugin_name in plugins['Auth Providers']:
101         plugin = plugins['Auth Providers'][plugin_name]
102         plugin.configure(args)
103
104
105 def uninstall(plugins, args):
106     logger.info('Uninstallation initiated')
107     raise Exception('Not Implemented')
108
109
110 def find_plugins():
111     plugins = {
112         'Login Managers': LoginMgrsInstall().plugins,
113         'Auth Providers': ProvidersInstall().plugins
114     }
115     return plugins
116
117
118 def parse_args(plugins):
119     parser = argparse.ArgumentParser(description='Ipsilon Install Options')
120     parser.add_argument('--version',
121                         action='version', version='%(prog)s 0.1')
122     parser.add_argument('-o', '--login-managers-order', dest='lm_order',
123                         help='Comma separated list of login managers')
124     parser.add_argument('--ipa', choices=['yes', 'no'], default='yes',
125                         help='Detect and use an IPA server for authentication')
126     parser.add_argument('--uninstall', action='store_true',
127                         help="Uninstall the server and all data")
128
129     lms = []
130
131     for plugin_group in plugins:
132         group = parser.add_argument_group(plugin_group)
133         for plugin_name in plugins[plugin_group]:
134             plugin = plugins[plugin_group][plugin_name]
135             if plugin.ptype == 'login':
136                 lms.append(plugin.name)
137             plugin.install_args(group)
138
139     args = vars(parser.parse_args())
140
141     if args['lm_order'] is None:
142         args['lm_order'] = []
143         for name in lms:
144             if args[name] == 'yes':
145                 args['lm_order'].append(name)
146     else:
147         args['lm_order'] = args['lm_order'].split(',')
148
149     if len(args['lm_order']) == 0:
150         #force the basic pam provider if nothing else is selected
151         if 'pam' not in args:
152             parser.print_help()
153             sys.exit(-1)
154         args['lm_order'] = ['pam']
155         args['pam'] = 'yes'
156
157     return args
158
159 if __name__ == '__main__':
160     opts = []
161     out = 0
162     openlogs()
163     try:
164         fplugins = find_plugins()
165         opts = parse_args(fplugins)
166
167         logger.setLevel(logging.DEBUG)
168
169         logger.info('Intallation arguments:')
170         for k in sorted(opts.iterkeys()):
171             logger.info('%s: %s', k, opts[k])
172
173         if 'uninstall' in opts and opts['uninstall'] is True:
174             uninstall(fplugins, opts)
175
176         install(fplugins, opts)
177     except Exception, e:  # pylint: disable=broad-except
178         logger.exception(e)
179         if 'uninstall' in opts and opts['uninstall'] is True:
180             print 'Uninstallation aborted.'
181         else:
182             print 'Installation aborted.'
183         print 'See log file %s for details' % LOGFILE
184         out = 1
185     finally:
186         if out == 0:
187             if 'uninstall' in opts and opts['uninstall'] is True:
188                 print 'Uninstallation complete.'
189             else:
190                 print 'Installation complete.'
191     sys.exit(out)