3 * ============LICENSE_START=======================================================
5 * ================================================================================
6 * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
7 * ================================================================================
8 * Licensed under the Apache License, Version 2.0 (the "License");
9 * you may not use this file except in compliance with the License.
10 * You may obtain a copy of the License at
12 * http://www.apache.org/licenses/LICENSE-2.0
14 * Unless required by applicable law or agreed to in writing, software
15 * distributed under the License is distributed on an "AS IS" BASIS,
16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 * See the License for the specific language governing permissions and
18 * limitations under the License.
19 * ============LICENSE_END=========================================================
20 * ECOMP is a trademark and service mark of AT&T Intellectual Property.
24 import time, datetime, json, os, sys, subprocess, re
32 from cherrypy.lib.httputil import parse_query_string
33 from cherrypy.lib import auth_basic
35 from multiprocessing import Process, Manager
37 from AnsibleModule import ansibleSysCall
40 from AnsibleSql import readPlaybook, readCredentials
42 from os import listdir
43 from os.path import isfile, join
45 TestRecord = Manager().dict()
49 p = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
50 output = p.stdout.readlines()
53 for i in range(len(output)):
54 output[i] = output[i].strip()
57 def callback (Id, Result, Output, Log, returncode):
59 print "***> in RestServer.callback"
62 time_now = datetime.datetime.utcnow()
63 delta_time = (time_now - TestRecord[Id]['Time']).total_seconds()
64 Result['PlaybookName'] = TestRecord[Id]['PlaybookName']
65 Result['Version'] = TestRecord[Id]['Version']
67 Result['StatusCode'] = 500
68 Result['StatusMessage'] = "TERMINATED"
70 Result['StatusCode'] = 200
71 Result['StatusMessage'] = "FINISHED"
73 # Need to update the whole data structure for key=Id otherwise Manager is not updated
74 TestRecord[Id] = {'PlaybookName': TestRecord[Id]['PlaybookName'],
75 'LCM': TestRecord[Id]['LCM'],
76 'Version': TestRecord[Id]['Version'],
77 'NodeList': TestRecord[Id]['NodeList'],
78 'HostGroupList': TestRecord[Id]['HostGroupList'],
79 'HostNameList': TestRecord[Id]['HostNameList'],
80 'Time': TestRecord[Id]['Time'],
81 'Timeout': TestRecord[Id]['Timeout'],
82 'Duration': str(delta_time),
83 'EnvParameters': TestRecord[Id]['EnvParameters'],
84 'LocalParameters': TestRecord[Id]['LocalParameters'],
85 'FileParameters': TestRecord[Id]['FileParameters'],
86 'CallBack': TestRecord[Id]['CallBack'],
90 'Path': TestRecord[Id]['Path'],
91 'Mandatory': TestRecord[Id]['Path']}
93 if not TestRecord[Id]['CallBack'] == None:
95 # Posting results to callback server
97 data = {"StatusCode": 200,
98 "StatusMessage": "FINISHED",
99 "PlaybookName": TestRecord[Id]["PlaybookName"],
100 "Version": TestRecord[Id]["Version"],
101 "Duration": TestRecord[Id]["Duration"],
102 "Results": TestRecord[Id]['Result']['Results']}
104 if not TestRecord[Id]['Output']['Output'] == {}:
105 for key in data["Results"]:
106 if key in TestRecord[Id]['Output']['Output']:
107 data["Results"][key]["Output"] = TestRecord[Id]['Output']['Output'][key]
109 print " Posting to", TestRecord[Id]['CallBack']
111 s = requests.Session()
112 r = s.post(TestRecord[Id]['CallBack'], data = json.dumps(data),
113 headers = {'content-type': 'application/json'})
114 print " Response", r.status_code, r.text
116 def RunAnsible_Playbook (callback, Id, Inventory, Playbook, NodeList, TestRecord,
119 print "***> in RestServer.RunAnsible_Playbook"
121 # Run test in playbook for given target
124 retval, log, returncode = ansibleSysCall (Inventory, Playbook, NodeList,
125 TestRecord[Id]['Mandatory'],
126 TestRecord[Id]['EnvParameters'],
127 TestRecord[Id]['LocalParameters'],
128 TestRecord[Id]['LCM'],
129 TestRecord[Id]['Timeout'])
132 print " returncode:", returncode
133 print " retval: ", retval
137 Output = {'Output': {}}
139 onlyfiles = [f for f in listdir(Path)
140 if isfile(join(Path, f))]
142 for file in onlyfiles:
143 if "results.txt" in file:
144 f = open(Path + "/" + file, "r")
145 key = file.split("_")[0]
146 Output['Output'][key] = f.read()
149 Result = {'Results': {}}
150 if 'could not be found' in Log:
151 Result['Results'] = {"StatusCode": 101,
152 "StatusMessage": "PLAYBOOK NOT FOUND"}
153 if returncode == 137:
154 Result['Results'] = {"StatusCode": 500,
155 "StatusMessage": "TERMINATED"}
157 elif TestRecord[Id]['NodeList'] == []:
161 if 'TargetNode' in TestRecord[Id]['EnvParameters']:
162 targetlist = TestRecord[Id]['EnvParameters']['TargetNode'].split(' ')
164 targetlist = ["localhost"]
167 for i in range (len(targetlist)):
168 if key in targetlist[i]:
171 if int(retval[key][0]) > 0 and int(retval[key][2]) == 0 and \
172 int(retval[key][3]) == 0:
175 Result['Results'][targetlist[host_index]] = \
176 {"GroupName": 'na', "StatusCode": 200, \
177 "StatusMessage": "SUCCESS"}
179 Result['Results'][key] = \
180 {"GroupName": 'na', "StatusCode": 200, \
181 "StatusMessage": "SUCCESS"}
182 elif int(retval[key][2]) > 0:
184 Result['Results'][targetlist[host_index]] = \
185 {"GroupName": 'na', "StatusCode": 400, \
186 "StatusMessage": "NOT REACHABLE"}
188 Result['Results'][key] = \
189 {"GroupName": 'na', "StatusCode": 400, \
190 "StatusMessage": "NOT REACHABLE"}
191 elif int(retval[key][3]) > 0:
193 Result['Results'][targetlist[host_index]] = \
194 {"GroupName": 'na', "StatusCode": 400, \
195 "StatusMessage": "FAILURE"}
197 Result['Results'][key] = \
198 {"GroupName": 'na', "StatusCode": 400, \
199 "StatusMessage": "FAILURE"}
204 if len(TestRecord[Id]['HostNameList']) > 0:
207 for i in range (len(TestRecord[Id]['HostNameList'])):
208 if key in TestRecord[Id]['HostNameList'][i]:
211 if int(retval[key][0]) > 0 and int(retval[key][2]) == 0 and \
212 int(retval[key][3]) == 0:
214 if len(host_index) > 0:
215 Result['Results'][TestRecord[Id]['HostNameList'][host_index[0]]] = \
216 {"GroupName": TestRecord[Id]['HostGroupList'][host_index[0]],
217 "StatusCode": 200, "StatusMessage": "SUCCESS"}
219 for i in range (1, len(host_index)):
220 Result['Results'][TestRecord[Id]['HostNameList'][host_index[i]]]["GroupName"]+=\
221 "," + TestRecord[Id]['HostGroupList'][host_index[i]]
223 Result['Results'][key] = \
225 "StatusCode": 200, "StatusMessage": "SUCCESS"}
227 elif int(retval[key][2]) > 0:
229 if len(host_index) > 0:
230 Result['Results'][TestRecord[Id]['HostNameList'][host_index[0]]] = \
231 {"GroupName": TestRecord[Id]['HostGroupList'][host_index[0]],
232 "StatusCode": 400, "StatusMessage": "NOT REACHABLE"}
234 for i in range (1, len(host_index)):
235 Result['Results'][TestRecord[Id]['HostNameList'][host_index[i]]]["GroupName"]+=\
236 "," + TestRecord[Id]['HostGroupList'][host_index[i]]
238 Result['Results'][key] = \
240 "StatusCode": 200, "StatusMessage": "NOT REACHABLE"}
242 elif int(retval[key][3]) > 0:
244 if len(host_index) > 0:
245 Result['Results'][TestRecord[Id]['HostNameList'][host_index[0]]] = \
246 {"GroupName": TestRecord[Id]['HostGroupList'][host_index[0]],
247 "StatusCode": 400, "StatusMessage": "FAILURE"}
249 for i in range (1, len(host_index)):
250 Result['Results'][TestRecord[Id]['HostNameList'][host_index[i]]]["GroupName"]+=\
251 "," + TestRecord[Id]['HostGroupList'][host_index[i]]
253 Result['Results'][key] = \
255 "StatusCode": 200, "StatusMessage": "FAILURE"}
258 for i in range (len(TestRecord[Id]['NodeList'])):
259 if key in TestRecord[Id]['NodeList'][i]:
262 if int(retval[key][0]) > 0 and int(retval[key][2]) == 0 and \
263 int(retval[key][3]) == 0:
264 Result['Results'][TestRecord[Id]['NodeList'][host_index]] = \
265 {"GroupName": 'na', "StatusCode": 200, \
266 "StatusMessage": "SUCCESS"}
267 elif int(retval[key][2]) > 0:
268 Result['Results'][TestRecord[Id]['NodeList'][host_index]] = \
269 {"GroupName": 'na', "StatusCode": 400, "StatusMessage": "NOT REACHABLE"}
270 elif int(retval[key][3]) > 0:
271 Result['Results'][TestRecord[Id]['NodeList'][host_index]] = \
272 {"GroupName": 'na', "StatusCode": 400, "StatusMessage": "FAILURE"}
274 callback (Id, Result, Output, Log, returncode)
276 class TestManager (object):
279 @cherrypy.tools.json_out()
280 @cherrypy.tools.json_in()
281 @cherrypy.tools.allow(methods=['POST', 'GET', 'DELETE'])
283 def Dispatch(self, **kwargs):
285 # Let cherrypy error handler deal with malformed requests
286 # No need for explicit error handler, we use default ones
288 time_now = datetime.datetime.utcnow()
290 # Erase old test results (2x timeout)
292 for key in TestRecord.copy():
293 delta_time = (time_now - TestRecord[key]['Time']).seconds
294 if delta_time > 2*TestRecord[key]['Timeout']:
295 print "Deleted history for test", key
296 if os.path.exists(TestRecord[key]['Path']):
297 shutil.rmtree (TestRecord[key]['Path'])
300 print "***> in RestServer.Dispatch:", cherrypy.request.method
302 HomeDir = os.path.dirname(os.path.realpath("~/"))
304 if 'POST' in cherrypy.request.method:
306 input_json = cherrypy.request.json
307 print " Payload: ", input_json
309 if 'Id' in input_json and 'PlaybookName' in input_json:
313 if not input_json['Id'] in TestRecord:
315 Id = input_json['Id']
316 PlaybookName = input_json['PlaybookName']
319 if 'Version' in input_json:
320 version = input_json['Version']
322 AnsibleInvFail = True
323 AnsiblePlaybookFail = True
330 str_uuid = str (uuid.uuid4())
332 LCM = PlaybookName.split(".")[0].split('_')[-1]
333 PlaybookDir = HomeDir + "/" + ansible_temp + "/" + \
334 PlaybookName.split(".")[0] + "_" + str_uuid
335 AnsibleInv = LCM + "_" + "inventory"
339 print " PlaybookDir: ", ansible_temp + PlaybookDir.split(ansible_temp)[1]
340 print " AnsibleInv: ", AnsibleInv
341 print " ansible_temp: ", ansible_temp
343 if not os.path.exists(HomeDir + "/" + ansible_temp):
344 os.makedirs(HomeDir + "/" + ansible_temp)
346 os.mkdir(PlaybookDir)
348 # Process inventory file for target
354 if 'NodeList' in input_json:
355 NodeList = input_json['NodeList']
357 print " NodeList: ", NodeList
360 # By default set to local host
361 AnsibleInvFail = False
363 LocalNodeList = "host"
364 LocalCredentials = "localhost ansible_connection=local"
365 f = open(PlaybookDir + "/" + AnsibleInv, "w")
366 f.write("[" + LocalNodeList + "]\n")
367 f.write(LocalCredentials)
374 # Get credentials from file
376 data_inventory_orig = {}
377 data_inventory_target = {}
380 print "***>", ansible_path + "/" + ansible_inv
381 f = open(ansible_path + "/" + ansible_inv, "r")
387 if "[" in line and "]" in line:
388 data_inventory_orig[line] = []
391 data_inventory_orig[curr_group].append(line)
394 for node in NodeList:
396 if "[" + node + "]" in data_inventory_orig:
397 if not "[" + node + "]" in data_inventory_target:
399 print "RESET", "[" + node + "]"
400 data_inventory_target["[" + node + "]"] = []
402 print "OK", "[" + node + "]"
404 for cred in data_inventory_orig["[" + node + "]"]:
405 data_inventory_target["[" + node + "]"].append(cred)
408 for key in data_inventory_orig:
409 if node in " ".join(data_inventory_orig[key]):
410 if not key in data_inventory_target:
411 data_inventory_target[key] = []
412 for cred in data_inventory_orig[key]:
414 data_inventory_target[key].append(cred)
418 data_inventory_target["["+node+"]"] = \
419 [node + " ansible_connection=ssh ansible_ssh_user=na ansible_ssh_private_key_file=na"]
421 AnsibleInvFail = False
423 f = open(PlaybookDir + "/" + AnsibleInv, "w")
424 for key in data_inventory_target:
426 for rec in data_inventory_target[key]:
427 hostgrouplist.append(key.replace("[", '').replace("]", ''))
428 hostnamelist.append(rec.split(' ')[0])
434 # Get credentials from mySQL
436 sqlintf = AnsibleSql.mySql (host, user, passwd,
440 errorCode, diag = readCredentials (sqlintf,
443 print errorCode, diag
445 f = open(PlaybookDir + "/" + AnsibleInv,
447 AnsibleInvFail = False
448 # [hostgroup, hostname, credentials]
449 for i in range(len(diag)):
450 f.write('[' + diag[i][0] + ']' + "\n")
451 f.write(diag[i][1]+ " " + diag[i][2] + "\n\n")
452 hostgrouplist.append(diag[i][0])
453 hostnamelist.append(diag[i][1])
456 MySqlConFailCause = sqlintf.error
459 timeout = timeout_seconds
460 if 'Timeout' in input_json:
461 timeout = int (input_json['Timeout'])
464 if 'EnvParameters' in input_json:
465 EnvParam = input_json['EnvParameters']
468 if 'LocalParameters' in input_json:
469 LocalParam = input_json['LocalParameters']
472 if 'FileParameters' in input_json:
473 FileParam = input_json['FileParameters']
476 if 'CallBack' in input_json:
477 callback_flag = input_json['CallBack']
479 TestRecord[Id] = {'PlaybookName': PlaybookName,
482 'NodeList': NodeList,
483 'HostGroupList': hostgrouplist,
484 'HostNameList': hostnamelist,
488 'EnvParameters': EnvParam,
489 'LocalParameters': LocalParam,
490 'FileParameters': FileParam,
491 'CallBack': callback_flag,
492 'Result': {"StatusCode": 100,
493 "StatusMessage": 'PENDING',
494 "ExpectedDuration": str(timeout) + "sec"},
502 if not TestRecord[Id]['FileParameters'] == {}:
503 for key in TestRecord[Id]['FileParameters']:
505 filecontent = TestRecord[Id]['FileParameters'][key]
506 f = open(PlaybookDir + "/" + filename, "w")
515 # Get playbooks from files
520 target_PlaybookName = None
522 if '@' in PlaybookName:
523 version = PlaybookName.split("@")[1]
524 version = version.replace('.yml','')
525 version = version.replace('.tar.gz','')
527 onlyfiles = [f for f in listdir(ansible_path)
528 if isfile(join(ansible_path, f))]
533 for file in onlyfiles:
535 temp_version = file.split("@")[1]
536 temp_version = temp_version.replace('.yml','')
537 temp_version = temp_version.replace('.tar.gz','')
538 if version_max < temp_version:
539 version_max = temp_version
541 if not version == None:
542 if version in PlaybookName:
543 version_target = version
544 target_PlaybookName = file
546 if target_PlaybookName == None:
547 for file in onlyfiles:
548 if LCM in file and version_max in file:
549 target_PlaybookName = file
550 version_target = version_max
552 if target_PlaybookName:
553 AnsiblePlaybookFail = False
554 readversion = version_target
555 src = ansible_path + "/" + target_PlaybookName
556 if ".tar.gz" in target_PlaybookName:
557 dest = PlaybookDir + "/" + LCM + ".tar.gz"
558 shutil.copy2(src, dest)
559 retcode = subprocess.call(['tar', '-xvzf',
560 dest, "-C", PlaybookDir])
563 dest = PlaybookDir + "/" + LCM + ".yml"
564 shutil.copy2(src, dest)
567 # Get playbooks from mySQL
569 sqlintf = AnsibleSql.mySql (host, user, passwd, db)
573 name, readversion, AnsiblePlaybookFail, diag = \
574 readPlaybook (sqlintf, PlaybookName.split(".")[0],
577 if not AnsiblePlaybookFail:
579 f = open(PlaybookDir + "/" + LCM + diag[1], "w")
583 if ".tar.gz" in diag[1]:
584 retcode = subprocess.call(['tar', '-xvzf',
585 PlaybookDir + "/" + LCM + diag[1], "-C", PlaybookDir])
589 MySqlConFailCause = sqlintf.error
593 if os.path.exists(PlaybookDir):
594 shutil.rmtree (PlaybookDir)
596 return {"StatusCode": 101,
597 "StatusMessage": "CANNOT CONNECT TO MYSQL: " \
599 elif AnsiblePlaybookFail:
600 if os.path.exists(PlaybookDir):
601 shutil.rmtree (PlaybookDir)
603 return {"StatusCode": 101,
604 "StatusMessage": "PLAYBOOK NOT FOUND"}
606 if os.path.exists(PlaybookDir):
607 shutil.rmtree (PlaybookDir)
609 return {"StatusCode": 101,
610 "StatusMessage": "NODE LIST CREDENTIALS NOT FOUND"}
616 for dName, sdName, fList in os.walk(PlaybookDir):
617 if LCM+".yml" in fList:
618 playbook_path = dName
620 playbook_path = PlaybookDir
623 if not os.path.exists(playbook_path + "/vars"):
624 os.mkdir(playbook_path + "/vars")
625 if not os.path.isfile(playbook_path + "/vars/defaults.yml"):
626 os.mknod(playbook_path + "/vars/defaults.yml")
628 for key in TestRecord[Id]['LocalParameters']:
630 for i in range(len(TestRecord[Id]['HostNameList'])):
631 if key in TestRecord[Id]['HostNameList'][i]:
633 if len(host_index) == 0:
634 for i in range(len(TestRecord[Id]['HostGroupList'])):
635 if key in TestRecord[Id]['HostGroupList'][i]:
637 if len(host_index) > 0:
638 for i in range(len(host_index)):
639 f = open(playbook_path + "/vars/" +
640 TestRecord[Id]['HostNameList'][host_index[i]] +
642 for param in TestRecord[Id]['LocalParameters'][key]:
643 f.write(param + ": " +
644 str (TestRecord[Id]['LocalParameters'][key][param]) +
648 # Get mandatory parameters from playbook
650 with open(playbook_path + "/" + LCM + ".yml") as origin_file:
651 for line in origin_file:
652 if "Mandatory" in line:
653 temp = line.split(":")[1].strip().replace(' ', '')
655 Mandatory = temp.split(",")
657 TestRecord[Id] = {'PlaybookName': TestRecord[Id]['PlaybookName'],
658 'LCM': TestRecord[Id]['LCM'],
659 'Version': readversion,
660 'NodeList': TestRecord[Id]['NodeList'],
661 'HostGroupList': TestRecord[Id]['HostGroupList'],
662 'HostNameList': TestRecord[Id]['HostNameList'],
663 'Time': TestRecord[Id]['Time'],
664 'Timeout': TestRecord[Id]['Timeout'],
665 'Duration': TestRecord[Id]['Duration'],
666 'EnvParameters': TestRecord[Id]['EnvParameters'],
667 'LocalParameters': TestRecord[Id]['LocalParameters'],
668 'FileParameters': TestRecord[Id]['FileParameters'],
669 'CallBack': TestRecord[Id]['CallBack'],
670 'Result': TestRecord[Id]['Result'],
671 'Log': TestRecord[Id]['Log'],
672 'Output': TestRecord[Id]['Output'],
673 'Path': TestRecord[Id]['Path'],
674 'Mandatory': Mandatory}
679 for val in Mandatory:
685 for key in TestRecord[Id]['NodeList']:
686 if key in LocalParam:
687 if val in LocalParam[key]:
691 for key in TestRecord[Id]['NodeList']:
692 if key in LocalParam:
693 if val in LocalParam[key]:
697 if os.path.exists(PlaybookDir):
698 shutil.rmtree (PlaybookDir)
700 return {"StatusCode": 101,
701 "StatusMessage": "MISSING MANDATORY PARAMETER: " + \
702 " ".join(str(x) for x in Mandatory)}
705 # Cannot use thread because ansible module uses
706 # signals which are only supported in main thread.
707 # So use multiprocess with shared object
709 p = Process(target = RunAnsible_Playbook,
710 args = (callback, Id, PlaybookDir + "/" + AnsibleInv,
711 playbook_path + "/" + LCM + ".yml",
712 NodeList, TestRecord, PlaybookDir,
715 ActiveProcess[Id] = p
716 return TestRecord[Id]['Result']
718 return {"StatusCode": 101, "StatusMessage": "TEST ID ALREADY DEFINED"}
721 return {"StatusCode": 500, "StatusMessage": "REQUEST MUST INCLUDE: NODELIST"}
724 return {"StatusCode": 500, "StatusMessage": "JSON OBJECT MUST INCLUDE: ID, PLAYBOOKNAME"}
726 elif 'GET' in cherrypy.request.method:
728 input_data = parse_query_string(cherrypy.request.query_string)
730 print "***> in RestServer.GET"
731 print " Payload: ", input_data, input_data['Type']
733 if 'Id' in input_data and 'Type' in input_data:
734 if not ('GetResult' in input_data['Type'] or 'GetOutput' in input_data['Type'] or 'GetLog' in input_data['Type']):
735 return {"StatusCode": 500, "StatusMessage": "RESULTS TYPE UNDEFINED"}
736 if input_data['Id'] in TestRecord:
738 if 'GetResult' in input_data['Type']:
740 print "Result:", TestRecord[input_data['Id']]['Result']
742 if 'StatusMessage' in TestRecord[input_data['Id']]['Result'] and getresults_block:
744 print "*** Request blocked", input_data['Id']
746 while ActiveProcess[input_data['Id']].is_alive():
749 print "*** Request released ", input_data['Id']
751 print TestRecord[input_data['Id']]['Result']
752 if TestRecord[input_data['Id']]['Result']['StatusCode'] == 500:
753 out_obj = TestRecord[input_data['Id']]['Result']['Results']
755 out_obj = {"StatusCode": 200,
756 "StatusMessage": "FINISHED",
757 "PlaybookName": TestRecord[input_data['Id']]["PlaybookName"],
758 "Version": TestRecord[input_data['Id']]["Version"],
759 "Duration": TestRecord[input_data['Id']]["Duration"],
760 "Results": TestRecord[input_data['Id']]['Result']['Results']}
761 if not TestRecord[input_data['Id']]['Output']['Output'] == {}:
762 for key in out_obj["Results"]:
763 if key in TestRecord[input_data['Id']]['Output']['Output']:
764 out_obj["Results"][key]["Output"] = TestRecord[input_data['Id']]['Output']['Output'][key]
768 elif 'GetOutput' in input_data['Type']:
770 if TestRecord[input_data['Id']]['Output'] == {} and \
773 print "*** Request blocked", input_data['Id']
775 while TestRecord[input_data['Id']]['Output'] == {} \
776 or 'StatusMessage' in TestRecord[input_data['Id']]['Result']:
779 print "*** Request released ", input_data['Id']
781 print "Output:", TestRecord[input_data['Id']]['Output']
782 return {"Output": TestRecord[input_data['Id']]['Output']['Output']}
786 if TestRecord[input_data['Id']]['Log'] == '' and \
789 print "*** Request blocked", input_data['Id']
791 while TestRecord[input_data['Id']]['Log'] == '' \
792 or 'StatusMessage' in TestRecord[input_data['Id']]['Result']:
795 print "*** Request released ", input_data['Id']
797 print "Log:", TestRecord[input_data['Id']]['Log']
798 return {"Log": TestRecord[input_data['Id']]['Log']}
800 return {"StatusCode": 500, "StatusMessage": "TEST ID UNDEFINED"}
802 return {"StatusCode": 500, "StatusMessage": "MALFORMED REQUEST"}
803 elif 'DELETE' in cherrypy.request.method:
804 input_data = parse_query_string(cherrypy.request.query_string)
806 print "***> in RestServer.DELETE"
807 print " Payload: ", input_data
809 if input_data['Id'] in TestRecord:
810 if not 'PENDING' in TestRecord[input_data['Id']]['Result']:
811 print " Path:", TestRecord[input_data['Id']]['Path']
812 if os.path.exists(TestRecord[input_data['Id']]['Path']):
813 shutil.rmtree (TestRecord[input_data['Id']]['Path'])
814 TestRecord.pop (input_data['Id'])
815 if input_data['Id'] in ActiveProcess:
816 ActiveProcess.pop (input_data['Id'])
818 return {"StatusCode": 200, "StatusMessage": "PLAYBOOK EXECUTION RECORDS DELETED"}
820 return {"StatusCode": 200, "StatusMessage": "PENDING"}
822 return {"StatusCode": 500, "StatusMessage": "TEST ID UNDEFINED"}
825 if __name__ == '__main__':
829 config_file_path = "RestServer_config"
831 if not os.path.exists(config_file_path):
832 print '[INFO] The config file does not exist'
843 timeout_seconds = 'na'
851 getresults_block = False
854 file = open(config_file_path, 'r')
855 for line in file.readlines():
858 ip = line.split(':')[1].strip()
859 elif 'port:' in line:
860 port = line.split(':')[1].strip()
862 tls = 'YES' in line.split(':')[1].strip().upper()
863 elif 'auth:' in line:
864 auth = 'YES' in line.split(':')[1].strip().upper()
865 if tls and 'priv:' in line:
866 priv = line.split(':')[1].strip()
867 if tls and 'pub:' in line:
868 pub = line.split(':')[1].strip()
869 if auth and 'id:' in line:
870 id = line.split(':')[1].strip()
871 if auth and 'psswd:' in line:
872 psswd = line.split(':')[1].strip()
873 if 'timeout_seconds' in line:
874 timeout_seconds = int (line.split(':')[1].strip())
875 if 'ansible_path' in line:
876 ansible_path = line.split(':')[1].strip()
877 if 'ansible_inv' in line:
878 ansible_inv = line.split(':')[1].strip()
879 if not os.path.exists(ansible_path + "/" + ansible_inv):
880 print '[INFO] The ansible_inv file does not exist'
882 if 'ansible_temp' in line:
883 ansible_temp = line.split(':')[1].strip()
885 host = line.split(':')[1].strip()
887 user = line.split(':')[1].strip()
889 passwd = line.split(':')[1].strip()
891 db = line.split(':')[1].strip()
892 if 'getresults_block' in line:
893 getresults_block = 'YES' in line.split(':')[1].strip().upper()
894 if 'from_files' in line:
895 from_files = 'YES' in line.split(':')[1].strip().upper()
902 'server.socket_host': ip,
903 'server.socket_port': int(port),
904 'server.protocol_version': 'HTTP/1.1'
909 # Use pythons built-in SSL
910 cherrypy.server.ssl_module = 'builtin'
912 # Point to certificate files
914 if not os.path.exists(pub):
915 print '[INFO] The public certificate does not exist'
918 if not os.path.exists(priv):
919 print '[INFO] The private key does not exist'
922 cherrypy.server.ssl_certificate = pub
923 cherrypy.server.ssl_private_key = priv
926 userpassdict = {id: psswd}
927 checkpassword = cherrypy.lib.auth_basic.checkpassword_dict(userpassdict)
930 {'tools.auth_basic.on': True,
931 'tools.auth_basic.realm': 'earth',
932 'tools.auth_basic.checkpassword': checkpassword,
936 cherrypy.tree.mount(TestManager(), '/', app_conf)
938 cherrypy.tree.mount(TestManager(), '/')
940 cherrypy.config.update(global_conf)
944 cherrypy.engine.start()
945 cherrypy.engine.block()