- fix .ssh directory permissions
[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$
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': '/bin/chmod 700 /root/.ssh',
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': '/bin/chmod 700 /home/site_admin/.ssh',
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': '/bin/chmod 700 /home/pl_admin/.ssh',
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         # Node Manager configuration
254         {'enabled': True,
255          'source': 'PlanetLabConf/pl_nm.conf',
256          'dest': '/etc/planetlab/pl_nm.conf',
257          'file_permissions': '644',
258          'file_owner': 'root',
259          'file_group': 'root',
260          'preinstall_cmd': '',
261          'postinstall_cmd': '/etc/init.d/pl_nm restart',
262          'error_cmd': '',
263          'ignore_cmd_errors': False,
264          'always_update': False},
265         {'enabled': True,
266          'source': 'PlanetLabConf/RootResources/plc_slice_pool.php',
267          'dest': '/home/pl_nm/RootResources/plc_slice_pool',
268          'file_permissions': '644',
269          'file_owner': 'pl_nm',
270          'file_group': 'pl_nm',
271          'preinstall_cmd': '',
272          'postinstall_cmd': '',
273          'error_cmd': '',
274          'ignore_cmd_errors': False,
275          'always_update': False},
276         {'enabled': True,
277          'source': 'PlanetLabConf/RootResources/pl_conf.py',
278          'dest': '/home/pl_nm/RootResources/pl_conf',
279          'file_permissions': '644',
280          'file_owner': 'pl_nm',
281          'file_group': 'pl_nm',
282          'preinstall_cmd': '',
283          'postinstall_cmd': '/etc/init.d/pl_nm restart',
284          'error_cmd': '',
285          'ignore_cmd_errors': False,
286          'always_update': False},
287         {'enabled': True,
288          'source': 'PlanetLabConf/RootResources/pl_netflow.py',
289          'dest': '/home/pl_nm/RootResources/pl_netflow',
290          'file_permissions': '644',
291          'file_owner': 'pl_nm',
292          'file_group': 'pl_nm',
293          'preinstall_cmd': '',
294          'postinstall_cmd': '',
295          'error_cmd': '',
296          'ignore_cmd_errors': False,
297          'always_update': False},
298
299         # Proper configuration
300         {'enabled': True,
301          'source': 'PlanetLabConf/propd.conf',
302          'dest': '/etc/proper/propd.conf',
303          'file_permissions': '644',
304          'file_owner': 'root',
305          'file_group': 'root',
306          'preinstall_cmd': '',
307          'postinstall_cmd': '/etc/init.d/proper restart',
308          'error_cmd': '',
309          'ignore_cmd_errors': True,
310          'always_update': False},
311
312         # Bandwidth cap
313         {'enabled': True,
314          'source': 'PlanetLabConf/bwlimit.php',
315          'dest': '/etc/planetlab/bwcap',
316          'file_permissions': '644',
317          'file_owner': 'root',
318          'file_group': 'root',
319          'preinstall_cmd': '',
320          'postinstall_cmd': '/etc/init.d/pl_nm restart',
321          'error_cmd': '',
322          'ignore_cmd_errors': True,
323          'always_update': False},
324
325         # Proxy ARP setup
326         {'enabled': True,
327          'source': 'PlanetLabConf/proxies.php',
328          'dest': '/etc/planetlab/proxies',
329          'file_permissions': '644',
330          'file_owner': 'root',
331          'file_group': 'root',
332          'preinstall_cmd': '',
333          'postinstall_cmd': '',
334          'error_cmd': '',
335          'ignore_cmd_errors': False,
336          'always_update': False},
337
338         # Firewall configuration
339         {'enabled': True,
340          'source': 'PlanetLabConf/iptables',
341          'dest': '/etc/sysconfig/iptables',
342          'file_permissions': '600',
343          'file_owner': 'root',
344          'file_group': 'root',
345          'preinstall_cmd': '',
346          'postinstall_cmd': '',
347          'error_cmd': '',
348          'ignore_cmd_errors': False,
349          'always_update': False},
350         {'enabled': True,
351          'source': 'PlanetLabConf/blacklist.php',
352          'dest': '/etc/planetlab/blacklist',
353          'file_permissions': '600',
354          'file_owner': 'root',
355          'file_group': 'root',
356          'preinstall_cmd': '',
357          'postinstall_cmd': '/sbin/iptables-restore --noflush < /etc/planetlab/blacklist',
358          'error_cmd': '',
359          'ignore_cmd_errors': True,
360          'always_update': True},
361
362         # /etc/issue
363         {'enabled': True,
364          'source': 'PlanetLabConf/issue.php',
365          'dest': '/etc/issue',
366          'file_permissions': '644',
367          'file_owner': 'root',
368          'file_group': 'root',
369          'preinstall_cmd': '',
370          'postinstall_cmd': '',
371          'error_cmd': '',
372          'ignore_cmd_errors': False,
373          'always_update': False},
374
375         # Kernel parameters
376         {'enabled': True,
377          'source': 'PlanetLabConf/sysctl.php',
378          'dest': '/etc/sysctl.conf',
379          'file_permissions': '644',
380          'file_owner': 'root',
381          'file_group': 'root',
382          'preinstall_cmd': '',
383          'postinstall_cmd': '/sbin/sysctl -e -p /etc/sysctl.conf',
384          'error_cmd': '',
385          'ignore_cmd_errors': False,
386          'always_update': True},
387
388         # Sendmail configuration
389         {'enabled': True,
390          'source': 'PlanetLabConf/sendmail.mc',
391          'dest': '/etc/mail/sendmail.mc',
392          'file_permissions': '644',
393          'file_owner': 'root',
394          'file_group': 'root',
395          'preinstall_cmd': '',
396          'postinstall_cmd': '',
397          'error_cmd': '',
398          'ignore_cmd_errors': False,
399          'always_update': False},
400         {'enabled': True,
401          'source': 'PlanetLabConf/sendmail.cf',
402          'dest': '/etc/mail/sendmail.cf',
403          'file_permissions': '644',
404          'file_owner': 'root',
405          'file_group': 'root',
406          'preinstall_cmd': '',
407          'postinstall_cmd': 'service sendmail restart',
408          'error_cmd': '',
409          'ignore_cmd_errors': False,
410          'always_update': False},
411
412         # GPG signing keys
413         {'enabled': True,
414          'source': 'PlanetLabConf/RPM-GPG-KEY-fedora',
415          'dest': '/etc/pki/rpm-gpg/RPM-GPG-KEY-fedora',
416          'file_permissions': '644',
417          'file_owner': 'root',
418          'file_group': 'root',
419          'preinstall_cmd': '',
420          'postinstall_cmd': 'rpm --import /etc/pki/rpm-gpg/RPM-GPG-KEY-fedora',
421          'error_cmd': '',
422          'ignore_cmd_errors': False,
423          'always_update': False},
424         {'enabled': True,
425          'source': 'PlanetLabConf/get_gpg_key.php',
426          'dest': '/etc/pki/rpm-gpg/RPM-GPG-KEY-planetlab',
427          'file_permissions': '644',
428          'file_owner': 'root',
429          'file_group': 'root',
430          'preinstall_cmd': '',
431          'postinstall_cmd': 'rpm --import /etc/pki/rpm-gpg/RPM-GPG-KEY-planetlab',
432          'error_cmd': '',
433          'ignore_cmd_errors': False,
434          'always_update': False},
435
436         # Ping of death configuration
437         {'enabled': True,
438          'source': 'PlanetLabConf/ipod.conf.php',
439          'dest': '/etc/ipod.conf',
440          'file_permissions': '644',
441          'file_owner': 'root',
442          'file_group': 'root',
443          'preinstall_cmd': '',
444          'postinstall_cmd': '',
445          'error_cmd': '',
446          'ignore_cmd_errors': False,
447          'always_update': False},
448
449         # sudo configuration
450         {'enabled': True,
451          'source': 'PlanetLabConf/sudoers',
452          'dest': '/etc/sudoers',
453          'file_permissions': '440',
454          'file_owner': 'root',
455          'file_group': 'root',
456          'preinstall_cmd': '',
457          'postinstall_cmd': '/usr/sbin/visudo -c',
458          'error_cmd': '',
459          'ignore_cmd_errors': False,
460          'always_update': False}
461         ]
462
463     # Get list of existing (enabled, global) files
464     conf_files = GetConfFiles()
465     conf_files = filter(lambda conf_file: conf_file['enabled'] and \
466                                           not conf_file['node_ids'] and \
467                                           not conf_file['nodegroup_ids'],
468                         conf_files)
469     dests = [conf_file['dest'] for conf_file in conf_files]
470     conf_files = dict(zip(dests, conf_files))
471
472     # Create/update default PlanetLabConf entries
473     for default_conf_file in default_conf_files:
474         if default_conf_file['dest'] not in dests:
475             AddConfFile(default_conf_file)
476         else:
477             conf_file = conf_files[default_conf_file['dest']]
478             UpdateConfFile(conf_file['conf_file_id'], default_conf_file)
479
480     # Setup default slice attribute types
481     default_attribute_types = [
482         # Slice type (only vserver is supported)
483         {'name': "type",
484          'description': "Type of slice (e.g. vserver)",
485          'min_role_id': 20},
486
487         # Slice enabled (1) or suspended (0)
488         {'name': "enabled",
489          'description': "Slice enabled (1) or suspended (0)",
490          'min_role_id': 10},
491
492         # Slice reference image
493         {'name': "vref",
494          'description': "Reference image",
495          'min_role_id': 30},
496
497         # Slice initialization script
498         {'name': "initscript",
499          'description': "Slice initialization script",
500          'min_role_id': 10},
501
502         # CPU share
503         {'name': "cpu_min",
504          'description': "Minimum CPU share (ms/s)",
505          'min_role_id': 10},
506         {'name': "cpu_share",
507          'description': "Number of CPU shares",
508          'min_role_id': 10},
509
510         # Bandwidth limits
511         {'name': "net_min",
512          'description': "Minimum bandwidth (bps)",
513          'min_role_id': 10},
514         {'name': "net_max",
515          'description': "Maximum bandwidth (bps)",
516          'min_role_id': 10},
517         {'name': "net_avg",
518          'description': "Average bandwidth (bps)",
519          'min_role_id': 10},
520         {'name': "net_share",
521          'description': "Number of bandwidth shares",
522          'min_role_id': 10},
523         {'name': "net2_min",
524          'description': "Minimum bandwidth over routes exempt from node bandwidth limits (bps)",
525          'min_role_id': 10},
526         {'name': "net2_max",
527          'description': "Maximum bandwidth over routes exempt from node bandwidth limits (bps)",
528          'min_role_id': 10},
529         {'name': "net2_avg",
530          'description': "Average bandwidth over routes exempt from node bandwidth limits (bps)",
531          'min_role_id': 10},
532         {'name': "net2_share",
533          'description': "Number of bandwidth shares over routes exempt from node bandwidth limits",
534          'min_role_id': 10},
535
536         # Disk quota
537         {'name': "disk_max",
538          'description': "Disk quota (1k disk blocks)",
539          'min_role_id': 10},
540
541         # Special attributes applicable to Slice Creation Service (pl_conf) slice
542         {'name': "plc_slice_type",
543          'description': "Type of slice rspec to be created",
544          'min_role_id': 20},
545         {'name': "plc_agent_version",
546          'description': "Version of PLC agent (slice creation service) software to be deployed",
547          'min_role_id': 10},
548         {'name': "plc_ticket_pubkey",
549          'description': "Public key used to verify PLC-signed tickets",
550          'min_role_id': 10}
551         ]
552
553     # Get list of existing attribute types
554     attribute_types = GetSliceAttributeTypes()
555     attribute_types = [attribute_type['name'] for attribute_type in attribute_types]
556
557     # Create/update default slice attribute types
558     for default_attribute_type in default_attribute_types:
559         if default_attribute_type['name'] not in attribute_types:
560             AddSliceAttributeType(default_attribute_type)
561         else:
562             UpdateSliceAttributeType(default_attribute_type['name'], default_attribute_type)
563
564     # Get contents of SSL public certificate used for signing slice tickets
565     try:
566         plc_ticket_pubkey = ""
567         for line in file(plc_ma_sa['ca_ssl_key_pub']):
568             # Skip comments
569             if line[0:5] != "-----":
570                 # XXX The embedded newlines matter, do not strip()!
571                 plc_ticket_pubkey += line
572     except:
573         plc_ticket_pubkey = '%KEY%'
574
575     # Create/update system slices
576     default_slices = [
577         # Required for old Node Manager
578         {'name': "pl_conf",
579          'description': "PlanetLab Slice Creation Service (SCS)",
580          'url': url,
581          'instantiation': "plc-instantiated",
582          # Renew forever
583          'expires': sys.maxint,
584          'attributes': {'plc_slice_type': "VServerSlice",
585                         'plc_agent_version': "1.0",
586                         'plc_ticket_pubkey': plc_ticket_pubkey}},
587
588         # Required for old Node Manager
589         {'name': "pl_conf_vserverslice",
590          'description': "Default attributes for vserver slices",
591          'url': url,
592          'instantiation': "plc-instantiated",
593          # Renew forever
594          'expires': sys.maxint,
595          'attributes': {'cpu_share': "32",
596                         'plc_slice_type': "VServerSlice",
597                         'disk_max': "5000000"}},
598
599          # PlanetFlow
600         {'name': plc['slice_prefix'] + "_netflow",
601          'description': "PlanetFlow Traffic Auditing Service",
602          'url': url,
603          'instantiation': "plc-instantiated",
604          # Renew forever
605          'expires': sys.maxint,
606          'attributes': {'vref': "planetflow"}},
607         ]
608
609     for default_slice in default_slices:
610         slices = GetSlices([default_slice['name']])
611         if slices:
612             slice = slices[0]
613             UpdateSlice(slice['slice_id'], default_slice)
614         else:
615             AddSlice(default_slice)
616             slice = GetSlices([default_slice['name']])[0]
617
618         # Create/update all attributes
619         slice_attributes = {}
620         if slice['slice_attribute_ids']:
621             for slice_attribute in GetSliceAttributes(slice['slice_attribute_ids']):
622                 slice_attributes[slice_attribute['name']] = slice_attribute
623
624         for name, value in default_slice['attributes'].iteritems():
625             if name not in slice_attributes:
626                 AddSliceAttribute(slice['name'], name, value)
627             else:
628                 UpdateSliceAttribute(slice_attributes[name]['slice_attribute_id'], value)
629
630 if __name__ == '__main__':
631     main()
632
633 # Local variables:
634 # tab-width: 4
635 # mode: python
636 # End: