- allow update of default login_base
[myplc.git] / db-config
1 #!/usr/bin/env /usr/bin/plcsh
2 #
3 # Bootstraps the PLC database with a default administrator account and
4 # a default site, defines default slice attribute types, and
5 # creates/updates default system slices.
6 #
7 # Mark Huang <mlhuang@cs.princeton.edu>
8 # Copyright (C) 2006 The Trustees of Princeton University
9 #
10 # $Id: db-config,v 1.4 2006/11/08 23:34:28 mlhuang Exp $
11 #
12
13 from plc_config import PLCConfiguration
14 import sys
15
16 def main():
17     cfg = PLCConfiguration()
18     cfg.load()
19     variables = cfg.variables()
20
21     # Load variables into dictionaries
22     for category_id, (category, variablelist) in variables.iteritems():
23         globals()[category_id] = dict(zip(variablelist.keys(),
24                                        [variable['value'] for variable in variablelist.values()]))
25
26     # Create/update the default administrator account (should be
27     # person_id 2).
28     admin = { 'person_id': 2,
29               'first_name': "Default",
30               'last_name': "Administrator",
31               'email': plc['root_user'],
32               'password': plc['root_password'] }
33     persons = GetPersons([admin['person_id']])
34     if not persons:
35         person_id = AddPerson(admin)
36         if person_id != admin['person_id']:
37             # Huh? Someone deleted the account manually from the database.
38             DeletePerson(person_id)
39             raise Exception, "Someone deleted the \"%s %s\" account from the database!" % \
40                   (admin['first_name'], admin['last_name'])
41         UpdatePerson(person_id, { 'enabled': True })
42     else:
43         person_id = persons[0]['person_id']
44         UpdatePerson(person_id, admin)
45
46     # Create/update the default site (should be site_id 1)
47     if plc_www['port'] == '80':
48         url = "http://" + plc_www['host'] + "/"
49     elif plc_www['port'] == '443':
50         url = "https://" + plc_www['host'] + "/"
51     else:
52         url = "http://" + plc_www['host'] + ":" + plc_www['port'] + "/"
53     site = { 'site_id': 1,
54              'name': plc['name'] + " Central",
55              'abbreviated_name': plc['name'],
56              'login_base': plc['slice_prefix'],
57              'is_public': False,
58              'url': url,
59              'max_slices': 100 }
60
61     sites = GetSites([site['site_id']])
62     if not sites:
63         site_id = AddSite(site['name'], site['abbreviated_name'], site['login_base'], site)
64         if site_id != site['site_id']:
65             DeleteSite(site_id)
66             raise Exception, "Someone deleted the \"%s\" site from the database!" % \
67                   site['name']
68         sites = [site]
69
70     # Must call UpdateSite() even after AddSite() to update max_slices
71     site_id = sites[0]['site_id']
72     UpdateSite(site_id, site)
73
74     # The default administrator account must be associated with a site
75     # in order to login.
76     AddPersonToSite(admin['person_id'], site['site_id'])
77     SetPersonPrimarySite(admin['person_id'], site['site_id'])
78
79     # Grant admin and PI roles to the default administrator account
80     AddRoleToPerson(10, admin['person_id'])
81     AddRoleToPerson(20, admin['person_id'])
82
83     # Setup default PlanetLabConf entries
84     default_conf_files = [
85         # NTP configuration
86         {'enabled': True,
87          'source': 'PlanetLabConf/ntp.conf.php',
88          'dest': '/etc/ntp.conf',
89          'file_permissions': '644',
90          'file_owner': 'root',
91          'file_group': 'root',
92          'preinstall_cmd': '',
93          'postinstall_cmd': '/etc/rc.d/init.d/ntpd restart',
94          'error_cmd': '',
95          'ignore_cmd_errors': False,
96          'always_update': False},
97         {'enabled': True,
98          'source': 'PlanetLabConf/ntp/step-tickers.php',
99          'dest': '/etc/ntp/step-tickers',
100          'file_permissions': '644',
101          'file_owner': 'root',
102          'file_group': 'root',
103          'preinstall_cmd': '',
104          'postinstall_cmd': '/etc/rc.d/init.d/ntpd restart',
105          'error_cmd': '',
106          'ignore_cmd_errors': False,
107          'always_update': False},
108
109         # SSH server configuration
110         {'enabled': True,
111          'source': 'PlanetLabConf/sshd_config',
112          'dest': '/etc/ssh/sshd_config',
113          'file_permissions': '600',
114          'file_owner': 'root',
115          'file_group': 'root',
116          'preinstall_cmd': '',
117          'postinstall_cmd': '/etc/init.d/sshd restart',
118          'error_cmd': '',
119          'ignore_cmd_errors': False,
120          'always_update': False},
121
122         # Administrative SSH keys
123         {'enabled': True,
124          'source': 'PlanetLabConf/keys.php?root',
125          'dest': '/root/.ssh/authorized_keys',
126          'file_permissions': '644',
127          'file_owner': 'root',
128          'file_group': 'root',
129          'preinstall_cmd': '',
130          'postinstall_cmd': '',
131          'error_cmd': '',
132          'ignore_cmd_errors': False,
133          'always_update': False},
134         {'enabled': True,
135          'source': 'PlanetLabConf/keys.php?site_admin',
136          'dest': '/home/site_admin/.ssh/authorized_keys',
137          'file_permissions': '644',
138          'file_owner': 'site_admin',
139          'file_group': 'site_admin',
140          'preinstall_cmd': 'grep -q site_admin /etc/passwd',
141          'postinstall_cmd': '',
142          'error_cmd': '',
143          'ignore_cmd_errors': False,
144          'always_update': False},
145         {'enabled': True,
146          'source': 'PlanetLabConf/keys.php?role=admin',
147          'dest': '/home/pl_admin/.ssh/authorized_keys',
148          'file_permissions': '644',
149          'file_owner': 'pl_admin',
150          'file_group': 'pl_admin',
151          'preinstall_cmd': 'grep -q pl_admin /etc/passwd',
152          'postinstall_cmd': '',
153          'error_cmd': '',
154          'ignore_cmd_errors': False,
155          'always_update': False},
156
157         # Log rotation configuration
158         {'enabled': True,
159          'source': 'PlanetLabConf/logrotate.conf',
160          'dest': '/etc/logrotate.conf',
161          'file_permissions': '644',
162          'file_owner': 'root',
163          'file_group': 'root',
164          'preinstall_cmd': '',
165          'postinstall_cmd': '',
166          'error_cmd': '',
167          'ignore_cmd_errors': False,
168          'always_update': False},
169
170         # updatedb/locate nightly cron job
171         {'enabled': True,
172          'source': 'PlanetLabConf/slocate.cron',
173          'dest': '/etc/cron.daily/slocate.cron',
174          'file_permissions': '755',
175          'file_owner': 'root',
176          'file_group': 'root',
177          'preinstall_cmd': '',
178          'postinstall_cmd': '',
179          'error_cmd': '',
180          'ignore_cmd_errors': False,
181          'always_update': False},
182
183         # YUM configuration
184         {'enabled': True,
185          'source': 'PlanetLabConf/yum.conf.php?gpgcheck=1',
186          'dest': '/etc/yum.conf',
187          'file_permissions': '644',
188          'file_owner': 'root',
189          'file_group': 'root',
190          'preinstall_cmd': '',
191          'postinstall_cmd': '',
192          'error_cmd': '',
193          'ignore_cmd_errors': False,
194          'always_update': False},
195         {'enabled': True,
196          'source': 'PlanetLabConf/delete-rpm-list-production',
197          'dest': '/etc/planetlab/delete-rpm-list',
198          'file_permissions': '644',
199          'file_owner': 'root',
200          'file_group': 'root',
201          'preinstall_cmd': '',
202          'postinstall_cmd': '',
203          'error_cmd': '',
204          'ignore_cmd_errors': False,
205          'always_update': False},
206
207         # PLC configuration
208         {'enabled': True,
209          'source': 'PlanetLabConf/get_plc_config.php',
210          'dest': '/etc/planetlab/plc_config',
211          'file_permissions': '644',
212          'file_owner': 'root',
213          'file_group': 'root',
214          'preinstall_cmd': '',
215          'postinstall_cmd': '',
216          'error_cmd': '',
217          'ignore_cmd_errors': False,
218          'always_update': False},
219         {'enabled': True,
220          'source': 'PlanetLabConf/get_plc_config.php?python',
221          'dest': '/etc/planetlab/plc_config.py',
222          'file_permissions': '644',
223          'file_owner': 'root',
224          'file_group': 'root',
225          'preinstall_cmd': '',
226          'postinstall_cmd': '',
227          'error_cmd': '',
228          'ignore_cmd_errors': False,
229          'always_update': False},
230         {'enabled': True,
231          'source': 'PlanetLabConf/get_plc_config.php?perl',
232          'dest': '/etc/planetlab/plc_config.pl',
233          'file_permissions': '644',
234          'file_owner': 'root',
235          'file_group': 'root',
236          'preinstall_cmd': '',
237          'postinstall_cmd': '',
238          'error_cmd': '',
239          'ignore_cmd_errors': False,
240          'always_update': False},
241         {'enabled': True,
242          'source': 'PlanetLabConf/get_plc_config.php?php',
243          'dest': '/etc/planetlab/php/plc_config.php',
244          'file_permissions': '644',
245          'file_owner': 'root',
246          'file_group': 'root',
247          'preinstall_cmd': '',
248          'postinstall_cmd': '',
249          'error_cmd': '',
250          'ignore_cmd_errors': False,
251          'always_update': False},
252
253         # Proper configuration
254         {'enabled': True,
255          'source': 'PlanetLabConf/propd.conf',
256          'dest': '/etc/proper/propd.conf',
257          'file_permissions': '644',
258          'file_owner': 'root',
259          'file_group': 'root',
260          'preinstall_cmd': '',
261          'postinstall_cmd': '/etc/init.d/proper restart',
262          'error_cmd': '',
263          'ignore_cmd_errors': True,
264          'always_update': False},
265
266         # Proxy ARP setup
267         {'enabled': True,
268          'source': 'PlanetLabConf/proxies.php',
269          'dest': '/etc/planetlab/proxies',
270          'file_permissions': '644',
271          'file_owner': 'root',
272          'file_group': 'root',
273          'preinstall_cmd': '',
274          'postinstall_cmd': '',
275          'error_cmd': '',
276          'ignore_cmd_errors': False,
277          'always_update': False},
278
279         # Firewall configuration
280         {'enabled': True,
281          'source': 'PlanetLabConf/iptables',
282          'dest': '/etc/sysconfig/iptables',
283          'file_permissions': '600',
284          'file_owner': 'root',
285          'file_group': 'root',
286          'preinstall_cmd': '',
287          'postinstall_cmd': '',
288          'error_cmd': '',
289          'ignore_cmd_errors': False,
290          'always_update': False},
291         {'enabled': True,
292          'source': 'PlanetLabConf/blacklist.php',
293          'dest': '/etc/planetlab/blacklist',
294          'file_permissions': '600',
295          'file_owner': 'root',
296          'file_group': 'root',
297          'preinstall_cmd': '',
298          'postinstall_cmd': '/sbin/iptables-restore --noflush < /etc/planetlab/blacklist',
299          'error_cmd': '',
300          'ignore_cmd_errors': True,
301          'always_update': True},
302
303         # /etc/issue
304         {'enabled': True,
305          'source': 'PlanetLabConf/issue.php',
306          'dest': '/etc/issue',
307          'file_permissions': '644',
308          'file_owner': 'root',
309          'file_group': 'root',
310          'preinstall_cmd': '',
311          'postinstall_cmd': '',
312          'error_cmd': '',
313          'ignore_cmd_errors': False,
314          'always_update': False},
315
316         # Kernel parameters
317         {'enabled': True,
318          'source': 'PlanetLabConf/sysctl.php',
319          'dest': '/etc/sysctl.conf',
320          'file_permissions': '644',
321          'file_owner': 'root',
322          'file_group': 'root',
323          'preinstall_cmd': '',
324          'postinstall_cmd': '/sbin/sysctl -e -p /etc/sysctl.conf',
325          'error_cmd': '',
326          'ignore_cmd_errors': False,
327          'always_update': True},
328
329         # Sendmail configuration
330         {'enabled': True,
331          'source': 'PlanetLabConf/sendmail.mc',
332          'dest': '/etc/mail/sendmail.mc',
333          'file_permissions': '644',
334          'file_owner': 'root',
335          'file_group': 'root',
336          'preinstall_cmd': '',
337          'postinstall_cmd': '',
338          'error_cmd': '',
339          'ignore_cmd_errors': False,
340          'always_update': False},
341         {'enabled': True,
342          'source': 'PlanetLabConf/sendmail.cf',
343          'dest': '/etc/mail/sendmail.cf',
344          'file_permissions': '644',
345          'file_owner': 'root',
346          'file_group': 'root',
347          'preinstall_cmd': '',
348          'postinstall_cmd': 'service sendmail restart',
349          'error_cmd': '',
350          'ignore_cmd_errors': False,
351          'always_update': False},
352
353         # GPG signing keys
354         {'enabled': True,
355          'source': 'PlanetLabConf/RPM-GPG-KEY-fedora',
356          'dest': '/etc/pki/rpm-gpg/RPM-GPG-KEY-fedora',
357          'file_permissions': '644',
358          'file_owner': 'root',
359          'file_group': 'root',
360          'preinstall_cmd': '',
361          'postinstall_cmd': 'rpm --import /etc/pki/rpm-gpg/RPM-GPG-KEY-fedora',
362          'error_cmd': '',
363          'ignore_cmd_errors': False,
364          'always_update': False},
365         {'enabled': True,
366          'source': 'PlanetLabConf/get_gpg_key.php',
367          'dest': '/etc/pki/rpm-gpg/RPM-GPG-KEY-planetlab',
368          'file_permissions': '644',
369          'file_owner': 'root',
370          'file_group': 'root',
371          'preinstall_cmd': '',
372          'postinstall_cmd': 'rpm --import /etc/pki/rpm-gpg/RPM-GPG-KEY-planetlab',
373          'error_cmd': '',
374          'ignore_cmd_errors': False,
375          'always_update': False},
376
377         # Ping of death configuration
378         {'enabled': True,
379          'source': 'PlanetLabConf/ipod.conf.php',
380          'dest': '/etc/ipod.conf',
381          'file_permissions': '644',
382          'file_owner': 'root',
383          'file_group': 'root',
384          'preinstall_cmd': '',
385          'postinstall_cmd': '',
386          'error_cmd': '',
387          'ignore_cmd_errors': False,
388          'always_update': False},
389
390         # sudo configuration
391         {'enabled': True,
392          'source': 'PlanetLabConf/sudoers',
393          'dest': '/etc/sudoers',
394          'file_permissions': '440',
395          'file_owner': 'root',
396          'file_group': 'root',
397          'preinstall_cmd': '',
398          'postinstall_cmd': '/usr/sbin/visudo -c',
399          'error_cmd': '',
400          'ignore_cmd_errors': False,
401          'always_update': False}
402         ]
403
404     # Get list of existing (enabled, global) files
405     conf_files = GetConfFiles()
406     conf_files = filter(lambda conf_file: conf_file['enabled'] and \
407                                           not conf_file['node_ids'] and \
408                                           not conf_file['nodegroup_ids'],
409                         conf_files)
410     dests = [conf_file['dest'] for conf_file in conf_files]
411     conf_files = dict(zip(dests, conf_files))
412
413     # Create/update default PlanetLabConf entries
414     for default_conf_file in default_conf_files:
415         if default_conf_file['dest'] not in dests:
416             AddConfFile(default_conf_file)
417         else:
418             conf_file = conf_files[default_conf_file['dest']]
419             UpdateConfFile(conf_file['conf_file_id'], default_conf_file)
420
421     # Setup default slice attribute types
422     default_attribute_types = [
423         # Slice type (only vserver is supported)
424         {'name': "type",
425          'description': "Type of slice (e.g. vserver)",
426          'min_role_id': 20},
427
428         # Slice enabled (1) or suspended (0)
429         {'name': "enabled",
430          'description': "Slice enabled (1) or suspended (0)",
431          'min_role_id': 10},
432
433         # Slice reference image
434         {'name': "vref",
435          'description': "Reference image",
436          'min_role_id': 30},
437
438         # Slice initialization script
439         {'name': "initscript",
440          'description': "Slice initialization script",
441          'min_role_id': 10},
442
443         # CPU share
444         {'name': "cpu_min",
445          'description': "Minimum CPU share (ms/s)",
446          'min_role_id': 10},
447         {'name': "cpu_share",
448          'description': "Number of CPU shares",
449          'min_role_id': 10},
450
451         # Bandwidth limits
452         {'name': "net_min",
453          'description': "Minimum bandwidth (bps)",
454          'min_role_id': 10},
455         {'name': "net_max",
456          'description': "Maximum bandwidth (bps)",
457          'min_role_id': 10},
458         {'name': "net_avg",
459          'description': "Average bandwidth (bps)",
460          'min_role_id': 10},
461         {'name': "net_share",
462          'description': "Number of bandwidth shares",
463          'min_role_id': 10},
464         {'name': "net2_min",
465          'description': "Minimum bandwidth over routes exempt from node bandwidth limits (bps)",
466          'min_role_id': 10},
467         {'name': "net2_max",
468          'description': "Maximum bandwidth over routes exempt from node bandwidth limits (bps)",
469          'min_role_id': 10},
470         {'name': "net2_avg",
471          'description': "Average bandwidth over routes exempt from node bandwidth limits (bps)",
472          'min_role_id': 10},
473         {'name': "net2_share",
474          'description': "Number of bandwidth shares over routes exempt from node bandwidth limits",
475          'min_role_id': 10},
476
477         # Disk quota
478         {'name': "disk_max",
479          'description': "Disk quota (bytes)",
480          'min_role_id': 10},
481         ]
482
483     # Get list of existing attribute types
484     attribute_types = GetSliceAttributeTypes()
485     attribute_types = [attribute_type['name'] for attribute_type in attribute_types]
486
487     # Create/update default slice attribute types
488     for default_attribute_type in default_attribute_types:
489         if default_attribute_type['name'] not in attribute_types:
490             AddSliceAttributeType(default_attribute_type)
491         else:
492             UpdateSliceAttributeType(default_attribute_type['name'], default_attribute_type)
493
494     # Create/update system slices
495     default_slices = [
496         {'name': plc['slice_prefix'] + "_netflow",
497          'description': "PlanetFlow Traffic Auditing Service",
498          'instantiation': "plc-instantiated",
499          # Renew forever
500          'expires': sys.maxint,
501          'attributes': {'reference': "planetflow"}},
502         ]
503
504     for default_slice in default_slices:
505         slices = GetSlices([default_slice['name']])
506         if slices:
507             slice = slices[0]
508             UpdateSlice(slice['slice_id'], default_slice)
509         else:
510             AddSlice(default_slice)
511             slice = GetSlices([default_slice['name']])[0]
512
513         # Create/update all attributes
514         slice_attributes = {}
515         if slice['slice_attribute_ids']:
516             for slice_attribute in GetSliceAttributes(slice['slice_attribute_ids']):
517                 slice_attributes[slice_attribute['name']] = slice_attribute
518
519         for name, value in default_slice['attributes'].iteritems():
520             if name not in slice_attributes:
521                 AddSliceAttribute(slice['name'], name, value)
522             else:
523                 UpdateSliceAttribute(slice_attributes[name]['slice_attribute_id'], value)
524
525 if __name__ == '__main__':
526     main()
527
528 # Local variables:
529 # tab-width: 4
530 # mode: python
531 # End: