Update the cherrypy branch to use authz.afs.cells instead of just
[invirt/packages/invirt-web.git] / code / main.py
index de0a739..3655352 100755 (executable)
@@ -67,14 +67,13 @@ class InvirtWeb(View):
     @cherrypy.expose
     @cherrypy.tools.mako(filename="/error.mako")
     def error(self):
     @cherrypy.expose
     @cherrypy.tools.mako(filename="/error.mako")
     def error(self):
-        #op, username, fields, err, emsg, traceback):
         """Print an error page when an exception occurs"""
         op = cherrypy.request.prev.path_info
         username = cherrypy.request.login
         err = cherrypy.request.prev.params["err"]
         emsg = cherrypy.request.prev.params["emsg"]
         traceback = cherrypy.request.prev.params["traceback"]
         """Print an error page when an exception occurs"""
         op = cherrypy.request.prev.path_info
         username = cherrypy.request.login
         err = cherrypy.request.prev.params["err"]
         emsg = cherrypy.request.prev.params["emsg"]
         traceback = cherrypy.request.prev.params["traceback"]
-        d = dict(op = op, user=username, fields=cherrypy.request.prev.params,
+        d = dict(op=op, user=username, fields=cherrypy.request.prev.params,
                  errorMessage=str(err), stderr=emsg, traceback=traceback)
         error_raw = cherrypy.request.lookup.get_template("/error_raw.mako")
         details = error_raw.render(**d)
                  errorMessage=str(err), stderr=emsg, traceback=traceback)
         error_raw = cherrypy.request.lookup.get_template("/error_raw.mako")
         details = error_raw.render(**d)
@@ -87,7 +86,7 @@ class InvirtWeb(View):
 
     def __getattr__(self, name):
         if name in ("admin", "overlord"):
 
     def __getattr__(self, name):
         if name in ("admin", "overlord"):
-            if not cherrypy.request.login in getAfsGroupMembers(config.adminacl, config.authz[0].cell):
+            if not cherrypy.request.login in getAfsGroupMembers(config.adminacl, config.authz.afs.cells[0].cell):
                 raise InvalidInput('username', cherrypy.request.login,
                                    'Not in admin group %s.' % config.adminacl)
             cherrypy.request.state = State(cherrypy.request.login, isadmin=True)
                 raise InvalidInput('username', cherrypy.request.login,
                                    'Not in admin group %s.' % config.adminacl)
             cherrypy.request.state = State(cherrypy.request.login, isadmin=True)
@@ -98,14 +97,12 @@ class InvirtWeb(View):
     def handle_error(self):
         err = sys.exc_info()[1]
         if isinstance(err, InvalidInput):
     def handle_error(self):
         err = sys.exc_info()[1]
         if isinstance(err, InvalidInput):
-            e = revertStandardError()
             cherrypy.request.params['err'] = err
             cherrypy.request.params['err'] = err
-            cherrypy.request.params['emsg'] = e
+            cherrypy.request.params['emsg'] = revertStandardError()
             raise cherrypy.InternalRedirect('/invalidInput')
         if not cherrypy.request.prev or 'err' not in cherrypy.request.prev.params:
             raise cherrypy.InternalRedirect('/invalidInput')
         if not cherrypy.request.prev or 'err' not in cherrypy.request.prev.params:
-            e = revertStandardError()
             cherrypy.request.params['err'] = err
             cherrypy.request.params['err'] = err
-            cherrypy.request.params['emsg'] = e
+            cherrypy.request.params['emsg'] = revertStandardError()
             cherrypy.request.params['traceback'] = _cperror.format_exc()
             raise cherrypy.InternalRedirect('/error')
         # fall back to cherrypy default error page
             cherrypy.request.params['traceback'] = _cperror.format_exc()
             raise cherrypy.InternalRedirect('/error')
         # fall back to cherrypy default error page
@@ -202,10 +199,16 @@ console will suffer artifacts.
     help._cp_config['tools.require_login.on'] = False
 
     def parseCreate(self, fields):
     help._cp_config['tools.require_login.on'] = False
 
     def parseCreate(self, fields):
