source: trunk/packages/invirt-remote/server/usr/sbin/invirt-remconffs @ 2234

Last change on this file since 2234 was 2234, checked in by broder, 16 years ago

Allow anyone on the adminacl to issue web remctls.

  • Property svn:executable set to *
File size: 3.3 KB
Line 
1#!/usr/bin/python
2
3import routefs
4from routes import Mapper
5
6from syslog import *
7from time import time
8import sqlalchemy as sa
9
10from invirt import database
11from invirt.config import structs as config
12
13class RemConfFS(routefs.RouteFS):
14    """
15    RemConfFS creates a filesytem for configuring remctl, like this:
16    /
17    |-- adminacl
18    |-- acl
19    |   |-- machine1
20    |   ...
21    |   `-- machinen
22    `-- conf
23   
24    The machine list and the acls are drawn from a database.
25    """
26   
27    def __init__(self, *args, **kw):
28        """Initialize the filesystem and set it to allow_other access besides
29        the user who mounts the filesystem (i.e. root)
30        """
31        super(RemConfFS, self).__init__(*args, **kw)
32        self.fuse_args.add("allow_other", True)
33       
34        openlog('invirt-remconffs ', LOG_PID, LOG_DAEMON)
35       
36        syslog(LOG_DEBUG, 'Init complete.')
37   
38    def make_map(self):
39        m = Mapper()
40        m.connect('', controller='getroot')
41        m.connect('acl', controller='getmachines')
42        m.connect('acl/:machine', controller='getacl')
43        m.connect('adminacl', controller='getadmin')
44        m.connect('conf', controller='getconf')
45        return m
46   
47    def getroot(self, **kw):
48        return ['adminacl', 'acl', 'conf']
49   
50    def getacl(self, machine, **kw):
51        """Build the ACL file for a machine
52        """
53        s = sa.sql.select([database.machine_access_table.c.user], # Field to select from
54                          sa.sql.and_( # where clause
55                database.machine_table.c.machine_id==database.machine_access_table.c.machine_id, # join field
56                database.machine_table.c.name == machine), # filter field
57                          from_obj=[database.machine_access_table, database.machine_table]) # from tables
58        users = [self.userToPrinc(acl[0]) for acl in
59                 database.session.execute(s)]
60        return "\n".join(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. Does not cache to prevent race conditions."""
74        return list(row[0] for row in database.session.execute(sa.sql.select([database.Machine.c.name])))
75
76    def getadmin(self, **kw):
77        """
78        Get the list of administrators for the global ACL.
79        """
80        acl = [self.userToPrinc(row[0]) for row in database.session.execute(sa.sql.select([database.admins_table.c.user]))]
81        acl.append('include /etc/remctl/acl/web\n')
82        return '\n'.join(acl)
83   
84    def userToPrinc(self, user):
85        """Convert Kerberos v4-style names to v5-style and append a default
86        realm if none is specified
87        """
88        if '@' in user:
89            (princ, realm) = user.split('@')
90        else:
91            princ = user
92            realm = config.kerberos.realm
93       
94        return princ.replace('.', '/') + '@' + realm
95
96if __name__ == '__main__':
97    database.connect()
98    routefs.main(RemConfFS)
Note: See TracBrowser for help on using the repository browser.