#. -*- coding: utf-8 - # required proxmox permissions: PVESysAdmin, PVEVMAdmin # # afx 2015-2016 # import site packages import logging import falcon import sys import json import urllib.parse #import local packages import ioconfig import grid import plugin import clientsdb config = ioconfig.parser logger = ioconfig.logger def welcome(): """displays motd in log as welcome message""" logger.info('###################################') logger.info('# proxmaster ][ (c) 2015-2016 afx #') logger.info('###################################') def apicheck(params): """ compares request params for api key with the config file""" try: if params['apipass'] == config.get('general', 'apipass'): status = True response = 'OK' else: status = False response = 'GET KEY DENIED' logger.error('grid> read access denied. key mismatch') except: #raise status = False response = 'GET URL DENIED' logger.error('grid> read access denied. url error?') finally: return (status, response) #API methods class Validate(object): def on_post(self, req, resp): """ get clientemail and password and compare it with the client db and returns a list of managed object IDs """ clientemail = req.params['clientemail'] passwd = req.params['password'] logger.info('grid> access requested for {} with {}'.format(clientemail, passwd)) #apicheck_stat, apicheck_resp = apicheck(req.params) response = clientsdb.validate(clientemail, passwd) if response is not None: resp.status = falcon.HTTP_200 resp.body = response else: resp.status = falcon.HTTP_403 resp.body = 'ERR' class ClusterResource(object): def on_get(self, req, resp): """TEST ONLY. List cluster nodes. TEST ONLY""" logger.info('grid> cache status') apicheck_stat, apicheck_resp = apicheck(req.params) if apicheck_stat: resp.status = falcon.HTTP_200 resp.body = str(grid.sync()) else: resp.status = falcon.HTTP_403 resp.body = apicheck_resp def on_post(self, req, resp): """Create a cluster node, returns array of: status, vmid, pass, ipv4, """ logger.info('grid> create ' + str(req.params)) apicheck_stat, apicheck_resp = apicheck(req.params) if apicheck_stat: resp.status = falcon.HTTP_200 try: resp.body = urllib.parse.urlencode(plugin.vmcreate(req.params)) except: logger.error('grid> create function cancelled') raise resp.status = falcon.HTTP_403 response = 'CREATE ERR' resp.body = response else: resp.status = falcon.HTTP_403 resp.body = apicheck_resp class StatusResource(object): def on_get(self, req, resp, vmid): """ check vm status """ logger.info('grid> status ' + str(vmid)) apicheck_stat, apicheck_resp = apicheck(req.params) if apicheck_stat: resp.status = falcon.HTTP_200 try: resp.body = urllib.parse.urlencode(plugin.vmstatus(vmid)) except: logger.error('grid> status error') raise resp.status = falcon.HTTP_403 response = 'STATUS ERR' resp.body = response else: resp.status = falcon.HTTP_403 resp.body = apicheck_resp class DeleteResource(object): def on_post(self, req, resp, vmid): """ delete machine completely""" logger.info('grid> delete ' + str(vmid)) apicheck_stat, apicheck_resp = apicheck(req.params) if apicheck_stat: try: resp.body = urllib.parse.urlencode(plugin.vmdelete(vmid)) except: logger.error('grid> delete error') raise resp.status = falcon.HTTP_403 response = 'DELETE ERR' resp.body = response else: resp.status = falcon.HTTP_403 resp.body = apicheck_resp class ArchivateResource(object): def on_post(self, req, resp, vmid): """ Temporary suspend the instance """ logger.info('grid> suspend ' + str(vmid)) apicheck_stat, apicheck_resp = apicheck(req.params) if apicheck_stat: resp.status = falcon.HTTP_200 try: resp.body = urllib.parse.urlencode(plugin.vmsuspend(vmid)) except: logger.error('grid> pause error') raise resp.status = falcon.HTTP_403 response = 'PAUSE ERR' resp.body = response else: resp.status = falcon.HTTP_403 resp.body = apicheck_resp class UnArchiveResource(object): def on_post(self, req, resp, vmid): """ Unuspend the instance """ logger.info('grid> resume ' + str(vmid)) apicheck_stat, apicheck_resp = apicheck(req.params) if apicheck_stat: resp.status = falcon.HTTP_200 try: resp.body = urllib.parse.urlencode(plugin.vmresume(vmid)) except: logger.error('grid> resume error') raise resp.status = falcon.HTTP_403 response = 'RESUME ERR' resp.body = response else: resp.status = falcon.HTTP_403 resp.body = apicheck_resp class StartResource(object): def on_post(self, req, resp, vmid): """ Start the instance """ logger.info('grid> start ' + str(vmid)) apicheck_stat, apicheck_resp = apicheck(req.params) if apicheck_stat: resp.status = falcon.HTTP_200 try: resp.body = urllib.parse.urlencode(plugin.vmstart(vmid)) except: logger.error('grid> start error') #raise resp.status = falcon.HTTP_403 response = 'START ERR' resp.body = response else: resp.status = falcon.HTTP_403 resp.body = apicheck_resp class ShutdownResource(object): def on_post(self, req, resp, vmid): """ ACPI Shutdown the instance """ logger.info('grid> shutdown ' + str(vmid)) apicheck_stat, apicheck_resp = apicheck(req.params) if apicheck_stat: resp.status = falcon.HTTP_200 try: resp.body = urllib.parse.urlencode(plugin.vmshutdown(vmid)) #TODO: Try few times and then return proper status message except: logger.error('grid> shutdown error') #raise resp.status = falcon.HTTP_403 response = 'SHUTDOWN ERR' resp.body = response else: resp.status = falcon.HTTP_403 resp.body = apicheck_resp class StopResource(object): def on_post(self, req, resp, vmid): """ Stop the instance """ logger.info('grid> stop ' + str(vmid)) apicheck_stat, apicheck_resp = apicheck(req.params) if apicheck_stat: resp.status = falcon.HTTP_200 try: resp.body = urllib.parse.urlencode(plugin.vmstop(vmid)) except: logger.error('grid> stop error') #raise resp.status = falcon.HTTP_403 response = 'STOP ERR' resp.body = response else: resp.status = falcon.HTTP_403 resp.body = apicheck_resp class VNCResource(object): def on_post(self, req, resp, vmid): """ Create a VNC link to the instance """ apicheck_stat, apicheck_resp = apicheck(req.params) logger.info('grid> vnc ' + str(vmid)) if apicheck_stat: try: resp.status = falcon.HTTP_200 resp.body = urllib.parse.urlencode(plugin.vmvnc(vmid)) except: logger.error('grid> vnc error') raise resp.status = falcon.HTTP_403 response = 'VNC ERR' resp.body = response else: resp.status = falcon.HTTP_403 resp.body = apicheck_resp if __name__ == '__main__': sys.exit("invoke proxmaster via uwsgi. thanks. bye. o/") #setup routes wsgi_app = api = application = falcon.API() #display motd welcome() #logger.info('grid> sync') #grid.sync() # setup routes res_validate = Validate() api.add_route('/instance/auth', res_validate) res_cluster = ClusterResource() api.add_route('/instance', res_cluster) res_status = StatusResource() api.add_route('/instance/{vmid}', res_status) res_delete = DeleteResource() api.add_route('/instance/delete/{vmid}', res_delete) res_archivate = ArchivateResource() api.add_route('/instance/archivate/{vmid}', res_archivate) res_unarchive = UnArchiveResource() api.add_route('/instance/unarchive/{vmid}', res_unarchive) res_start = StartResource() api.add_route('/instance/start/{vmid}', res_start) res_shutdown = ShutdownResource() api.add_route('/instance/shutdown/{vmid}', res_shutdown) res_stop = StopResource() api.add_route('/instance/stop/{vmid}', res_stop) res_vnc = VNCResource() api.add_route('/instance/vnc/{vmid}', res_vnc)