Example #1
0
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)
Example #2
0
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
Example #3
0
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')
Example #4
0
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)
Example #5
0
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
Example #6
0
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')