def handler(req): # figure out the vserver name and command path = os.path.normpath(req.uri) # no trailing slash parts = path.split('/', 4) # defaults command, params = 'index', '' if len(parts) < 2: return error(req, 'request not understood') if parts[1] == 'admin': vserver_name = parts[2] vservers = vsutil.list_vservers() if not vservers.has_key(vserver_name): return error(req, 'request not understood') if len(parts) > 3: command = parts[3] if command == 'login': return login(req, vserver_name) # anything else requires authentication userid = check_authen(req, vserver_name) if not userid: return apache.OK if (userid != SUPER) and (userid != cfg.PANEL_SUPERUSER) and (userid != vserver_name): return error(req, 'request not understood') # save it in request to be used later in some places req.user = userid if len(parts) > 4: params = parts[4] elif parts[1] == 'pubkey': # hand out our public key return pubkey(req) elif parts[1] == 'getstats': if len(parts) != 4: return error(req, 'request not understood') name, command = parts[2:] return getstats(req, name, command) elif parts[1] in ['suspend', 'unsuspend']: if len(parts) != 3: return error(req, 'request not understood') name = parts[2] if parts[1] == 'suspend': return suspend(req, name) else: return unsuspend(req, name) elif parts[1] == 'graph': if len(parts) != 4: return error(req, 'request not understood') name, command = parts[2:] return graph(req, name, command) else: return error(req, 'request not understood') if command not in ALLOWED_COMMANDS: return error(req, 'request not understood') # now call the appropriate action self = sys.modules[__name__] func = getattr(self, command) # call the command with params return func(req, vserver_name, params)
def login(req, vserver_name, message=''): if req.method == 'POST': # someone is trying to login fs = util.FieldStorage(req) userid = fs.getfirst('userid') passwd = fs.getfirst('passwd') uri = fs.getfirst('uri') vservers = vsutil.list_vservers() if ((vserver_name == userid and vservers.has_key(vserver_name) and vds.checkpw(vserver_name, userid, passwd)) or # root (userid == SUPER and vds.checkpw('/', userid, passwd)) or # superuser (userid == cfg.PANEL_SUPERUSER and crypto.check_passwd_md5(passwd, cfg.PANEL_SUPERUSER_PW))): # plant the cookie key = _read_priv_key() cookie = RSASignedCookie.RSASignedCookie('openvps-user', "%d:%s" % (time.time(), userid), key) cookie.path = '/' Cookie.add_cookie(req, cookie) if uri and not uri.endswith('login'): util.redirect(req, str(uri)) else: util.redirect(req, '/admin/%s/status' % vserver_name) else: message = 'invalid login or password' # if we got here, either it's not a POST or login failed # it's possible that some qargs were passed in qargs = {} if req.args: qargs = util.parse_qs(req.args) if qargs.has_key('m'): if not message: if qargs['m'][0] == '1': message = 'please log in' elif qargs['m'][0] == '2': message = 'session time-out, please log in again' if qargs.has_key('url'): url = qargs['url'][0] else: url = req.uri body_tmpl = _tmpl_path('login_body.html') body_vars = {'message':message, 'url':url} vars = {'global_menu': '', 'body':psp.PSP(req, body_tmpl, vars=body_vars), 'name':''} p = psp.PSP(req, _tmpl_path('main_frame.html'), vars=vars) p.run() return apache.OK
def graph(req, name, command): if not req.args: return error(req, 'Not sure what you mean') qargs = util.parse_qs(req.args) if not qargs.has_key('s'): return error(req, 'Where do I start?') start = '-'+qargs['s'][0] # exclude these vps's exclude = [] if qargs.has_key('exclude'): exclude = qargs['exclude'][0].split() # limit to only these vps's limit = [] if qargs.has_key('limit'): limit = qargs['limit'][0].split() width = 600 if qargs.has_key('w'): width = int(qargs['w'][0]) height = 400 if qargs.has_key('h'): height = int(qargs['h'][0]) # how many days back? secs = abs(int(start)) if secs < 60*60*24: # we're talking hours title = 'last %d hours' % (secs/(60*60)) else: title = 'last %d days' % (secs/(60*60*24)) if command in ['bwidth', 'mem']: # here we need to draw a nice little graph.... tfile, tpath = tempfile.mkstemp('.gif', 'oh') os.close(tfile) args = [tpath, '--start', start, '--title', title, '-w', str(width), '-h', str(height), '-c', 'SHADEB#FFFFFF', '-c', 'SHADEA#FFFFFF', '-l', '0'] if qargs.has_key('l'): args.append('-g') # no legend # list vservers vservers = vsutil.list_vservers() keys = vservers.keys() # assign colors colors = {} ci = 0 for vs in keys: colors[vs.replace('-', '')] = COLORS[ci] ci += 1 # process limit and exclude if limit: keys = [k for k in keys if k in limit] keys = [k for k in keys if k not in exclude] # we only have so many colors if len(keys) > len(COLORS): return error(req, 'Not enough colors for VPSs, exclude some:\n%s' % `keys`) keys.sort() for vs in keys: rrd = os.path.join(cfg.VAR_DB_OPENVPS, 'vsmon/%s.rrd' % vs) vs = vs.replace('-', '') # rrdtool does not like dashes if command == 'bwidth': args = args + [ 'DEF:%s_in=%s:vs_in:AVERAGE' % (vs, rrd), 'DEF:%s_out=%s:vs_out:AVERAGE' % (vs, rrd), 'CDEF:%s_inb=%s_in,-8,*' % (vs, vs), 'CDEF:%s_outb=%s_out,8,*' % (vs, vs) ] elif command == 'mem': args = args + [ 'DEF:%s_vm=%s:vs_vm:AVERAGE' % (vs, rrd), 'DEF:%s_rss=%s:vs_rss:AVERAGE' % (vs, rrd), 'CDEF:%s_vmb=%s_vm,1024,*' % (vs, vs), 'CDEF:%s_rssb=%s_rss,1024,*' % (vs, vs), 'CDEF:%s_rssbg=%s_rss,-1024,*' % (vs, vs), ] if command == 'bwidth': # incoming vs = keys[0].replace('-', '') args = args + [ 'AREA:%s_outb#%s:%s bps out' % (vs, colors[vs], vs.ljust(10)), 'GPRINT:%s_inb:MAX:Max IN\\: %%8.2lf%%s' % (vs, ), 'GPRINT:%s_inb:AVERAGE:Avg IN\\: %%8.2lf%%s' % (vs, ), 'GPRINT:%s_outb:MAX:Max OUT\\: %%8.2lf%%s' % (vs, ), 'GPRINT:%s_outb:AVERAGE:Avg OUT\\: %%8.2lf%%s\\n' % (vs, ) ] for vs in keys[1:]: vs = vs.replace('-', '') args = args + [ 'STACK:%s_outb#%s:%s bps out' % (vs, colors[vs], vs.ljust(10)), 'GPRINT:%s_inb:MAX:Max IN\\: %%8.2lf%%s' % (vs, ), 'GPRINT:%s_inb:AVERAGE:Avg IN\\: %%8.2lf%%s' % (vs, ), 'GPRINT:%s_outb:MAX:Max OUT\\: %%8.2lf%%s' % (vs, ), 'GPRINT:%s_outb:AVERAGE:Avg OUT\\: %%8.2lf%%s\\n' % (vs, ) ] # outgoing keys.reverse() vs = keys[0].replace('-', '') args = args + [ 'AREA:%s_inb#%s::' % (vs, colors[vs]), ] for vs in keys[1:]: vs = vs.replace('-', '') args = args + [ 'STACK:%s_inb#%s::' % (vs, colors[vs]), ] elif command == 'mem': # rss (displayed at bottom) vs = keys[0].replace('-', '') args = args + [ 'AREA:%s_rssbg#%s:%s RSS bytes' % (vs, colors[vs], vs.ljust(10)), 'GPRINT:%s_rssb:MAX:Max RSS\\: %%8.2lf%%s' % (vs, ), 'GPRINT:%s_rssb:AVERAGE:Avg RSS\\: %%8.2lf%%s' % (vs, ), 'GPRINT:%s_vmb:MAX:Max VM\\: %%8.2lf%%s' % (vs, ), 'GPRINT:%s_vmb:AVERAGE:Avg VM\\: %%8.2lf%%s\\n' % (vs, ) ] for vs in keys[1:]: vs = vs.replace('-', '') args = args + [ 'STACK:%s_rssbg#%s:%s RSS bytes' % (vs, colors[vs], vs.ljust(10)), 'GPRINT:%s_rssb:MAX:Max RSS\\: %%8.2lf%%s' % (vs, ), 'GPRINT:%s_rssb:AVERAGE:Avg RSS\\: %%8.2lf%%s' % (vs, ), 'GPRINT:%s_vmb:MAX:Max VM\\: %%8.2lf%%s' % (vs, ), 'GPRINT:%s_vmb:AVERAGE:Avg VM\\: %%8.2lf%%s\\n' % (vs, ) ] # vm keys.reverse() vs = keys[0].replace('-', '') args = args + [ 'AREA:%s_vmb#%s::' % (vs, colors[vs]), ] for vs in keys[1:]: vs = vs.replace('-', '') args = args + [ 'STACK:%s_vmb#%s::' % (vs, colors[vs]), ] RRD.graph(*args) req.content_type = 'image/gif' req.sendfile(tpath) os.unlink(tpath) return apache.OK else: return error(req, 'request not understood')
def handler(req): # figure out the vserver name and command path = os.path.normpath(req.uri) # no trailing slash parts = path.split('/', 4) # defaults command, params = 'index', '' if len(parts) < 2: return error(req, 'request not understood') if parts[1] == 'admin': vserver_name = parts[2] vservers = vsutil.list_vservers() if not vservers.has_key(vserver_name): return error(req, 'request not understood') if len(parts) > 3: command = parts[3] if command == 'login': return login(req, vserver_name) # anything else requires authentication userid = check_authen(req, vserver_name) if not userid: return apache.OK if (userid != SUPER) and (userid != cfg.PANEL_SUPERUSER) and ( userid != vserver_name): return error(req, 'request not understood') # save it in request to be used later in some places req.user = userid if len(parts) > 4: params = parts[4] elif parts[1] == 'pubkey': # hand out our public key return pubkey(req) elif parts[1] == 'getstats': if len(parts) != 4: return error(req, 'request not understood') name, command = parts[2:] return getstats(req, name, command) elif parts[1] in ['suspend', 'unsuspend']: if len(parts) != 3: return error(req, 'request not understood') name = parts[2] if parts[1] == 'suspend': return suspend(req, name) else: return unsuspend(req, name) elif parts[1] == 'graph': if len(parts) != 4: return error(req, 'request not understood') name, command = parts[2:] return graph(req, name, command) else: return error(req, 'request not understood') if command not in ALLOWED_COMMANDS: return error(req, 'request not understood') # now call the appropriate action self = sys.modules[__name__] func = getattr(self, command) # call the command with params return func(req, vserver_name, params)
def login(req, vserver_name, message=''): if req.method == 'POST': # someone is trying to login fs = util.FieldStorage(req) userid = fs.getfirst('userid') passwd = fs.getfirst('passwd') uri = fs.getfirst('uri') vservers = vsutil.list_vservers() if ((vserver_name == userid and vservers.has_key(vserver_name) and vds.checkpw(vserver_name, userid, passwd)) or # root (userid == SUPER and vds.checkpw('/', userid, passwd)) or # superuser (userid == cfg.PANEL_SUPERUSER and crypto.check_passwd_md5(passwd, cfg.PANEL_SUPERUSER_PW))): # plant the cookie key = _read_priv_key() cookie = RSASignedCookie.RSASignedCookie( 'openvps-user', "%d:%s" % (time.time(), userid), key) cookie.path = '/' Cookie.add_cookie(req, cookie) if uri and not uri.endswith('login'): util.redirect(req, str(uri)) else: util.redirect(req, '/admin/%s/status' % vserver_name) else: message = 'invalid login or password' # if we got here, either it's not a POST or login failed # it's possible that some qargs were passed in qargs = {} if req.args: qargs = util.parse_qs(req.args) if qargs.has_key('m'): if not message: if qargs['m'][0] == '1': message = 'please log in' elif qargs['m'][0] == '2': message = 'session time-out, please log in again' if qargs.has_key('url'): url = qargs['url'][0] else: url = req.uri body_tmpl = _tmpl_path('login_body.html') body_vars = {'message': message, 'url': url} vars = { 'global_menu': '', 'body': psp.PSP(req, body_tmpl, vars=body_vars), 'name': '' } p = psp.PSP(req, _tmpl_path('main_frame.html'), vars=vars) p.run() return apache.OK
def graph(req, name, command): if not req.args: return error(req, 'Not sure what you mean') qargs = util.parse_qs(req.args) if not qargs.has_key('s'): return error(req, 'Where do I start?') start = '-' + qargs['s'][0] # exclude these vps's exclude = [] if qargs.has_key('exclude'): exclude = qargs['exclude'][0].split() # limit to only these vps's limit = [] if qargs.has_key('limit'): limit = qargs['limit'][0].split() width = 600 if qargs.has_key('w'): width = int(qargs['w'][0]) height = 400 if qargs.has_key('h'): height = int(qargs['h'][0]) # how many days back? secs = abs(int(start)) if secs < 60 * 60 * 24: # we're talking hours title = 'last %d hours' % (secs / (60 * 60)) else: title = 'last %d days' % (secs / (60 * 60 * 24)) if command in ['bwidth', 'mem']: # here we need to draw a nice little graph.... tfile, tpath = tempfile.mkstemp('.gif', 'oh') os.close(tfile) args = [ tpath, '--start', start, '--title', title, '-w', str(width), '-h', str(height), '-c', 'SHADEB#FFFFFF', '-c', 'SHADEA#FFFFFF', '-l', '0' ] if qargs.has_key('l'): args.append('-g') # no legend # list vservers vservers = vsutil.list_vservers() keys = vservers.keys() # assign colors colors = {} ci = 0 for vs in keys: colors[vs.replace('-', '')] = COLORS[ci] ci += 1 # process limit and exclude if limit: keys = [k for k in keys if k in limit] keys = [k for k in keys if k not in exclude] # we only have so many colors if len(keys) > len(COLORS): return error( req, 'Not enough colors for VPSs, exclude some:\n%s' % ` keys `) keys.sort() for vs in keys: rrd = os.path.join(cfg.VAR_DB_OPENVPS, 'vsmon/%s.rrd' % vs) vs = vs.replace('-', '') # rrdtool does not like dashes if command == 'bwidth': args = args + [ 'DEF:%s_in=%s:vs_in:AVERAGE' % (vs, rrd), 'DEF:%s_out=%s:vs_out:AVERAGE' % (vs, rrd), 'CDEF:%s_inb=%s_in,-8,*' % (vs, vs), 'CDEF:%s_outb=%s_out,8,*' % (vs, vs) ] elif command == 'mem': args = args + [ 'DEF:%s_vm=%s:vs_vm:AVERAGE' % (vs, rrd), 'DEF:%s_rss=%s:vs_rss:AVERAGE' % (vs, rrd), 'CDEF:%s_vmb=%s_vm,1024,*' % (vs, vs), 'CDEF:%s_rssb=%s_rss,1024,*' % (vs, vs), 'CDEF:%s_rssbg=%s_rss,-1024,*' % (vs, vs), ] if command == 'bwidth': # incoming vs = keys[0].replace('-', '') args = args + [ 'AREA:%s_outb#%s:%s bps out' % (vs, colors[vs], vs.ljust(10)), 'GPRINT:%s_inb:MAX:Max IN\\: %%8.2lf%%s' % (vs, ), 'GPRINT:%s_inb:AVERAGE:Avg IN\\: %%8.2lf%%s' % (vs, ), 'GPRINT:%s_outb:MAX:Max OUT\\: %%8.2lf%%s' % (vs, ), 'GPRINT:%s_outb:AVERAGE:Avg OUT\\: %%8.2lf%%s\\n' % (vs, ) ] for vs in keys[1:]: vs = vs.replace('-', '') args = args + [ 'STACK:%s_outb#%s:%s bps out' % (vs, colors[vs], vs.ljust(10)), 'GPRINT:%s_inb:MAX:Max IN\\: %%8.2lf%%s' % (vs, ), 'GPRINT:%s_inb:AVERAGE:Avg IN\\: %%8.2lf%%s' % (vs, ), 'GPRINT:%s_outb:MAX:Max OUT\\: %%8.2lf%%s' % (vs, ), 'GPRINT:%s_outb:AVERAGE:Avg OUT\\: %%8.2lf%%s\\n' % (vs, ) ] # outgoing keys.reverse() vs = keys[0].replace('-', '') args = args + [ 'AREA:%s_inb#%s::' % (vs, colors[vs]), ] for vs in keys[1:]: vs = vs.replace('-', '') args = args + [ 'STACK:%s_inb#%s::' % (vs, colors[vs]), ] elif command == 'mem': # rss (displayed at bottom) vs = keys[0].replace('-', '') args = args + [ 'AREA:%s_rssbg#%s:%s RSS bytes' % (vs, colors[vs], vs.ljust(10)), 'GPRINT:%s_rssb:MAX:Max RSS\\: %%8.2lf%%s' % (vs, ), 'GPRINT:%s_rssb:AVERAGE:Avg RSS\\: %%8.2lf%%s' % (vs, ), 'GPRINT:%s_vmb:MAX:Max VM\\: %%8.2lf%%s' % (vs, ), 'GPRINT:%s_vmb:AVERAGE:Avg VM\\: %%8.2lf%%s\\n' % (vs, ) ] for vs in keys[1:]: vs = vs.replace('-', '') args = args + [ 'STACK:%s_rssbg#%s:%s RSS bytes' % (vs, colors[vs], vs.ljust(10)), 'GPRINT:%s_rssb:MAX:Max RSS\\: %%8.2lf%%s' % (vs, ), 'GPRINT:%s_rssb:AVERAGE:Avg RSS\\: %%8.2lf%%s' % (vs, ), 'GPRINT:%s_vmb:MAX:Max VM\\: %%8.2lf%%s' % (vs, ), 'GPRINT:%s_vmb:AVERAGE:Avg VM\\: %%8.2lf%%s\\n' % (vs, ) ] # vm keys.reverse() vs = keys[0].replace('-', '') args = args + [ 'AREA:%s_vmb#%s::' % (vs, colors[vs]), ] for vs in keys[1:]: vs = vs.replace('-', '') args = args + [ 'STACK:%s_vmb#%s::' % (vs, colors[vs]), ] RRD.graph(*args) req.content_type = 'image/gif' req.sendfile(tpath) os.unlink(tpath) return apache.OK else: return error(req, 'request not understood')