-        kws = dict([(kw, fields.get(kw)) for kw in 'name description owner memory disksize vmtype cdrom autoinstall'.split() if fields.get(kw)])
-        validate = validation.Validate(cherrypy.request.login, cherrypy.request.state, strict=True, **kws)
-        return dict(contact=cherrypy.request.login, name=validate.name, description=validate.description, memory=validate.memory,
-                    disksize=validate.disksize, owner=validate.owner, machine_type=getattr(validate, 'vmtype', Defaults.type),
+        kws = dict([(kw, fields[kw]) for kw in
+         'name description owner memory disksize vmtype cdrom autoinstall'.split()
+                    if fields[kw]])
+        validate = validation.Validate(cherrypy.request.login,
+                                       cherrypy.request.state,
+                                       strict=True, **kws)
+        return dict(contact=cherrypy.request.login, name=validate.name,
+                    description=validate.description, memory=validate.memory,
+                    disksize=validate.disksize, owner=validate.owner,
+                    machine_type=getattr(validate, 'vmtype', Defaults.type),
                     cdrom=getattr(validate, 'cdrom', None),
                     autoinstall=getattr(validate, 'autoinstall', None))
 
                     cdrom=getattr(validate, 'cdrom', None),
                     autoinstall=getattr(validate, 'autoinstall', None))
 
@@ -216,7 +219,8 @@ console will suffer artifacts.
         """Handler for create requests."""
         try:
             parsed_fields = self.parseCreate(fields)
         """Handler for create requests."""
         try:
             parsed_fields = self.parseCreate(fields)
-            machine = controls.createVm(cherrypy.request.login, cherrypy.request.state, **parsed_fields)
+            machine = controls.createVm(cherrypy.request.login,
+                                        cherrypy.request.state, **parsed_fields)
         except InvalidInput, err:
             pass
         else:
         except InvalidInput, err:
             pass
         else:
@@ -225,8 +229,8 @@ console will suffer artifacts.
         d = getListDict(cherrypy.request.login, cherrypy.request.state)
         d['err'] = err
         if err:
         d = getListDict(cherrypy.request.login, cherrypy.request.state)
         d['err'] = err
         if err:
-            for field in fields.keys():
-                setattr(d['defaults'], field, fields.get(field))
+            for field, value in fields.items():
+                setattr(d['defaults'], field, value)
         else:
             d['new_machine'] = parsed_fields['name']
         return d
         else:
             d['new_machine'] = parsed_fields['name']
         return d
@@ -244,14 +248,19 @@ console will suffer artifacts.
         raise RuntimeError("test of the emergency broadcast system")
 
     class MachineView(View):
         raise RuntimeError("test of the emergency broadcast system")
 
     class MachineView(View):
-        # This is hairy. Fix when CherryPy 3.2 is out. (rename to
-        # _cp_dispatch, and parse the argument as a list instead of
-        # string
-
         def __getattr__(self, name):
         def __getattr__(self, name):
+            """Synthesize attributes to allow RESTful URLs like
+            /machine/13/info. This is hairy. CherryPy 3.2 adds a
+            method called _cp_dispatch that allows you to explicitly
+            handle URLs that can't be mapped, and it allows you to
+            rewrite the path components and continue processing.
+
+            This function gets the next path component being resolved
+            as a string. _cp_dispatch will get an array of strings
+            representing any subsequent path components as well."""
+
             try:
             try:
-                machine_id = int(name)
-                cherrypy.request.params['machine_id'] = machine_id
+                cherrypy.request.params['machine_id'] = int(name)
                 return self
             except ValueError:
                 return None
                 return self
             except ValueError:
                 return None
@@ -260,7 +269,9 @@ console will suffer artifacts.
         @cherrypy.tools.mako(filename="/info.mako")
         def info(self, machine_id):
             """Handler for info on a single VM."""
         @cherrypy.tools.mako(filename="/info.mako")
         def info(self, machine_id):
             """Handler for info on a single VM."""
-            machine = validation.Validate(cherrypy.request.login, cherrypy.request.state, machine_id=machine_id).machine
+            machine = validation.Validate(cherrypy.request.login,
+                                          cherrypy.request.state,
+                                          machine_id=machine_id).machine
             d = infoDict(cherrypy.request.login, cherrypy.request.state, machine)
             checkpoint.checkpoint('Got infodict')
             return d
             d = infoDict(cherrypy.request.login, cherrypy.request.state, machine)
             checkpoint.checkpoint('Got infodict')
             return d
@@ -272,19 +283,24 @@ console will suffer artifacts.
         def modify(self, machine_id, **fields):
             """Handler for modifying attributes of a machine."""
             try:
         def modify(self, machine_id, **fields):
             """Handler for modifying attributes of a machine."""
             try:
-                modify_dict = modifyDict(cherrypy.request.login, cherrypy.request.state, machine_id, fields)
+                modify_dict = modifyDict(cherrypy.request.login,
+                                         cherrypy.request.state,
+                                         machine_id, fields)
             except InvalidInput, err:
                 result = None
             except InvalidInput, err:
                 result = None
