f4d88b87d27d631b2e283c0be2beebc0b939904d
[invirt/packages/invirt-remote.git] / files / usr / sbin / invirt-remconffs
1 #!/usr/bin/python
2
3 import routefs
4 from routes import Mapper
5
6 from syslog import *
7 from time import time
8
9 from invirt import database
10 from invirt.config import structs as config
11
12 class RemConfFS(routefs.RouteFS):
13     """
14     RemConfFS creates a filesytem for configuring remctl, like this:
15     /
16     |-- acl
17     |   |-- machine1
18     |   ...
19     |   `-- machinen
20     `-- conf
21     
22     The machine list and the acls are drawn from a database.
23     """
24     
25     def __init__(self, *args, **kw):
26         """Initialize the filesystem and set it to allow_other access besides
27         the user who mounts the filesystem (i.e. root)
28         """
29         super(RemConfFS, self).__init__(*args, **kw)
30         self.lasttime = 0
31         self.fuse_args.add("allow_other", True)
32         
33         openlog('invirt-remconffs ', LOG_PID, LOG_DAEMON)
34         
35         syslog(LOG_DEBUG, 'Init complete.')
36     
37     def make_map(self):
38         m = Mapper()
39         m.connect('', controller='getroot')
40         m.connect('acl', controller='getmachines')
41         m.connect('acl/:machine', controller='getacl')
42         m.connect('conf', controller='getconf')
43         return m
44     
45     def recache(self):
46         if time() - self.lasttime > 5:
47             self.lasttime = time()
48             database.clear_cache()
49             self.machines = dict((machine.name, machine) for machine in database.session.query(database.Machine).all())
50     
51     def getroot(self, **kw):
52         return ['acl', 'conf']
53     
54     def getacl(self, machine, **kw):
55         """Build the ACL file for a machine
56         """
57         self.recache()
58         machine = self.machines[machine]
59         users = [acl.user for acl in machine.acl]
60         return "\n".join(map(self.userToPrinc, users)
61                  + ['include /etc/remctl/acl/web',
62                     ''])
63     
64     def getconf(self, **kw):
65         """Build the master conf file, with all machines
66         """
67         return '\n'.join("control %s /usr/sbin/invirt-remote-proxy-control"
68                  " /etc/remctl/remconffs/acl/%s"
69                  % (machine_name, machine_name)
70                  for machine_name in self.getmachines())+'\n'
71     
72     def getmachines(self, **kw):
73         """Get the list of VMs in the database, clearing the cache if it's 
74         older than 15 seconds"""
75         self.recache()
76         return self.machines.keys()
77     
78     def userToPrinc(self, user):
79         """Convert Kerberos v4-style names to v5-style and append a default
80         realm if none is specified
81         """
82         if '@' in user:
83             (princ, realm) = user.split('@')
84         else:
85             princ = user
86             realm = config.authn[0].realm
87         
88         return princ.replace('.', '/') + '@' + realm
89
90 if __name__ == '__main__':
91     database.connect()
92     routefs.main(RemConfFS)