#!/usr/bin/python3 # Build 5 ##It can be run directly with "waitress-serve --port=3333 api:api" import falcon import random import os import time import sql # SQL work file import json,yaml from datetime import datetime import sysopt #File of options def logit(text): text = str(text) now = datetime.now() print ("Log: " + text) with open('api.log', 'a') as file: file.write("Log ("+now.strftime("%x %X") + "): ") file.write(text) file.write('\n') class getComputerExists(object): def on_get(self, request, response): logit(request) ComputerName,UUID = None, None for key, value in request.params.items(): if key == "ComputerName": ComputerName = value if key == "UUID": UUID = value if ComputerName is None: response.media = {'RESULT': '0'} else: result = sql.select("SELECT COUNT(*) 'RESULT' FROM COMPUTERS WHERE Name='"+ComputerName+"' AND UUID='"+UUID+"'") if result[0]['RESULT'] == 0: # 0 or 1 if sql.select("SELECT COUNT(*) 'RESULT' FROM COMPUTERS WHERE Name='"+ComputerName+"' AND UUID IS NULL")[0]['RESULT'] != 0: sql.insert("UPDATE COMPUTERS SET UUID='"+UUID+"' WHERE Name='"+ComputerName+"'") response.media = {'RESULT': '1'} return if sysopt.addComputers == True: sql.insert("INSERT INTO COMPUTERS (`Name`,`UUID`) VALUES('"+ComputerName+"','"+UUID+"')") response.media = {'RESULT': '1'} else: response.media = {'RESULT': '0'} else: #Exists response.media = {'RESULT': '1'} class getGroups(object): #Get local groups of a Computer def on_get(self,request, response): logit(request) ComputerID=None for key, value in request.params.items(): if key == "ComputerName": ComputerID = str(sql.select("SELECT ID_C FROM COMPUTERS WHERE Name='"+value+"'")[0]['ID_C']) if key == "ComputerID": ComputerID = value if ComputerID is None: data = sql.select("SELECT * FROM GROUPS") response.media = data else: data = sql.select("SELECT * FROM GROUPS WHERE (SELECT ID_G FROM COMPUTER_GROUP WHERE ID_C = '"+ComputerID+"')") response.media = data class getComputers(object): def on_get(self,request, response): logit(request) ComputerID=None for key, value in request.params.items(): if key == "ComputerName": ComputerID = str(sql.select("SELECT ID_C FROM COMPUTERS WHERE Name='"+value+"'")[0]['ID_C']) if key == "ComputerID": ComputerID = value if ComputerID is None: data = sql.select("SELECT * FROM COMPUTERS") response.media = data else: data = sql.select("SELECT * FROM COMPUTERS WHERE ID_C = '"+ComputerID+"')") response.media = data class getComputersGrp(object): #List of computers in a group def on_get(self,request, response): logit(request) GroupID=None for key, value in request.params.items(): if key == "GroupName": GroupID = str(sql.select("SELECT ID_G FROM GROUPS WHERE Name='"+value+"'")[0]['ID_G']) if key == "GroupID": GroupID = value data = sql.select("SELECT * FROM COMPUTERS WHERE ID_C IN (SELECT ID_C FROM COMPUTER_GROUP WHERE ID_G='"+GroupID+"') ORDER BY Name") response.media = data class getCook(object): # Get the list of cooks for a computer to implement (Var all=1 for see all of, implemented or not) def on_get(self,request, response): logit(request) ComputerID,GroupID, SeeAll =None, None, None for key, value in request.params.items(): if key == "ComputerName": ComputerID = str(sql.select("SELECT ID_C FROM COMPUTERS WHERE Name='"+value+"'")[0]['ID_C']) if key == "ComputerID": ComputerID = value if key == "GroupName": GroupID = str(sql.select("SELECT ID_G FROM GROUPS WHERE Name='"+value+"'")[0]['ID_G']) if key == "GroupID": GroupID = value if key == "SeeAll": SeeAll = str(value) if ComputerID is None and GroupID is None: response.media = {'ERROR': 'I need a Group or Computer to search'} elif ComputerID is not None and SeeAll is None: data = sql.select("SELECT * FROM COOKS_IDG WHERE ID_G IN (SELECT ID_G FROM COMPUTER_GROUP WHERE ID_C = '"+ComputerID+"')") #All cooks for this computer fordelete = [] for i in range(len(data)): for key, value in data[i].items(): #Iterate in a dict (json) if key == 'CookName': CookName = value #Name with open('cooks/'+CookName+'.yaml', 'r') as myfile: filecook = myfile.read() coun = sql.select("SELECT COUNT(*) 'RESULT' FROM COOKS_STATUS WHERE ID_C='"+ComputerID+"' AND CookName='"+CookName+"' AND Revision='"+str(yaml.safe_load(filecook)['revision'])+"' AND `Error`='0'") if coun[0]['RESULT'] == 1: fordelete.append(i) #Its good, do not say to client for x in reversed(fordelete): #Deleting cooks that are implemented in client. Reverse order (Because is an array and index..) data.pop(x) response.media = data else: response.media = sql.select("SELECT * FROM COOKS_IDG WHERE ID_G IN (SELECT ID_G FROM COMPUTER_GROUP WHERE ID_C = '"+ComputerID+"')") #All cooks for this computer class setCook(object): #Assign Cook to group def on_get(self, request, response): logit(request) GroupID, CookName = None, None # Initialize for key, value in request.params.items(): if key == "CookName": exists = os.path.isfile('cooks/'+value+'.yaml') CookName = value if key == "GroupName": GroupID = str(sql.select("SELECT ID_G FROM GROUPS WHERE Name='"+value+"'")[0]['ID_G']) if key == "GroupID": GroupID = value if GroupID is None or exists is False: response.media = {'ERROR': 'GroupID is not defined or Cook not exists'} elif int(sql.select("SELECT COUNT(*) 'COUNT' FROM COOKS_IDG WHERE `ID_G`='"+GroupID+"' AND `CookName`='"+CookName+"'")[0]['COUNT']) > 0: response.media = {'WARNING': 'This union GROUP-CookName exists'} else: result = sql.insert("INSERT INTO COOKS_IDG (`ID_G`,`CookName`) VALUES ('"+GroupID+"','"+CookName+"')") response.media = result class delCookGrp(object): #Delete cook from a group def on_get(self,request,response): logit(request) GroupID, CookName = None, None # Initialize for key, value in request.params.items(): if key == "CookName": exists = os.path.isfile('cooks/'+value+'.yaml') if exists: CookName = value if key == "GroupName": GroupID = str(sql.select("SELECT ID_G FROM GROUPS WHERE Name='"+value+"'")[0]['ID_G']) if key == "GroupID": GroupID = value if GroupID is not None and CookName is not None: result = sql.insert("DELETE FROM COOKS_IDG WHERE ID_G='"+GroupID+"' AND CookName='"+CookName+"'") response.media = result else: response.media = {'RESULT': 'Error, no Group, or CookName does\'t exists'} class delEmptyPcsGroup(object): #Delete all computers from a group def on_get(self,request,response): logit(request) GroupID = None # Initialize for key, value in request.params.items(): if key == "GroupName": GroupID = str(sql.select("SELECT ID_G FROM GROUPS WHERE Name='"+value+"'")[0]['ID_G']) if key == "GroupID": GroupID = value if GroupID is not None: result = sql.insert("DELETE FROM COMPUTER_GROUP WHERE ID_G='"+GroupID+"'") response.media = result else: response.media = {'RESULT': 'Error, this group doesn\'t exists'} class getCookGrp(object): # Get cooks from a Group def on_get(self,request,response): logit(request) GroupID = None # Initialize for key, value in request.params.items(): if key == "GroupName": GroupID = str(sql.select("SELECT ID_G FROM GROUPS WHERE Name='"+value+"'")[0]['ID_G']) if key == "GroupID": GroupID = value if GroupID is not None: result = sql.select("SELECT * FROM COOKS_IDG WHERE ID_G='"+GroupID+"'") response.media = result else: response.media = {'RESULT': 'Error, no Group selected'} class getGrpCook(object): # Get Groups of a Cook def on_get(self,request,response): logit(request) CookName = None # Initialize for key, value in request.params.items(): if key == "CookName": exists = os.path.isfile('cooks/'+value+'.yaml') if exists: CookName = value if CookName is not None: response.media = sql.select("SELECT Name FROM GROUPS WHERE ID_G IN (SELECT ID_G FROM COOKS_IDG WHERE CookName='"+CookName+"')") else: response.media = {'RESULT': 'Error, no Cook selected'} class getStatusCook(object): # Get Status of a Cook (If Brief=1 is sent too, brief status (Completed:X, updated:X..)) def on_get(self,request,response): logit(request) CookName = None # Initialize for key, value in request.params.items(): if key == "CookName": exists = os.path.isfile('cooks/'+value+'.yaml') if exists: CookName = value if CookName is not None: response.media = sql.select("SELECT Name, Revision, Error FROM COMPUTERS,COOKS_STATUS WHERE CookName = '"+CookName+"' AND COMPUTERS.ID_C=COOKS_STATUS.ID_C") else: response.media = {'RESULT': 'Error, no Cook selected'} class getLastRevisionCook(object): # Get Number Revision (Revision=X) def on_get(self,request,response): logit(request) CookName = None # Initialize for key, value in request.params.items(): if key == "CookName": exists = os.path.isfile('cooks/'+value+'.yaml') if exists: CookName = value if CookName is not None: with open('cooks/'+CookName+'.yaml', 'r') as myfile: filecook = myfile.read() response.media = {'Revision': str(yaml.safe_load(filecook)['revision'])} else: response.media = {'RESULT': 'Error, no Cook selected'} class addComputer(object): def on_get(self, request, response): logit(request) ComputerName = None for key,value in request.params.items(): if key == "ComputerName": ComputerName = value if ComputerName is None: response.media = {'RESULT': 'Error, you need a ComputerName to add'} else: result = sql.insert("INSERT INTO COMPUTERS (Name) VALUES ('"+ComputerName+"')") response.media = result class addGroup(object): def on_get(self, request, response): logit(request) GroupName= None for key,value in request.params.items(): if key == "GroupName": GroupName = value if GroupName is None: response.media = {'RESULT': 'Error, you need a GroupName to add'} else: result = sql.insert("INSERT INTO GROUPS (Name) VALUES ('"+GroupName+"')") response.media = result class delGroup(object): #Delete group def on_get(self, request, response): logit(request) GroupID= None for key,value in request.params.items(): if key == "GroupID": GroupID = value if key == "GroupName": GroupID = str(sql.select("SELECT ID_G FROM GROUPS WHERE Name='"+value+"'")[0]['ID_G']) if GroupID is None: response.media = {'RESULT': 'Error, you need a GroupName to delete'} else: sql.insert("DELETE FROM COMPUTER_GROUP WHERE ID_G='"+GroupID+"'") sql.insert("DELETE FROM COOKS_IDG WHERE ID_G='"+GroupID+"'") result = sql.insert("DELETE FROM GROUPS WHERE ID_G='"+GroupID+"'") response.media = result class updGroup(object): #Delete group def on_get(self, request, response): logit(request) GroupID, GroupNewName= None, None for key,value in request.params.items(): if key == "GroupID": GroupID = value if key == "GroupName": GroupID = str(sql.select("SELECT ID_G FROM GROUPS WHERE Name='"+value+"'")[0]['ID_G']) if key == "GroupNewName": Count = str(sql.select("SELECT COUNT(*) 'Count' FROM GROUPS WHERE Name='"+value+"'")[0]['Count']) if Count == "0": GroupNewName = value else: response.media = {'RESULT': 'Error, New group name exists'} if GroupID is None or GroupNewName is None: response.media = {'RESULT': 'Error, you need a GroupName and new name to update name'} else: result = sql.insert("UPDATE GROUPS SET Name='"+GroupNewName+"' WHERE ID_G='"+GroupID+"'") response.media = result class addGrpComputer(object): #Add computer to a group (Local) def on_get(self, request, response): logit(request) ComputerID, GroupID= None, None for key, value in request.params.items(): if key == "ComputerName": ComputerID = str(sql.select("SELECT ID_C FROM COMPUTERS WHERE Name='"+value+"'")[0]['ID_C']) if key == "ComputerID": ComputerID = value if key == "GroupName": GroupID = str(sql.select("SELECT ID_G FROM GROUPS WHERE Name='"+value+"'")[0]['ID_G']) if key == "GroupID": GroupID = value if ComputerID is None or GroupID is None: response.media = {'RESULT': 'Error, you need a Name and Group to add'} else: result = sql.insert("INSERT INTO COMPUTER_GROUP (ID_C,ID_G) VALUES ('"+ComputerID+"','"+GroupID+"')") response.media = result class delGrpComputer(object): #Del computer from a group def on_get(self, request, response): logit(request) ComputerID, GroupID= None, None for key, value in request.params.items(): if key == "ComputerName": ComputerID = str(sql.select("SELECT ID_C FROM COMPUTERS WHERE Name='"+value+"'")[0]['ID_C']) if key == "ComputerID": ComputerID = value if key == "GroupName": GroupID = str(sql.select("SELECT ID_G FROM GROUPS WHERE Name='"+value+"'")[0]['ID_G']) if key == "GroupID": GroupID = value if ComputerID is None or GroupID is None: response.media = {'RESULT': 'Error, you need a Name and Group to add'} else: result = sql.insert("DELETE FROM COMPUTER_GROUP WHERE ID_C='"+ComputerID+"' AND ID_G='"+GroupID+"'") response.media = result class delComputer(object): #Delete computer def on_get(self, request, response): logit(request) ComputerID= None for key, value in request.params.items(): if key == "ComputerName": ComputerID = str(sql.select("SELECT ID_C FROM COMPUTERS WHERE Name='"+value+"'")[0]['ID_C']) if key == "ComputerID": ComputerID = value if ComputerID is None: response.media = {'RESULT': 'Error, you need a Name/ComputerID to update data'} else: sql.insert("DELETE FROM COMPUTER_GROUP WHERE ID_C='"+ComputerID+"'") sql.insert("DELETE FROM COOKS_STATUS WHERE ID_C='"+ComputerID+"'") resp = sql.insert("DELETE FROM COMPUTERS WHERE ID_C='"+ComputerID+"'") logit(resp) class updComputer(object): def on_get(self, request, response): logit(request) ComputerID, UUID= None, None for key, value in request.params.items(): if key == "ComputerName": try: ComputerID = str(sql.select("SELECT ID_C FROM COMPUTERS WHERE Name='"+value+"'")[0]['ID_C']) except: response.media = {'RESULT': 'Error: Computer not exists in database'} break if key == "ComputerID": ComputerID = value if key == "UUID": UUID = value if ComputerID is None and response.media is None: response.media = {'RESULT': 'Error, you need a ComputerName/ComputerID to update data'} elif response.media is None and ComputerID is not None and UUID is not None: Count = str(sql.select("SELECT COUNT(*) 'Count' FROM COMPUTERS WHERE UUID='"+UUID+"' AND ID_C='"+ComputerID+"'")[0]['Count']) if Count == "0": response.media = {'RESULT': 'Error, computer doesn\'t exists in database'} else: for key, value in request.params.items(): if key == "SOVersion": response.media = sql.insert("UPDATE COMPUTERS SET SOVersion ='"+value+"' WHERE ID_C='"+ComputerID+"'") if key == "SOBit": response.media = sql.insert("UPDATE COMPUTERS SET SOBit ='"+value+"' WHERE ID_C='"+ComputerID+"'") if key == "SOCaption": response.media = sql.insert("UPDATE COMPUTERS SET SOCaption ='"+value+"' WHERE ID_C='"+ComputerID+"'") if key == "LastConnection": response.media = sql.insert("UPDATE COMPUTERS SET LastConnection ='"+value+"' WHERE ID_C='"+ComputerID+"'") if key == "LastUser": response.media = sql.insert("UPDATE COMPUTERS SET LastUser='"+value+"' WHERE ID_C='"+ComputerID+"'") if key == "RAM": response.media = sql.insert("UPDATE COMPUTERS SET RAM='"+value+"' WHERE ID_C='"+ComputerID+"'") if key == "CPUName": response.media = sql.insert("UPDATE COMPUTERS SET CPUName='"+value+"' WHERE ID_C='"+ComputerID+"'") class updCookName(object): def on_get(self, request, response): logit(request) CookName, CookNewName= None, None #Initialize for key, value in request.params.items(): if key == "CookName": if os.path.isfile('cooks/'+value+'.yaml'): CookName= value else: response.media = {'RESULT': 'Error: Cook not exists in folder'} break if key == "CookNewName": if os.path.isfile('cooks/'+value+'.yaml'): response.media = {'RESULT': 'Error: There is a cook with the new name in folder!'} break else: CookNewName= value if CookName is None or CookNewName is None: response.media = {'RESULT': 'Error, you need the old and new Cook Name to update data'} elif response.media is None: old_file = os.path.join("cooks", CookName+'.yaml') new_file = os.path.join("cooks", CookNewName+'.yaml') os.rename(old_file, new_file) sql.insert("UPDATE COOKS_IDG SET CookName ='"+CookNewName+"' WHERE CookName='"+CookName+"'") response.media = sql.insert("UPDATE COOKS_STATUS SET CookName ='"+CookNewName+"' WHERE CookName='"+CookName+"'") class loadCook(object): def on_get(self, request, response): logit(request) CookName, ComputerID, UUID= None, None, None #Initialize for key, value in request.params.items(): if key == "CookName": if os.path.isfile('cooks/'+value+'.yaml'): CookName= value else: response.media = {'RESULT': 'Error: Cook not exists in folder'} break if key == "ComputerName": ComputerID = str(sql.select("SELECT ID_C FROM COMPUTERS WHERE Name='"+value+"'")[0]['ID_C']) if key == "ComputerID": ComputerID = value if key == "UUID": UUID = value if CookName is None and response.media is None: response.media = {'RESULT': 'Error, you need a CookName to load it'} elif response.media is None: Count = str(sql.select("SELECT COUNT(*) 'Count' FROM COMPUTERS WHERE UUID='"+UUID+"' AND ID_C='"+ComputerID+"'")[0]['Count']) if Count == "0": response.media = {'RESULT': 'Error, computer doesn\'t exists in database'} else: with open('cooks/'+CookName+'.yaml', 'r') as myfile: data = myfile.read() response.media = yaml.safe_load(data) class setCookStatus(object): def on_get(self, request, response): logit(request) CookName, ComputerID, Revision, Error,ErrorDesc= None, None, None, None, "" for key, value in request.params.items(): if key == "CookName": if os.path.isfile('cooks/'+value+'.yaml'): # You have to know that cook exists. CookName= value else: response.media = {'RESULT': 'Error: Cook not exists in folder'} break if key == "ComputerName": ComputerID = str(sql.select("SELECT ID_C FROM COMPUTERS WHERE Name='"+value+"'")[0]['ID_C']) if key == "ComputerID": ComputerID = value if key == "Revision": Revision = value if key == "Error": Error = value if key == "ErrorDesc": ErrorDesc = value if CookName is None and response.media is None: response.media = {'RESULT': 'Error, you need a CookName to load it'} elif response.media is None and CookName is not None and ComputerID is not None and Revision is not None and Error is not None: statt = sql.select("SELECT COUNT(*) 'RESULT' FROM COOKS_STATUS WHERE CookName='"+CookName+"' AND ID_C='"+ComputerID+"'")[0]['RESULT'] if statt == 0: #INSERT, NEW response.media = sql.insert("INSERT INTO COOKS_STATUS (CookName,ID_C,Revision,`Error`,`ErrorDesc`) VALUES ('"+CookName+"', '"+ComputerID+"', '"+Revision+"','"+Error+"','"+ErrorDesc+"')") else: #UPDATE, NOT NEW response.media = sql.insert("UPDATE COOKS_STATUS SET Revision='"+Revision+"',`Error`='"+Error+"',`ErrorDesc`='"+ErrorDesc+"' WHERE ID_C='"+ComputerID+"' AND CookName='"+CookName+"'") else: response.media = {'RESULT': 'Error in parameters...'} logit(response.media) api = falcon.API() api.add_route('/get/computers', getComputers()) #Get list of computer api.add_route('/get/computerexists', getComputerExists()) #Returns 0 or 1 (name status) api.add_route('/get/groups', getGroups()) #Get groups of a computer (Or list if not args) api.add_route('/get/computersgrp', getComputersGrp()) #Get computers in a group api.add_route('/get/cook', getCook()) #Get cooks from a group api.add_route('/set/cook', setCook()) #Assign cook to group api.add_route('/del/cookgrp', delCookGrp()) # Deassign cook from a group api.add_route('/del/emptypcsgroup', delEmptyPcsGroup()) # Delete all computers from a group api.add_route('/get/cookgrp', getCookGrp()) # See cooks that have a determinated group api.add_route('/get/grpcook', getGrpCook()) # See groups of a determinated cook api.add_route('/get/statuscook', getStatusCook()) # See status of a cook api.add_route('/get/lastrevisioncook', getLastRevisionCook()) # Returns number of last revision of a cook api.add_route('/add/computer', addComputer()) #Add computer api.add_route('/del/computer', delComputer()) #Delete computer api.add_route('/add/group', addGroup()) #Add group to the list of local groups api.add_route('/del/group', delGroup()) #Delete group api.add_route('/upd/group', updGroup()) #Update group name api.add_route('/add/grpcomputer', addGrpComputer()) #Add computer to a group api.add_route('/del/grpcomputer', delGrpComputer()) #Delete computer from a group api.add_route('/upd/computer', updComputer()) #Update data of computer api.add_route('/upd/cookname', updCookName()) #Update file name of cook and SQL references to it. api.add_route('/load/cook', loadCook()) # Load a cook (Transfer in json way) api.add_route('/set/cookstatus', setCookStatus()) # Update status of a cook in a computer