Changeset 632 for trunk/packages


Ignore:
Timestamp:
Jun 21, 2008, 10:39:27 PM (16 years ago)
Author:
andersk
Message:

Add overlord mode, accessible from xvm.mit.edu/overlord by
system:sipb-xen.

Location:
trunk/packages/sipb-xen-www/code
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/packages/sipb-xen-www/code/main.py

    r629 r632  
    4040from webcommon import InvalidInput, CodeError, State
    4141import controls
     42from getafsgroups import getAfsGroupMembers
     43
     44def pathSplit(path):
     45    if path.startswith('/'):
     46        path = path[1:]
     47    i = path.find('/')
     48    if i == -1:
     49        i = len(path)
     50    return path[:i], path[i:]
    4251
    4352class Checkpoint:
     
    142151                autoinstall=getattr(validate, 'autoinstall', None))
    143152
    144 def create(username, state, fields):
     153def create(username, state, path, fields):
    145154    """Handler for create requests."""
    146155    try:
     
    205214    return d
    206215
    207 def listVms(username, state, fields):
     216def listVms(username, state, path, fields):
    208217    """Handler for list requests."""
    209218    checkpoint.checkpoint('Getting list dict')
     
    212221    return templates.list(searchList=[d])
    213222
    214 def vnc(username, state, fields):
     223def vnc(username, state, path, fields):
    215224    """VNC applet page.
    216225
     
    309318    return disk_fields
    310319
    311 def command(username, state, fields):
     320def command(username, state, path, fields):
    312321    """Handler for running commands like boot and delete on a VM."""
    313322    back = fields.getfirst('back')
     
    395404                machine=machine)
    396405
    397 def modify(username, state, fields):
     406def modify(username, state, path, fields):
    398407    """Handler for modifying attributes of a machine."""
    399408    try:
     
    415424
    416425
    417 def helpHandler(username, state, fields):
     426def helpHandler(username, state, path, fields):
    418427    """Handler for help messages."""
    419428    simple = fields.getfirst('simple')
     
    466475
    467476
    468 def badOperation(u, s, e):
     477def badOperation(u, s, p, e):
    469478    """Function called when accessing an unknown URI."""
    470479    return ({'Status': '404 Not Found'}, 'Invalid operation.')
     
    565574    return d
    566575
    567 def info(username, state, fields):
     576def info(username, state, path, fields):
    568577    """Handler for info on a single VM."""
    569578    machine = validation.Validate(username, state, machine_id=fields.getfirst('machine_id')).machine
     
    572581    return templates.info(searchList=[d])
    573582
    574 def unauthFront(_, _2, fields):
     583def unauthFront(_, _2, _3, fields):
    575584    """Information for unauth'd users."""
    576585    return templates.unauth(searchList=[{'simple' : True}])
    577586
    578 def throwError(_, __, ___):
     587def overlord(username, state, path, fields):
     588    if not username in getAfsGroupMembers('system:xvm', 'athena.mit.edu'):
     589        raise InvalidInput('username', username, 'Not an overlord.')
     590    newstate = State(username, overlord=True)
     591    newstate.environ = state.environ
     592    return handler(username, newstate, path, fields)
     593
     594def throwError(_, __, ___, ____):
    579595    """Throw an error, to test the error-tracing mechanisms."""
    580596    raise RuntimeError("test of the emergency broadcast system")
     
    588604               help=helpHandler,
    589605               unauth=unauthFront,
     606               overlord=overlord,
    590607               errortest=throwError)
    591608
     
    626643    return environ.get('REMOTE_USER', None)
    627644
     645def handler(username, state, path, fields):
     646    operation, path = pathSplit(path)
     647    if not operation:
     648        operation = 'list'
     649    print 'Starting', operation
     650    fun = mapping.get(operation, badOperation)
     651    return fun(username, state, path, fields)
     652
    628653class App:
    629654    def __init__(self, environ, start_response):
     
    636661
    637662    def __iter__(self):
     663        start_time = time.time()
    638664        sipb_xen_database.clear_cache()
    639665        sys.stderr = StringIO()
     
    646672        if self.username is None:
    647673            operation = 'unauth'
    648         if operation.startswith('/'):
    649             operation = operation[1:]
    650         if not operation:
    651             operation = 'list'
    652         print 'Starting', operation
    653 
    654         start_time = time.time()
    655         fun = mapping.get(operation, badOperation)
     674
    656675        try:
    657676            checkpoint.checkpoint('Before')
    658             output = fun(self.username, self.state, fields)
     677            output = handler(self.username, self.state, operation, fields)
    659678            checkpoint.checkpoint('After')
    660679
  • trunk/packages/sipb-xen-www/code/validation.py

    r629 r632  
    3737
    3838        if machine_id is not None:
    39             self.machine = testMachineId(username, machine_id)
     39            self.machine = testMachineId(username, state, machine_id)
    4040        machine = getattr(self, 'machine', None)
    4141
     
    5959                                      on=not created_new)
    6060        if disksize is not None:
    61             self.disksize = validDisk(self.owner, disksize, machine)
     61            self.disksize = validDisk(self.owner, state, disksize, machine)
    6262        if vmtype is not None:
    6363            self.vmtype = validVmType(vmtype)
     
    124124    return False
    125125
    126 def haveAccess(user, machine):
     126def haveAccess(user, state, machine):
    127127    """Return whether a user has administrative access to a machine"""
    128     return user in cache_acls.accessList(machine)
     128    return state.overlord or user in cache_acls.accessList(machine)
    129129
    130130def owns(user, machine):
     
    158158                           "Minimum %s MiB" % MIN_MEMORY_SINGLE)
    159159    max_val = maxMemory(owner, g, machine, on)
    160     if memory > max_val:
     160    if not g.overlord and memory > max_val:
    161161        raise InvalidInput('memory', memory,
    162162                           'Maximum %s MiB for %s' % (max_val, owner))
    163163    return memory
    164164
    165 def validDisk(owner, disk, machine=None):
     165def validDisk(owner, g, disk, machine=None):
    166166    """Parse and validate limits for disk for a given owner and machine."""
    167167    try:
    168168        disk = float(disk)
    169         if disk > maxDisk(owner, machine):
     169        if not g.overlord and disk > maxDisk(owner, machine):
    170170            raise InvalidInput('disk', disk,
    171171                               "Maximum %s G" % maxDisk(owner, machine))
     
    186186    return t
    187187
    188 def testMachineId(user, machine_id, exists=True):
     188def testMachineId(user, state, machine_id, exists=True):
    189189    """Parse, validate and check authorization for a given user and machine.
    190190
     
    201201    if exists and machine is None:
    202202        raise InvalidInput('machine_id', machine_id, "Does not exist.")
    203     if machine is not None and not haveAccess(user, machine):
     203    if machine is not None and not haveAccess(user, state, machine):
    204204        raise InvalidInput('machine_id', machine_id,
    205205                           "You do not have access to this machine.")
  • trunk/packages/sipb-xen-www/code/webcommon.py

    r578 r632  
    3939class State(object):
    4040    """State for a request"""
    41     def __init__(self, user):
     41    def __init__(self, user, overlord=False):
    4242        self.username = user
     43        self.overlord = overlord
    4344
    44     machines = cachedproperty(lambda self:
    45                                   Machine.query().join('acl').select_by(user=self.username))
     45    def getMachines(self):
     46        if self.overlord:
     47            return Machine.select()
     48        else:
     49            return Machine.query().join('acl').select_by(user=self.username)
     50
     51    machines = cachedproperty(getMachines)
    4652    xmlist_raw = cachedproperty(lambda self: controls.getList())
    4753    xmlist = cachedproperty(lambda self:
Note: See TracChangeset for help on using the changeset viewer.