Allow to configure SSL authnetication backend.
[slapos.git] / slapos / recipe / generate_erp5_tidstorage.py
1 ##############################################################################
2 #
3 # Copyright (c) 2011 Vifib SARL and Contributors. All Rights Reserved.
4 #
5 # WARNING: This program as such is intended to be used by professional
6 # programmers who take the whole responsibility of assessing all potential
7 # consequences resulting from its eventual inadequacies and bugs
8 # End users who are looking for a ready-to-use solution with commercial
9 # guarantees and support are strongly adviced to contract a Free Software
10 # Service Company
11 #
12 # This program is Free Software; you can redistribute it and/or
13 # modify it under the terms of the GNU General Public License
14 # as published by the Free Software Foundation; either version 3
15 # of the License, or (at your option) any later version.
16 #
17 # This program is distributed in the hope that it will be useful,
18 # but WITHOUT ANY WARRANTY; without even the implied warranty of
19 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 # GNU General Public License for more details.
21 #
22 # You should have received a copy of the GNU General Public License
23 # along with this program; if not, write to the Free Software
24 # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
25 #
26 ##############################################################################
27 from slapos.recipe.librecipe import GenericSlapRecipe
28 import os
29 import json
30 import traceback
31
32 SECTION_BACKEND_PUBLISHER = """[publish-apache-backend-list]
33 recipe = slapos.cookbook:publish"""
34 ZOPE_PORT_BASE = 12000
35 ZEO_PORT_BASE = 15000
36 HAPROXY_PORT_BASE = 11000
37 APACHE_PORT_BASE = 10000
38
39 class Recipe(GenericSlapRecipe):
40 def _options(self, options):
41 self.dirname = os.path.join(self.buildout['buildout']['parts-directory'],
42 self.name)
43 options['output'] = os.path.join(self.dirname, self.name + '.cfg')
44
45 def _generateRealTemplate(self):
46 current_zeo_port = ZEO_PORT_BASE
47 current_zope_port = ZOPE_PORT_BASE
48 current_apache_port = APACHE_PORT_BASE
49 current_haproxy_port = HAPROXY_PORT_BASE
50 json_data = json.loads(self.parameter_dict['json'])
51 site_id = str(json_data['site-id'])
52 # prepare zeo
53 output = ''
54 part_list = []
55 zope_dict = {}
56 zope_connection_dict = {}
57 known_tid_storage_identifier_dict = {}
58 snippet_zeo = open(self.options['snippet-zeo']).read()
59 for zeo_id, zeo_configuration_list in json_data['zeo'].iteritems():
60 if not type(zeo_configuration_list) in (type([]), type(set()), type(())):
61 raise ValueError('%s passed in json is not a list, json: %s.' % (
62 zeo_configuration_list, json_data))
63 storage_list = []
64 a = storage_list.append
65 for zeo_slave in zeo_configuration_list:
66 zope_connection_dict[zeo_slave['storage-name']] = {
67 'zope-cache-size': zeo_slave['zope-cache-size'],
68 'zeo-cache-size': zeo_slave['zeo-cache-size'],
69 'mount-point': zeo_slave['mount-point'] % {'site-id': site_id},
70 'storage-name': zeo_slave['storage-name'],
71 'server': '${zeo-instance-%(zeo-id)s:ip}:${zeo-instance-%(zeo-id)s:port}' % {'zeo-id': zeo_id}
72 }
73 zodb_path = os.path.join('${directory:zodb}', zeo_slave['storage-name'] + '.fs')
74 a(' storage-name=%(storage-name)s zodb-path=%(zodb-path)s' % {'zodb-path': zodb_path, 'storage-name': zeo_slave['storage-name']})
75 known_tid_storage_identifier_dict[
76 "((('%(ip)s', %(port)s),), '%(storage_name)s')" % dict(
77 ip='${zeo-instance-%s:ip}' % zeo_id,
78 port='${zeo-instance-%s:port}' % zeo_id,
79 storage_name=zeo_slave['storage-name'])] = (zodb_path, '${directory:zodb-backup}/%s/' % zeo_slave['storage-name'], zeo_slave['serialize-path'] % {'site-id': site_id})
80 current_zeo_port += 1
81 output += snippet_zeo % dict(
82 zeo_id=zeo_id,
83 zeo_port=current_zeo_port,
84 storage_list='\n'.join(storage_list)
85 )
86 part_list.extend([
87 "zeo-instance-%s" % zeo_id,
88 "logrotate-entry-zeo-%s" % zeo_id
89 ])
90
91 zeo_connection_list = []
92 a = zeo_connection_list.append
93 for k, v in zope_connection_dict.iteritems():
94 a(' zeo-cache-size=%(zeo-cache-size)s zope-cache-size=%(zope-cache-size)s server=%(server)s mount-point=%(mount-point)s storage-name=%(storage-name)s' % v)
95 zeo_connection_string = '\n'.join(zeo_connection_list)
96 zope_dict.update(
97 timezone=json_data['timezone'],
98 zeo_connection_string=zeo_connection_string
99 )
100 # always one distribution node
101 current_zope_port += 1
102 snippet_zope = open(self.options['snippet-zope']).read()
103 zope_id = 'zope-distribution'
104 part_list.append(zope_id)
105 part_list.append('logrotate-entry-%s' % zope_id)
106 output += snippet_zope % dict(zope_thread_amount=1, zope_id=zope_id,
107 zope_port=current_zope_port, zope_timeserver=True,
108 longrequest_logger_file='', longrequest_logger_timeout='',
109 longrequest_logger_interval='', **zope_dict)
110 # always one admin node
111 current_zope_port += 1
112 zope_id = 'zope-admin'
113 part_list.append(zope_id)
114 part_list.append('logrotate-entry-%s' % zope_id)
115 output += snippet_zope % dict(zope_thread_amount=1, zope_id=zope_id,
116 zope_port=current_zope_port, zope_timeserver=False,
117 longrequest_logger_file='', longrequest_logger_timeout='',
118 longrequest_logger_interval='', **zope_dict)
119 # handle activity key
120 for q in range(1, json_data['activity']['zopecount'] + 1):
121 current_zope_port += 1
122 part_name = 'zope-activity-%s' % q
123 part_list.append(part_name)
124 part_list.append('logrotate-entry-%s' % part_name)
125 output += snippet_zope % dict(zope_thread_amount=1, zope_id=part_name,
126 zope_port=current_zope_port, zope_timeserver=True,
127 longrequest_logger_file='', longrequest_logger_timeout='',
128 longrequest_logger_interval='', **zope_dict)
129 # handle backend key
130 snippet_backend = open(self.options['snippet-backend']).read()
131 publish_url_list = []
132 for backend_name, backend_configuration in json_data['backend'].iteritems():
133 haproxy_backend_list = []
134 for q in range(1, backend_configuration['zopecount'] + 1):
135 current_zope_port += 1
136 part_name = 'zope-%s-%s' % (backend_name, q)
137 part_list.append(part_name)
138 part_list.append('logrotate-entry-%s' % part_name)
139 longrequest_logger = backend_configuration.get("longrequest-logger", None)
140 if longrequest_logger is not None:
141 longrequest_part_name = '%s-longrequest' %part_name
142 longrequest_logger_file = '${basedirectory:log}/%s.log' \
143 %longrequest_part_name
144 longrequest_logger_timeout = longrequest_logger.get('timeout', '4')
145 longrequest_logger_interval = longrequest_logger.get('interval', '2')
146 else:
147 longrequest_logger_file = longrequest_logger_timeout = \
148 longrequest_logger_interval = ''
149 output += snippet_zope % dict(
150 zope_thread_amount=backend_configuration['thread-amount'],
151 zope_id=part_name, zope_port=current_zope_port, zope_timeserver=False,
152 longrequest_logger_file=longrequest_logger_file,
153 longrequest_logger_timeout=longrequest_logger_timeout,
154 longrequest_logger_interval=longrequest_logger_interval,
155 **zope_dict)
156 haproxy_backend_list.append('${%(part_name)s:ip}:${%(part_name)s:port}' % dict(part_name=part_name))
157
158 scheme = backend_configuration.get('scheme', ['https'])
159
160 # now generate backend access
161 current_apache_port += 1
162 current_haproxy_port += 1
163 backend_dict = dict(
164 backend_name=backend_name,
165 apache_port=current_apache_port,
166 apache_public_port=current_apache_port+1,
167 haproxy_port=current_haproxy_port,
168 access_control_string=backend_configuration['access-control-string'],
169 maxconn=backend_configuration['maxconn'],
170 server_check_path='/%s/getId' % site_id,
171 haproxy_backend_list=' '.join(haproxy_backend_list),
172 ssl_authentication=backend_configuration.get('ssl-authentication',
173 False)
174 )
175 current_apache_port += 1
176 output += snippet_backend % backend_dict
177
178 if 'http' in scheme:
179 part_list.append('apache-public-%(backend_name)s logrotate-entry-apache-public-%(backend_name)s' % dict(backend_name=backend_name))
180 publish_url_list.append('url-public-%(backend_name)s = http://[${apache-public-%(backend_name)s:ip}]:${apache-public-%(backend_name)s:port}' % dict(
181 backend_name=backend_name))
182 if 'https' in scheme:
183 part_list.append('apache-%(backend_name)s ca-apache-%(backend_name)s logrotate-entry-apache-%(backend_name)s haproxy-%(backend_name)s' % dict(backend_name=backend_name))
184 publish_url_list.append('url-%(backend_name)s = https://[${apache-%(backend_name)s:ip}]:${apache-%(backend_name)s:port}' % dict(
185 backend_name=backend_name))
186
187 output += SECTION_BACKEND_PUBLISHER + '\n'
188 output += '\n'.join(publish_url_list)
189 part_list.append('publish-apache-backend-list')
190 prepend = open(self.options['snippet-master']).read() % dict(
191 part_list=' \n'.join([' '+q for q in part_list]),
192 known_tid_storage_identifier_dict=known_tid_storage_identifier_dict,
193 haproxy_section="haproxy-%s" % backend_name,
194 zope_section=zope_id,
195 site_id=site_id,
196 **self.parameter_dict
197 )
198 output = prepend + output
199 with open(self.options['output'], 'w') as f:
200 f.write(output)
201
202 def _install(self):
203 if not os.path.exists(self.dirname):
204 os.mkdir(self.dirname)
205 if not "json" in self.parameter_dict:
206 # no json transimtted, nothing to do
207 with open(self.options['output'], 'w') as f:
208 f.write("[buildout]\nparts =\n")
209 else:
210 try:
211 self._generateRealTemplate()
212 except Exception:
213 print 'Ignored issue during template generation:\n%s' % \
214 traceback.format_exc()
215 return [self.dirname]