#!/usr/bin/python3 BUILD = 29 API_VER = 2 from flask import Flask, request import random import os import time import sql # SQL work file import json,yaml from datetime import datetime import base64 app = Flask(__name__) sqlAddComputers = sql.retOption('AddComputers') 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') def retPassword(): try: return sql.select("SELECT Value FROM OPTIONS WHERE Option='Password'")[0]['Value'] except: return "" ## # getComputerExists: Know if computer exists and matches UUID # /get/computerexists? # @param ComputerName -> Computer to deploy it # @param UUID: Check UUID validation of this computer # Error exit code: # 1: No params supplied # 2: Computer and UUID not match database # 3: Computer doesn't exists in database ## @app.route("/get/computerexists",methods=['POST']) def getComputerExists(): logit(request.base_url) ComputerName,UUID = None, None for key, value in request.args.to_dict().items(): if key == "ComputerName": ComputerName = value if key == "UUID": UUID = value if ComputerName is None: return str({'TEXT':'No params','RESULT': 'ERROR','EXITCODE':'1'}) 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: #UUID doesn't in database, insert it sql.insert("UPDATE COMPUTERS SET UUID='"+UUID+"' WHERE Name='"+ComputerName+"'") return str({'RESULT': '1'}) elif sql.select("SELECT COUNT(*) 'RESULT' FROM COMPUTERS WHERE Name='"+ComputerName+"'")[0]['RESULT'] != 0: #Not UUID match, but computer exists return str({'TEXT': 'Error, computer and UUID doesn\'t match in database', 'RESULT': 'ERROR','EXITCODE':'2'}) if sqlAddComputers == 'True': #Computer doesn't exist, but you have enabled add all computers sql.insert("INSERT INTO COMPUTERS (`Name`,`UUID`) VALUES('"+ComputerName+"','"+UUID+"')") return str({'RESULT': '1'}) else: #Computer doesn't exist and you don't want to be added return str({'TEXT':'Error: Computer not exists in database', 'RESULT': 'ERROR','EXITCODE':'3'}) else: #Exists return str({'RESULT': '1'}) ## # getGroupID: Return GroupID from GroupName # /get/groupid? # @param ComputerName/ComputerID -> Computer to see groups (Not neccesary) # @param GroupID -> For know Name of a GroupID ## @app.route("/get/groupid",methods=['POST']) def getGroupID(): #Get local groups of a Computer logit(request.base_url) GroupName=None for key, value in request.args.to_dict().items(): if key == "GroupName": GroupID = str(sql.select("SELECT ID_G FROM GROUPS WHERE Name='"+value+"'")[0]['ID_G']) if GroupID is not None: return GroupID else: return str({'TEXT': 'I need a valid GroupName for returning GroupID','RESULT':'ERROR'}) ## # getGroups: Know all groups, or groups of a computer # /get/groups? # @param ComputerName/ComputerID -> Computer to see groups (Not neccesary) # @param GroupID -> For know Name of a GroupID ## @app.route("/get/groups",methods=['POST']) def getGroups(): #Get local groups of a Computer logit(request.base_url) ComputerID,GroupID=None,None for key, value in request.args.to_dict().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 == "GroupID": GroupID = value if GroupID is not None: return str(sql.select("SELECT * FROM GROUPS WHERE ID_G='"+str(GroupID)+"' LIMIT 1")[0]) #NOT RETURNS A TABLE if ComputerID is None: return str(sql.select("SELECT * FROM GROUPS ORDER BY Name ASC")) else: return str(sql.select("SELECT * FROM GROUPS WHERE ID_G IN (SELECT ID_G FROM COMPUTER_GROUP WHERE ID_C = '"+ComputerID+"') ORDER BY Name ASC")) ## # getComputers: List all computers with data # /get/computers? # @param ComputerID/ComputerName -> To see all data only for one computer ## @app.route("/get/computers",methods=['POST']) def getComputers(): logit(request.base_url) ComputerID=None for key, value in request.args.to_dict().items(): if key == "ComputerName": ComputerID = str(sql.select("SELECT ID_C FROM COMPUTERS WHERE Name='"+value+"' LIMIT 1")[0]['ID_C']) if key == "ComputerID": ComputerID = value if ComputerID is not None: # One computer data = sql.select("SELECT * FROM COMPUTERS WHERE ID_C = '"+ComputerID+"' ORDER BY Name ASC LIMIT 1") return str(data) else: # All computers data = sql.select("SELECT * FROM COMPUTERS ORDER BY Name ASC") return str(data) ## # getComputersGrp: Know all computers that have this group # /get/computersgrp? # @param GroupName/GroupID -> Group to see computers ## @app.route("/get/computersgrp",methods=['POST']) def getComputersGrp(): logit(request.base_url) GroupID=None for key, value in request.args.to_dict().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") return str(data) ## # getCookAll: Get the list of all cooks (Or all added at least to one group) # /get/cookall? # @param OnlyAdded: Show only added cooks ## @app.route("/get/cookall",methods=['POST']) def getCookAll(): logit(request.base_url) OnlyAdded =None for key, value in request.args.to_dict().items(): if key == "OnlyAdded": OnlyAdded= 1 if OnlyAdded is None: x = [] for file in os.listdir("cooks"): if file.endswith(".yaml"): x.append(str(file.replace('.yaml','')).lower()) data = {} data['CookName'] = x else: data = sql.select("SELECT DISTINCT CookName FROM COOKS_IDG ORDER BY CookName ASC") #All cooks return str(data) ## # getCookPend: Get the list of cooks that are pending to deploy to a computer # /get/cookpend? # @param ComputerName/ComputerID -> Computer to deploy it # @param GroupName/GroupID: Groups # @param SeeAll: Send all cooks from this computer # @param UUID: Check UUID validation of this computer (Not implemented yet) ## @app.route("/get/cookpend",methods=['POST']) def getCookPend(): # Get the list of cooks for a computer to implement (Var all=1 for see all of, implemented or not) logit(request.base_url) ComputerID,GroupID, SeeAll =None, None, None for key, value in request.args.to_dict().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: # Error of null parameters return str({'TEXT': 'I need a Group or Computer to search','RESULT':'ERROR'}) elif ComputerID is not None and SeeAll is None: data = sql.select("SELECT DISTINCT CookName 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) return str(data) else: # SeeAll. Send all cooks return str(sql.select("SELECT DISTINCT CookName FROM COOKS_IDG WHERE ID_G IN (SELECT ID_G FROM COMPUTER_GROUP WHERE ID_C = '"+ComputerID+"') ORDER BY CookName ASC")) #All cooks for this computer ## # addCookGrp: Assign Cook to group # /add/cookgrp? # @param GroupName/GroupID -> Group to show cooks # @param CookName -> Cook to assign # @param Password -> Password to validate ## @app.route("/add/cookgrp",methods=['POST']) def addCookGrp(): #Assign Cook to group logit(request.base_url) GroupID, CookName, Password = None, None, None # Initialize for key, value in request.args.to_dict().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 key == "Password" and value == retPassword(): Password=value if GroupID is None or exists is False: return str({'TEXT': 'GroupID is not defined or Cook not exists','RESULT':'ERROR'}) elif Password is None: # Validate password return str({'TEXT': 'Invalid password','RESULT':'ERROR'}) elif int(sql.select("SELECT COUNT(*) 'COUNT' FROM COOKS_IDG WHERE `ID_G`='"+GroupID+"' AND `CookName`='"+CookName+"'")[0]['COUNT']) > 0: return str({'TEXT': 'This union GROUP-CookName exists','RESULT':'0'}) else: result = sql.insert("INSERT INTO COOKS_IDG (`ID_G`,`CookName`) VALUES ('"+GroupID+"','"+CookName+"')") return str(result) #str({'TEXT': 'OK'}) ? ## # delCookGrp: Delete cook from a group # /del/cookgrp? # @param GroupName/GroupID -> Group to show cooks # @param CookName -> Cook to assign ## @app.route("/del/cookgrp",methods=['POST']) def delCookGrp(): #Delete cook from a group logit(request.base_url) GroupID, CookName = None, None # Initialize for key, value in request.args.to_dict().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+"'") cleanDatabase() return str({'TEXT': '','RESULT':'0'}) #Return text str(result) is problematic (json inside json) else: return str({'TEXT': 'Error, no Group, or CookName doesnt exists','RESULT':'ERROR'}) ## # delEmptyPcsGroup: Delete all computers from from a group # /del/emptypcsgroup? # @param GroupName/GroupID -> Group to delete computers ## @app.route("/del/emptypcsgroup",methods=['POST']) def delEmptyPcsGroup(): logit(request.base_url) GroupID = None # Initialize for key, value in request.args.to_dict().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+"'") return str(result) else: return str({'TEXT': 'Error, this group doesnt exists','RESULT':'ERROR'}) ## # getCookGrp: Get cooks from a Group # /get/cookgrp? # @param GroupName/GroupID -> Group to show cooks ## @app.route("/get/cookgrp",methods=['POST']) def getCookGrp(): logit(request.base_url) GroupID = None # Initialize for key, value in request.args.to_dict().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+"' ORDER BY CookName ASC") return str(result) else: return str({'TEXT': 'Error, no Group selected','RESULT':'ERROR'}) ## # getGrpCook: Get groups from a Cook # /get/grpcook? # @param CookName -> Cook to show groups ## @app.route("/get/grpcook",methods=['POST']) def getGrpCook(): logit(request.base_url) CookName = None # Initialize for key, value in request.args.to_dict().items(): if key == "CookName": exists = os.path.isfile('cooks/'+value+'.yaml') if exists: CookName = value if CookName is not None: return str(sql.select("SELECT Name FROM GROUPS WHERE ID_G IN (SELECT ID_G FROM COOKS_IDG WHERE CookName='"+CookName+"') ORDER BY Name ASC")) else: return str({'TEXT': 'Error, no Cook selected','RESULT':'ERROR'}) ## # getStatusCook: Get groups from a Cook # /get/statuscook? # @param CookName -> Cook to show detailed status ## @app.route("/get/statuscook",methods=['POST']) def getStatusCook(): # Get Status of a Cook (If Brief=1 is sent too, brief status (Completed:X, updated:X..)) logit(request.base_url) CookName = None # Initialize for key, value in request.args.to_dict().items(): if key == "CookName": exists = os.path.isfile('cooks/'+value+'.yaml') if exists: CookName = value if CookName is not None: return str(sql.select("SELECT Name, Revision, Error FROM COMPUTERS,COOKS_STATUS WHERE CookName = '"+CookName+"' AND COMPUTERS.ID_C=COOKS_STATUS.ID_C ORDER BY Name ASC")) else: return str({'TEXT': 'Error, no Cook selected','RESULT':'ERROR'}) ## # getLastRevisionCook: Get last revision from a Cook # /get/lastrevisioncook? # @param CookName -> Cook to show detailed status ## @app.route("/get/lastrevisioncook",methods=['POST']) def getLastRevisionCook(): # Get Number Revision (Revision=X) logit(request.base_url) CookName = None # Initialize for key, value in request.args.to_dict().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() return str({'Revision': str(yaml.safe_load(filecook)['revision'])}) else: return str({'TEXT': 'Error, no Cook selected','RESULT':'ERROR'}) ## # addComputer: Add a computer in database # /add/computer? # @param ComputerName -> ComputerName to add ## @app.route("/add/computer",methods=['POST']) def addComputer(): logit(request.base_url) ComputerName = None for key,value in request.args.to_dict().items(): if key == "ComputerName": ComputerName = value if ComputerName is None: return str({'TEXT': 'Error, you need a ComputerName to add','RESULT':'ERROR'}) else: result = sql.insert("INSERT INTO COMPUTERS (Name) VALUES ('"+ComputerName+"')") return str(result) ## # addGroup: Add a new group # /add/group? # @param GroupName -> Name of group to add ## @app.route("/add/group",methods=['POST']) def addGroup(): logit(request.base_url) GroupName= None for key,value in request.args.to_dict().items(): if key == "GroupName": GroupName = value if GroupName is None: return str({'TEXT': 'Error, you need a GroupName to add','RESULT':'ERROR'}) else: result = sql.insert("INSERT INTO GROUPS (Name) VALUES ('"+GroupName+"')") return str(result) ## # delGroup: Delete a group and all tables that has it. # /del/group? # @param GroupName/GroupID -> Name of group to delete ## @app.route("/del/group",methods=['POST']) def delGroup(): logit(request.base_url) GroupID= None for key,value in request.args.to_dict().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: return str({'TEXT': 'Error, you need a GroupName to delete','RESULT':'ERROR'}) 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+"'") return str(result) ## # delCook: Delete a cook and all tables that has it. It doesn't delete files # /del/cook? # @param CookName -> Name of cook to disappear ## @app.route("/del/cook",methods=['POST']) def delCook(): logit(request.base_url) CookName = None, None # Initialize for key, value in request.args.to_dict().items(): if key == "CookName": exists = os.path.isfile('cooks/'+value+'.yaml') if exists: CookName = value if CookName is not None: sql.insert("DELETE FROM COOKS_ONETIME WHERE CookName='"+CookName+"'") sql.insert("DELETE FROM COOKS_STATUS WHERE CookName='"+CookName+"'") result = sql.insert("DELETE FROM COOKS_IDG WHERE CookName='"+CookName+"'") return str(result) else: return str({'TEXT': 'Error, CookName don\'t exists','RESULT':'ERROR'}) ## # delGroupsCook: Delete groups of a cook # /del/groupscook? # @param CookName -> Name of cook to make his groups disappear ## @app.route("/del/groupscook",methods=['POST']) def delGroupsCook(): logit(request.base_url) CookName = None, None # Initialize for key, value in request.args.to_dict().items(): if key == "CookName": exists = os.path.isfile('cooks/'+value+'.yaml') if exists: CookName = value if CookName is not None: result = sql.insert("DELETE FROM COOKS_IDG WHERE CookName='"+CookName+"'") return str(result) else: return str({'TEXT': 'Error, CookName don\'t exists','RESULT':'ERROR'}) ## # delCleanCook: Delete groups of a cook # /del/cleancook? # @param CookName -> Clean status of a cook (Restart it) ## @app.route("/del/cleancook",methods=['POST']) def delCleanCook(): logit(request.base_url) CookName = None, None # Initialize for key, value in request.args.to_dict().items(): if key == "CookName": exists = os.path.isfile('cooks/'+value+'.yaml') if exists: CookName = value if CookName is not None: result = sql.insert("DELETE FROM COOKS_STATUS WHERE CookName='"+CookName+"'") return str(result) else: return str({'TEXT': 'Error, CookName don\'t exists','RESULT':'ERROR'}) ## # updGroup: Update Group Name # /upd/group? # @param GroupID/GroupName -> Actual ID / Name of group # @param GroupNewName -> New name for group ## @app.route("/upd/group",methods=['POST']) def updGroup(): logit(request.base_url) GroupID, GroupNewName= None, None for key,value in request.args.to_dict().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: return str({'TEXT': 'Error, New group name exists','RESULT':'ERROR'}) if GroupID is None or GroupNewName is None: return str({'TEXT': 'Error, you need a GroupName and new name to update name','RESULT':'ERROR'}) else: result = sql.insert("UPDATE GROUPS SET Name='"+GroupNewName+"' WHERE ID_G='"+GroupID+"'") return str(result) ## # addGrpComputer: Add computer to a group # /add/grpcomputer? # @param GroupID/GroupName-> ID or Name of group # @param ComputerID/ComputerName -> ID or Name of computer ## @app.route("/add/grpcomputer",methods=['POST']) def addGrpComputer(): logit(request.base_url) ComputerID, GroupID= None, None for key, value in request.args.to_dict().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: return str({'TEXT': 'Error, you need a Name and Group to add','RESULT':'ERROR'}) else: result = sql.insert("INSERT INTO COMPUTER_GROUP (ID_C,ID_G) VALUES ('"+ComputerID+"','"+GroupID+"')") return str(result) ## # delGrpComputer: Delete computer from a group # /del/grpcomputer? # @param GroupID/GroupName-> ID or Name of group # @param ComputerID/ComputerName -> ID or Name of computer ## @app.route("/del/grpcomputer",methods=['POST']) def delGrpComputer(): logit(request.base_url) ComputerID, GroupID= None, None for key, value in request.args.to_dict().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: return str({'TEXT': 'Error, you need a Name and Group to add','RESULT':'ERROR'}) else: result = sql.insert("DELETE FROM COMPUTER_GROUP WHERE ID_C='"+ComputerID+"' AND ID_G='"+GroupID+"'") return str(result) ## # delComputer: Delete computer and data of it # /del/computer? # @param ComputerName/ComputerID -> Computer ID or Name # @param Password -> Password validated command ## @app.route("/del/computer",methods=['POST']) def delComputer(): logit(request.base_url) ComputerID= None for key, value in request.args.to_dict().items(): if key == "ComputerName": ComputerID = str(sql.select("SELECT ID_C FROM COMPUTERS WHERE Name='"+value+"'")[0]['ID_C']) if key == "ComputerID": ComputerID = str(sql.select("SELECT ID_C FROM COMPUTERS WHERE ID_C='"+value+"'")[0]['ID_C']) if key == "Password" and value == retPassword(): Password=value if Password is None: return str({'TEXT': 'Invalid password','RESULT':'ERROR'}) elif ComputerID is None: return str({'TEXT': 'Error, you need a Name/ComputerID to update data','RESULT':'ERROR'}) elif ComputerID=='': return str({'TEXT': 'Error, this Name/ID is not valid','RESULT':'ERROR'}) 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) ## # updComputer: Update computer data # /upd/computer? # @param ComputerID -> Computer ID # @param UUID -> UUID of computer # No need password, validate from ComputerID+UUID for updates.. ## @app.route("/upd/computer",methods=['POST']) def updComputer(): logit(request.base_url) ComputerID, UUID = None, None for key, value in request.args.to_dict().items(): if key == "ComputerName": try: ComputerID = str(sql.select("SELECT ID_C FROM COMPUTERS WHERE Name='"+value+"'")[0]['ID_C']) except: return str({'TEXT': 'Error: Computer not exists in database','RESULT':'ERROR','EXITCODE':'1'}) if key == "ComputerID": ComputerID = value if key == "UUID": UUID = value if ComputerID is None: return str({'TEXT': 'Error, you need a ComputerName/ComputerID to update data','RESULT':'ERROR'}) elif 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": return str({'TEXT': 'Error, computer and UUID doesn\'t match in database','RESULT':'ERROR','EXITCODE':'2'}) else: for key, value in request.args.to_dict().items(): if key == "SOVersion": str(sql.insert("UPDATE COMPUTERS SET SOVersion ='"+value+"' WHERE ID_C='"+ComputerID+"'")) if key == "SOBit": str(sql.insert("UPDATE COMPUTERS SET SOBit ='"+value+"' WHERE ID_C='"+ComputerID+"'")) if key == "SOCaption": str(sql.insert("UPDATE COMPUTERS SET SOCaption ='"+value+"' WHERE ID_C='"+ComputerID+"'")) if key == "LastConnection": str(sql.insert("UPDATE COMPUTERS SET LastConnection ='"+value+"' WHERE ID_C='"+ComputerID+"'") ) if key == "LastUser": str(sql.insert("UPDATE COMPUTERS SET LastUser='"+value+"' WHERE ID_C='"+ComputerID+"'")) if key == "RAM": str(sql.insert("UPDATE COMPUTERS SET RAM='"+value+"' WHERE ID_C='"+ComputerID+"'")) if key == "CPUName": str(sql.insert("UPDATE COMPUTERS SET CPUName='"+value+"' WHERE ID_C='"+ComputerID+"'")) if key == "RAMFree": str(sql.insert("UPDATE COMPUTERS SET RAMFree='"+str(value)+"' WHERE ID_C='"+ComputerID+"'")) if key == "HDD": str(sql.insert("UPDATE COMPUTERS SET HDD='"+str(value)+"' WHERE ID_C='"+ComputerID+"'")) return str({'RESULT':'1','TEXT':'OK','EXITCODE':'0'}) ## # updCookName: Rename cook name # /upd/cookname? # @param CookName -> Original Cook Name # @param CookNewName -> New Cook Name # @param Password -> Password validated command ## @app.route("/upd/cookname",methods=['POST']) def updCookName(): logit(request.base_url) CookName, CookNewName,Password= None, None,None #Initialize for key, value in request.args.to_dict().items(): if key == "CookName": if os.path.isfile('cooks/'+value+'.yaml'): CookName= value else: return str({'TEXT': 'Error: Cook not exists in folder','RESULT':'ERROR'}) if key == "CookNewName": if os.path.isfile('cooks/'+value+'.yaml'): return str({'TEXT': 'Error: There is a cook with the new name in folder!','RESULT':'ERROR'}) else: CookNewName= value if key == "Password" and value == retPassword(): Password=value if Password is None: return str({'TEXT': 'Invalid password','RESULT':'ERROR'}) elif CookName is None or CookNewName is None: return str({'TEXT': 'Error, you need the old and new Cook Name to update data','RESULT':'ERROR'}) else: #Do it. 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+"'") return str(sql.insert("UPDATE COOKS_STATUS SET CookName ='"+CookNewName+"' WHERE CookName='"+CookName+"'")) ## # loadCook: Load a Cook # /load/cook? # @param ComputerID/ComputerName -> ID or Name of computer # @param UUID -> UUID of ComputerID # @param CookName -> Name of the cook ## @app.route("/load/cook",methods=['POST']) def loadCook(): logit(request.base_url) CookName, ComputerID, UUID= None, None, None #Initialize for key, value in request.args.to_dict().items(): if key == "CookName": if os.path.isfile('cooks/'+value+'.yaml'): CookName= value else: return str({'TEXT': 'Error: Cook not exists in folder','RESULT':'ERROR'}) 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: return str({'TEXT': 'Error, you need a CookName to load it','RESULT':'ERROR'}) else: Count = str(sql.select("SELECT COUNT(*) 'Count' FROM COMPUTERS WHERE UUID='"+UUID+"' AND ID_C='"+ComputerID+"'")[0]['Count']) if Count == "0": return str({'TEXT': 'Error, computer doesn\'t exists in database','RESULT':'ERROR'}) else: with open('cooks/'+CookName+'.yaml', 'r') as myfile: data = myfile.read() return str(yaml.safe_load(data)) ## # setCookStatus: Set status of a executed Cook # /set/cookstatus? # @param ComputerID/ComputerName -> ID or Name of computer # @param CookName -> Name of the cook # @param Revision -> Revision of cook applied # @param Error -> Output, 0 if not error # @param ErrorDesc -> Optional, if error ocurred, description ## @app.route("/set/cookstatus",methods=['POST']) def setCookStatus(): logit(request.base_url) CookName, ComputerID, Revision, Error,ErrorDesc= None, None, None, None, "" for key, value in request.args.to_dict().items(): if key == "CookName": if os.path.isfile('cooks/'+value+'.yaml'): # You have to know that cook exists. CookName= value else: return str({'TEXT': 'Error: Cook not exists in folder','RESULT':'ERROR'}) 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: return str({'TEXT': 'Error, you need a CookName to load it','RESULT':'ERROR'}) elif 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 return str(sql.insert("INSERT INTO COOKS_STATUS (CookName,ID_C,Revision,`Error`,`ErrorDesc`) VALUES ('"+CookName+"', '"+ComputerID+"', '"+Revision+"','"+Error+"','"+ErrorDesc+"')")) else: #UPDATE, NOT NEW return str(sql.insert("UPDATE COOKS_STATUS SET Revision='"+Revision+"',`Error`='"+Error+"',`ErrorDesc`='"+ErrorDesc+"' WHERE ID_C='"+ComputerID+"' AND CookName='"+CookName+"'")) else: return str({'TEXT': 'Error in parameters...','RESULT':'ERROR'}) ## # checkPassword: Check password # /check/password? # @param Password -> SHA-256 of password # Error exit code: # 0: No error # 1: No password supplied # 2: Password incorrect # 3: Password not set in app yet ## @app.route("/check/password",methods=['POST']) def checkPassword(): #Check password (ERROR if password not valid or no password and 1 if valid) logit(request.base_url) Password= None for key, value in request.args.to_dict().items(): if key == "Password": Password = value if Password is None: return str({'TEXT': 'Error, you need to supply a password','RESULT':'ERROR','EXITCODE':'1'}) else: res = sql.select("SELECT COUNT(*) 'RESULT' FROM OPTIONS WHERE Option='Password' AND Value='"+Password+"'")[0]['RESULT'] if res == 1: return str({'RESULT':'1','TEXT':'OK','EXITCODE':'0'}) else: res = sql.select("SELECT COUNT(*) 'RESULT' FROM OPTIONS WHERE Option='Password'")[0]['RESULT'] if res == 0: #Password doesn't exists in database return str({'RESULT':'ERROR','TEXT':'No password set. Please set it','EXITCODE':'3'}) else: return str({'RESULT':'ERROR','TEXT':'Password incorrect','EXITCODE':'2'}) ## # updPassword: Update password # /upd/password? # @param OldPassword -> SHA-256 of password (Old) # @param NewPassword -> SHA-256 of password (New) ## @app.route("/upd/password",methods=['POST']) def updPassword(): #Update password (ERROR if password not valid or no password and 1 if changed) logit(request.base_url) OldPassword,NewPassword= None, None for key, value in request.args.to_dict().items(): if key == "NewPassword": NewPassword = value if key == "OldPassword": OldPassword = value res = sql.select("SELECT COUNT(*) 'RESULT' FROM OPTIONS WHERE Option='Password'")[0]['RESULT'] if res == 0 and NewPassword is not None: #Password doesn't exists in database return str(sql.insert("INSERT INTO OPTIONS VALUES('Password','"+NewPassword+"')")) elif res == 0 and NewPassword is None: #No password supplied return str({'RESULT':'ERROR','TEXT':'Error, you need to supply a password'}) elif res == 1 and OldPassword is not None: # Password exists in database (And you supplied OldPassword) res = sql.select("SELECT COUNT(*) 'RESULT' FROM OPTIONS WHERE Option='Password' AND Value='"+OldPassword+"'")[0]['RESULT'] if res == 0: # Old password incorrect return str({'RESULT':'ERROR','TEXT':'Old password incorrect'}) elif res == 1 and NewPassword is not None: # All is supplied return str(sql.insert("UPDATE OPTIONS SET Value='"+NewPassword+"' WHERE Option='Password'")) else: return str({'RESULT':'ERROR', 'TEXT':'No password supplied or bad args'}) else: return str({'RESULT':'ERROR', 'TEXT':'No password supplied or bad args'}) ## # getOptionValue: Get Option # /get/optionvalue? # @param Password -> SHA-256 of password # @param Option -> Option ID ## @app.route("/get/optionvalue",methods=['POST']) def getOptionValue(): logit(request.base_url) Password,Option= None,None for key, value in request.args.to_dict().items(): if key == "Option": Option = value if key == "Password" and value == retPassword(): Password=value if Password is None: return str({'TEXT': 'Invalid password','RESULT':'ERROR'}) else: return sql.select("SELECT VALUE FROM OPTIONS WHERE Option='"+str(Option)+"'")[0] def cleanDatabase(): sql.insert("DELETE FROM COOKS_STATUS WHERE CookName NOT IN (SELECT CookName FROM COOKS_IDG)") sq = sql.select("SELECT ID_C FROM COMPUTERS") for val in sq: sql.insert("DELETE FROM COOKS_STATUS WHERE ID_C='"+str(val['ID_C'])+"' AND CookName NOT IN (SELECT DISTINCT CookName FROM COOKS_IDG WHERE ID_G IN (SELECT ID_G FROM COMPUTER_GROUP WHERE ID_C='"+str(val['ID_C'])+"'))") return 0 @app.route('/get/apiver',methods=['POST']) def getApiVer(): return str({'API':API_VER}) print("Build: "+str(BUILD)) print("API Version: "+str(API_VER)) print("Cleaning database before start..") cleanDatabase() app.run(debug=False,port=3333,ssl_context='adhoc',host='0.0.0.0',threaded=True)