-                machine = validation.Validate(cherrypy.request.login, cherrypy.request.state, machine_id=machine_id).machine
+                machine = validation.Validate(cherrypy.request.login,
+                                              cherrypy.request.state,
+                                              machine_id=machine_id).machine
             else:
                 machine = modify_dict['machine']
                 result = 'Success!'
                 err = None
             else:
                 machine = modify_dict['machine']
                 result = 'Success!'
                 err = None
-            info_dict = infoDict(cherrypy.request.login, cherrypy.request.state, machine)
+            info_dict = infoDict(cherrypy.request.login,
+                                 cherrypy.request.state, machine)
             info_dict['err'] = err
             if err:
             info_dict['err'] = err
             if err:
-                for field in fields.keys():
-                    setattr(info_dict['defaults'], field, fields.get(field))
+                for field, value in fields.items():
+                    setattr(info_dict['defaults'], field, value)
             info_dict['result'] = result
             return info_dict
 
             info_dict['result'] = result
             return info_dict
 
@@ -310,8 +326,9 @@ console will suffer artifacts.
             Remember to enable iptables!
             echo 1 > /proc/sys/net/ipv4/ip_forward
             """
             Remember to enable iptables!
             echo 1 > /proc/sys/net/ipv4/ip_forward
             """
-            machine = validation.Validate(cherrypy.request.login, cherrypy.request.state, machine_id=machine_id).machine
-
+            machine = validation.Validate(cherrypy.request.login,
+                                          cherrypy.request.state,
+                                          machine_id=machine_id).machine
             token = controls.vnctoken(machine)
             host = controls.listHost(machine)
             if host:
             token = controls.vnctoken(machine)
             host = controls.listHost(machine)
             if host:
@@ -329,14 +346,17 @@ console will suffer artifacts.
                      port=port,
                      authtoken=token)
             return d
                      port=port,
                      authtoken=token)
             return d
+
         @cherrypy.expose
         @cherrypy.tools.mako(filename="/command.mako")
         @cherrypy.tools.require_POST()
         def command(self, command_name, machine_id, **kwargs):
             """Handler for running commands like boot and delete on a VM."""
         @cherrypy.expose
         @cherrypy.tools.mako(filename="/command.mako")
         @cherrypy.tools.require_POST()
         def command(self, command_name, machine_id, **kwargs):
             """Handler for running commands like boot and delete on a VM."""
-            back = kwargs.get('back', None)
+            back = kwargs.get('back')
             try:
             try:
-                d = controls.commandResult(cherrypy.request.login, cherrypy.request.state, command_name, machine_id, kwargs)
+                d = controls.commandResult(cherrypy.request.login,
+                                           cherrypy.request.state,
+                                           command_name, machine_id, kwargs)
                 if d['command'] == 'Delete VM':
                     back = 'list'
             except InvalidInput, err:
                 if d['command'] == 'Delete VM':
                     back = 'list'
             except InvalidInput, err:
@@ -350,9 +370,12 @@ console will suffer artifacts.
                     return d
             if back == 'list':
                 cherrypy.request.state.clear() #Changed global state
                     return d
             if back == 'list':
                 cherrypy.request.state.clear() #Changed global state
-                raise cherrypy.InternalRedirect('/list?result=%s' % urllib.quote(result))
+                raise cherrypy.InternalRedirect('/list?result=%s'
+                                                % urllib.quote(result))
             elif back == 'info':
             elif back == 'info':
-                raise cherrypy.HTTPRedirect(cherrypy.request.base + '/machine/%d/' % machine_id, status=303)
+                raise cherrypy.HTTPRedirect(cherrypy.request.base
+                                            + '/machine/%d/' % machine_id,
+                                            status=303)
             else:
                 raise InvalidInput('back', back, 'Not a known back page.')
 
             else:
                 raise InvalidInput('back', back, 'Not a known back page.')
 
@@ -510,7 +533,9 @@ def modifyDict(username, state, machine_id, fields):
     olddisk = {}
     session.begin()
     try:
     olddisk = {}
     session.begin()
     try:
-        kws = dict([(kw, fields.get(kw)) for kw in 'owner admin contact name description memory vmtype disksize'.split() if fields.get(kw)])
+        kws = dict([(kw, fields[kw]) for kw in
+         'owner admin contact name description memory vmtype disksize'.split()
+                    if fields[kw]])
         kws['machine_id'] = machine_id
         validate = validation.Validate(username, state, **kws)
         machine = validate.machine
         kws['machine_id'] = machine_id
         validate = validation.Validate(username, state, **kws)
         machine = validate.machine
@@ -664,4 +689,4 @@ Subject: %s
     p.stdin.close()
     p.wait()
 
     p.stdin.close()
     p.wait()
 
-random.seed()
+random.seed() #sigh