blob: 1469e59ede572ca9e68cc27008b2c71067b3d9e3 [file] [log] [blame]
Timoney, Dan (dt5972)12622052018-09-12 10:53:10 -04001'''
2/*-
3* ============LICENSE_START=======================================================
4* ONAP : APPC
5* ================================================================================
Taka Chodc4950b2019-01-29 09:30:22 -05006* Copyright (C) 2017-2019 AT&T Intellectual Property. All rights reserved.
Timoney, Dan (dt5972)12622052018-09-12 10:53:10 -04007* ================================================================================
8* Copyright (C) 2017 Amdocs
9* =============================================================================
10* Licensed under the Apache License, Version 2.0 (the "License");
11* you may not use this file except in compliance with the License.
12* You may obtain a copy of the License at
13*
14* http://www.apache.org/licenses/LICENSE-2.0
15*
16* Unless required by applicable law or agreed to in writing, software
17* distributed under the License is distributed on an "AS IS" BASIS,
18* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
19* See the License for the specific language governing permissions and
20* limitations under the License.
21*
22* ECOMP is a trademark and service mark of AT&T Intellectual Property.
23* ============LICENSE_END=========================================================
24*/
25'''
26
27import time, datetime, json, os, sys, subprocess, re
28import uuid
29import tarfile
30import shutil
Taka Chodc4950b2019-01-29 09:30:22 -050031import glob
32import crypt
Timoney, Dan (dt5972)12622052018-09-12 10:53:10 -040033
34import requests
35
36import cherrypy
37from cherrypy.lib.httputil import parse_query_string
38from cherrypy.lib import auth_basic
39
40from multiprocessing import Process, Manager
41
42from AnsibleModule import ansibleSysCall
Taka Chodc4950b2019-01-29 09:30:22 -050043from BuildHostFile import buildHostsSysCall
Timoney, Dan (dt5972)12622052018-09-12 10:53:10 -040044
45from os import listdir
46from os.path import isfile, join
47
48TestRecord = Manager().dict()
49ActiveProcess = {}
50
Taka Chodc4950b2019-01-29 09:30:22 -050051def validate_password(realm, username, password):
52 comp = crypt.crypt(password, salt)
53 if username in userpassdict and userpassdict[username] == comp:
54 return True
55 return False
56
Timoney, Dan (dt5972)12622052018-09-12 10:53:10 -040057def sys_call (cmd):
58 p = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
59 output = p.stdout.readlines()
60 retval = p.wait()
61 if len (output) > 0:
62 for i in range(len(output)):
63 output[i] = output[i].strip()
64 return retval, output
65
66def callback (Id, Result, Output, Log, returncode):
67
68 print "***> in RestServer.callback"
69
70 if Id in TestRecord:
71 time_now = datetime.datetime.utcnow()
72 delta_time = (time_now - TestRecord[Id]['Time']).total_seconds()
73 Result['PlaybookName'] = TestRecord[Id]['PlaybookName']
74 Result['Version'] = TestRecord[Id]['Version']
75 if returncode == 137:
76 Result['StatusCode'] = 500
77 Result['StatusMessage'] = "TERMINATED"
78 else:
79 Result['StatusCode'] = 200
80 Result['StatusMessage'] = "FINISHED"
81
82 # Need to update the whole data structure for key=Id otherwise Manager is not updated
83 TestRecord[Id] = {'PlaybookName': TestRecord[Id]['PlaybookName'],
Timoney, Dan (dt5972)12622052018-09-12 10:53:10 -040084 'Version': TestRecord[Id]['Version'],
85 'NodeList': TestRecord[Id]['NodeList'],
86 'HostGroupList': TestRecord[Id]['HostGroupList'],
87 'HostNameList': TestRecord[Id]['HostNameList'],
88 'Time': TestRecord[Id]['Time'],
89 'Timeout': TestRecord[Id]['Timeout'],
90 'Duration': str(delta_time),
91 'EnvParameters': TestRecord[Id]['EnvParameters'],
92 'LocalParameters': TestRecord[Id]['LocalParameters'],
93 'FileParameters': TestRecord[Id]['FileParameters'],
94 'CallBack': TestRecord[Id]['CallBack'],
95 'Result': Result,
96 'Log': Log,
97 'Output': Output,
98 'Path': TestRecord[Id]['Path'],
99 'Mandatory': TestRecord[Id]['Path']}
100
101 if not TestRecord[Id]['CallBack'] == None:
102
103 # Posting results to callback server
104
105 data = {"StatusCode": 200,
106 "StatusMessage": "FINISHED",
107 "PlaybookName": TestRecord[Id]["PlaybookName"],
108 "Version": TestRecord[Id]["Version"],
109 "Duration": TestRecord[Id]["Duration"],
110 "Results": TestRecord[Id]['Result']['Results']}
111
Taka Chodc4950b2019-01-29 09:30:22 -0500112 cherrypy.log("CALLBACK: TestRecord[Id]['Output']['Output']:", str(TestRecord[Id]['Output']['Output']))
113 cherrypy.log("CALLBACK: Results:", str(data["Results"]))
114
Timoney, Dan (dt5972)12622052018-09-12 10:53:10 -0400115 if not TestRecord[Id]['Output']['Output'] == {}:
116 for key in data["Results"]:
117 if key in TestRecord[Id]['Output']['Output']:
118 data["Results"][key]["Output"] = TestRecord[Id]['Output']['Output'][key]
119
120 print " Posting to", TestRecord[Id]['CallBack']
121
122 s = requests.Session()
123 r = s.post(TestRecord[Id]['CallBack'], data = json.dumps(data),
124 headers = {'content-type': 'application/json'})
125 print " Response", r.status_code, r.text
126
127def RunAnsible_Playbook (callback, Id, Inventory, Playbook, NodeList, TestRecord,
128 Path, ArchiveFlag):
129
130 print "***> in RestServer.RunAnsible_Playbook"
131
132 # Run test in playbook for given target
133 Result = ''
134
135 retval, log, returncode = ansibleSysCall (Inventory, Playbook, NodeList,
136 TestRecord[Id]['Mandatory'],
137 TestRecord[Id]['EnvParameters'],
138 TestRecord[Id]['LocalParameters'],
Taka Chodc4950b2019-01-29 09:30:22 -0500139 TestRecord[Id]['Timeout'],
140 Path)
Timoney, Dan (dt5972)12622052018-09-12 10:53:10 -0400141
142
Taka Chodc4950b2019-01-29 09:30:22 -0500143 cherrypy.log("Return code:" + str(returncode))
144 cherrypy.log("Return val:" + str(retval))
Timoney, Dan (dt5972)12622052018-09-12 10:53:10 -0400145
146 Log = ''.join(log)
Taka Chodc4950b2019-01-29 09:30:22 -0500147 #Output = {'Output': {}}
148 Output = {}
Timoney, Dan (dt5972)12622052018-09-12 10:53:10 -0400149
150 onlyfiles = [f for f in listdir(Path)
151 if isfile(join(Path, f))]
152
Taka Chodc4950b2019-01-29 09:30:22 -0500153 cherrypy.log("Checking for results.txt files: ")
Timoney, Dan (dt5972)12622052018-09-12 10:53:10 -0400154 for file in onlyfiles:
155 if "results.txt" in file:
Taka Chodc4950b2019-01-29 09:30:22 -0500156# if file.endswith("results.txt"):
157 cherrypy.log("results file: " + file)
Timoney, Dan (dt5972)12622052018-09-12 10:53:10 -0400158 f = open(Path + "/" + file, "r")
Taka Chodc4950b2019-01-29 09:30:22 -0500159 resultsData = f.read() # Not to pass vnf instance name
160 OutputP = json.loads(resultsData)
161 Output['Output'] = OutputP
162 cherrypy.log("Output = " + str(Output['Output']))
163 #Output['Output'][key] = f.read() # To pass vnf instance name
Timoney, Dan (dt5972)12622052018-09-12 10:53:10 -0400164 f.close()
165
Taka Chodc4950b2019-01-29 09:30:22 -0500166 if Output == {}:
167 Output = {'Output': {}}
168
Timoney, Dan (dt5972)12622052018-09-12 10:53:10 -0400169 Result = {'Results': {}}
170 if 'could not be found' in Log:
171 Result['Results'] = {"StatusCode": 101,
172 "StatusMessage": "PLAYBOOK NOT FOUND"}
173 if returncode == 137:
174 Result['Results'] = {"StatusCode": 500,
175 "StatusMessage": "TERMINATED"}
176
177 elif TestRecord[Id]['NodeList'] == []:
178
179 host_index = None
180
181 if 'TargetNode' in TestRecord[Id]['EnvParameters']:
182 targetlist = TestRecord[Id]['EnvParameters']['TargetNode'].split(' ')
183 else:
184 targetlist = ["localhost"]
185
186 for key in retval:
187 for i in range (len(targetlist)):
188 if key in targetlist[i]:
189 host_index = i
190
191 if int(retval[key][0]) > 0 and int(retval[key][2]) == 0 and \
192 int(retval[key][3]) == 0:
193
194 if host_index:
195 Result['Results'][targetlist[host_index]] = \
196 {"GroupName": 'na', "StatusCode": 200, \
197 "StatusMessage": "SUCCESS"}
198 else:
199 Result['Results'][key] = \
200 {"GroupName": 'na', "StatusCode": 200, \
201 "StatusMessage": "SUCCESS"}
202 elif int(retval[key][2]) > 0:
203 if host_index:
204 Result['Results'][targetlist[host_index]] = \
205 {"GroupName": 'na', "StatusCode": 400, \
206 "StatusMessage": "NOT REACHABLE"}
207 else:
208 Result['Results'][key] = \
209 {"GroupName": 'na', "StatusCode": 400, \
210 "StatusMessage": "NOT REACHABLE"}
211 elif int(retval[key][3]) > 0:
212 if host_index:
213 Result['Results'][targetlist[host_index]] = \
214 {"GroupName": 'na', "StatusCode": 400, \
215 "StatusMessage": "FAILURE"}
216 else:
217 Result['Results'][key] = \
218 {"GroupName": 'na', "StatusCode": 400, \
219 "StatusMessage": "FAILURE"}
220 else:
221
222 for key in retval:
223
224 if len(TestRecord[Id]['HostNameList']) > 0:
225
226 host_index = []
227 for i in range (len(TestRecord[Id]['HostNameList'])):
228 if key in TestRecord[Id]['HostNameList'][i]:
229 host_index.append(i)
230
231 if int(retval[key][0]) > 0 and int(retval[key][2]) == 0 and \
232 int(retval[key][3]) == 0:
233
234 if len(host_index) > 0:
235 Result['Results'][TestRecord[Id]['HostNameList'][host_index[0]]] = \
236 {"GroupName": TestRecord[Id]['HostGroupList'][host_index[0]],
237 "StatusCode": 200, "StatusMessage": "SUCCESS"}
238
239 for i in range (1, len(host_index)):
240 Result['Results'][TestRecord[Id]['HostNameList'][host_index[i]]]["GroupName"]+=\
241 "," + TestRecord[Id]['HostGroupList'][host_index[i]]
242 else:
243 Result['Results'][key] = \
244 {"GroupName": key,
245 "StatusCode": 200, "StatusMessage": "SUCCESS"}
246
247 elif int(retval[key][2]) > 0:
248
249 if len(host_index) > 0:
250 Result['Results'][TestRecord[Id]['HostNameList'][host_index[0]]] = \
251 {"GroupName": TestRecord[Id]['HostGroupList'][host_index[0]],
252 "StatusCode": 400, "StatusMessage": "NOT REACHABLE"}
253
254 for i in range (1, len(host_index)):
255 Result['Results'][TestRecord[Id]['HostNameList'][host_index[i]]]["GroupName"]+=\
256 "," + TestRecord[Id]['HostGroupList'][host_index[i]]
257 else:
258 Result['Results'][key] = \
259 {"GroupName": key,
260 "StatusCode": 200, "StatusMessage": "NOT REACHABLE"}
261
262 elif int(retval[key][3]) > 0:
263
264 if len(host_index) > 0:
265 Result['Results'][TestRecord[Id]['HostNameList'][host_index[0]]] = \
266 {"GroupName": TestRecord[Id]['HostGroupList'][host_index[0]],
267 "StatusCode": 400, "StatusMessage": "FAILURE"}
268
269 for i in range (1, len(host_index)):
270 Result['Results'][TestRecord[Id]['HostNameList'][host_index[i]]]["GroupName"]+=\
271 "," + TestRecord[Id]['HostGroupList'][host_index[i]]
272 else:
273 Result['Results'][key] = \
274 {"GroupName": key,
275 "StatusCode": 200, "StatusMessage": "FAILURE"}
276 else:
277 host_index = None
278 for i in range (len(TestRecord[Id]['NodeList'])):
279 if key in TestRecord[Id]['NodeList'][i]:
280 host_index = i
281
282 if int(retval[key][0]) > 0 and int(retval[key][2]) == 0 and \
283 int(retval[key][3]) == 0:
284 Result['Results'][TestRecord[Id]['NodeList'][host_index]] = \
285 {"GroupName": 'na', "StatusCode": 200, \
286 "StatusMessage": "SUCCESS"}
287 elif int(retval[key][2]) > 0:
288 Result['Results'][TestRecord[Id]['NodeList'][host_index]] = \
289 {"GroupName": 'na', "StatusCode": 400, "StatusMessage": "NOT REACHABLE"}
290 elif int(retval[key][3]) > 0:
291 Result['Results'][TestRecord[Id]['NodeList'][host_index]] = \
292 {"GroupName": 'na', "StatusCode": 400, "StatusMessage": "FAILURE"}
293
Taka Chodc4950b2019-01-29 09:30:22 -0500294 cherrypy.log("TESTRECORD: " + str(TestRecord[Id]))
295 #cherrypy.log("Output: " + str(Output))
Timoney, Dan (dt5972)12622052018-09-12 10:53:10 -0400296 callback (Id, Result, Output, Log, returncode)
297
298class TestManager (object):
299
300 @cherrypy.expose
301 @cherrypy.tools.json_out()
302 @cherrypy.tools.json_in()
303 @cherrypy.tools.allow(methods=['POST', 'GET', 'DELETE'])
304
305 def Dispatch(self, **kwargs):
306
307 # Let cherrypy error handler deal with malformed requests
308 # No need for explicit error handler, we use default ones
309
310 time_now = datetime.datetime.utcnow()
311
312 # Erase old test results (2x timeout)
Taka Chodc4950b2019-01-29 09:30:22 -0500313 # Do cleanup too of ActiveProcess list and old Records - PAP
Timoney, Dan (dt5972)12622052018-09-12 10:53:10 -0400314 if TestRecord:
315 for key in TestRecord.copy():
Taka Chodc4950b2019-01-29 09:30:22 -0500316 cherrypy.log( "LOOKING AT ALL TestRecords: " + str(key))
317 if key in ActiveProcess:
318 if not ActiveProcess[key].is_alive(): # Just to cleanup defunct processes
319 cherrypy.log( "Not ActiveProcess for ID: " + str(key))
Timoney, Dan (dt5972)12622052018-09-12 10:53:10 -0400320 delta_time = (time_now - TestRecord[key]['Time']).seconds
321 if delta_time > 2*TestRecord[key]['Timeout']:
Taka Chodc4950b2019-01-29 09:30:22 -0500322 cherrypy.log( "DELETED HISTORY for ID: " + str(key))
323 if key in ActiveProcess:
324 if not ActiveProcess[key].is_alive():
325 ActiveProcess.pop (key)
326 cherrypy.log( "DELETED ActiveProcess for ID: " + str(key))
327 #if os.path.exists(TestRecord[key]['Path']):
328 # don't remove run dirrectory
329 #shutil.rmtree (TestRecord[key]['Path'])
Timoney, Dan (dt5972)12622052018-09-12 10:53:10 -0400330 del TestRecord[key]
331
Taka Chodc4950b2019-01-29 09:30:22 -0500332 cherrypy.log("RestServer.Dispatch: " + cherrypy.request.method)
Timoney, Dan (dt5972)12622052018-09-12 10:53:10 -0400333
Timoney, Dan (dt5972)12622052018-09-12 10:53:10 -0400334
335 if 'POST' in cherrypy.request.method:
336
337 input_json = cherrypy.request.json
Taka Chodc4950b2019-01-29 09:30:22 -0500338 cherrypy.log("Payload: " + str(input_json))
Timoney, Dan (dt5972)12622052018-09-12 10:53:10 -0400339
Taka Chodc4950b2019-01-29 09:30:22 -0500340 if 'Id' in input_json and 'PlaybookName' in input_json and 'EnvParameters' in input_json:
Timoney, Dan (dt5972)12622052018-09-12 10:53:10 -0400341
342 if True:
343
344 if not input_json['Id'] in TestRecord:
Taka Chodc4950b2019-01-29 09:30:22 -0500345 # check if Id exists in previous run dirctory
346 # if so retun error
347 s_cmd = 'ls ' + ansible_temp + '/*_' + input_json['Id']
348 #if subprocess.check_output([s_cmd, ]):
Timoney, Dan (dt5972)12622052018-09-12 10:53:10 -0400349 Id = input_json['Id']
Taka Chodc4950b2019-01-29 09:30:22 -0500350 if glob.glob( ansible_temp + '/*_' + input_json['Id']):
351 cherrypy.log("Old directory found for ID: " + Id)
352 return {"StatusCode": 101, "StatusMessage": "TEST ID FILE ALREADY DEFINED"}
353
Timoney, Dan (dt5972)12622052018-09-12 10:53:10 -0400354 PlaybookName = input_json['PlaybookName']
Taka Chodc4950b2019-01-29 09:30:22 -0500355 # if required it should be passed as an argument
356 EnvParameters = input_json['EnvParameters']
Timoney, Dan (dt5972)12622052018-09-12 10:53:10 -0400357
Taka Chodc4950b2019-01-29 09:30:22 -0500358 # The lines below are to test multiple EnvParameters being passed
359 #for i in EnvParameters:
360 # cherrypy.log("EnvParameter object: " + i)
361 # cherrypy.log(" EnvParameter Value: " + EnvParameters[ i ])
362
363 # Now get things out of EnvParameters
364 VNF_instance = None
365 VNF_instance = EnvParameters.get('vnf_instance')
366
367 # Get Version if present
Timoney, Dan (dt5972)12622052018-09-12 10:53:10 -0400368 version = None
369 if 'Version' in input_json:
370 version = input_json['Version']
Timoney, Dan (dt5972)12622052018-09-12 10:53:10 -0400371
Taka Chodc4950b2019-01-29 09:30:22 -0500372 # GetInventoryNames
373 HaveNodeList = False
374 HaveInventoryNames = False
375 inventory_names = None
376 if 'InventoryNames' in input_json:
377 inventory_names = input_json['InventoryNames']
378 HaveInventoryNames = True
379
380 #AnsibleInvFail = True
381 AnsiblePlaybookFail = True
Timoney, Dan (dt5972)12622052018-09-12 10:53:10 -0400382
383 LocalNodeList = None
384
385 str_uuid = str (uuid.uuid4())
386
Taka Chodc4950b2019-01-29 09:30:22 -0500387
388 VnfType= PlaybookName.split("/")[0]
389 if auth:
390 cherrypy.log( "Request USER : " + cherrypy.request.login)
391 cherrypy.log( "Request Decode: ID " + Id)
392 cherrypy.log( "Request Decode: VnfType " + VnfType)
393 cherrypy.log( "Request Decode: EnvParameters " + json.dumps(EnvParameters))
394
395 # Verify VNF_instance was passed in EnvParameters
396 if VNF_instance != None:
397 cherrypy.log( "Request Decode: VnfInstance " + VNF_instance)
398 else:
399 cherrypy.log( "StatusCode: 107, StatusMessage: VNF_instance NOT PROVIDED" )
400 return {"StatusCode": 107,
401 "StatusMessage": "VNF_instance NOT PROVIDED"}
402
403 if inventory_names != None:
404 cherrypy.log( "Request Decode: Inventory Names " + inventory_names)
405 else:
406 cherrypy.log( "Request Decode: Inventory Names " + "Not provided")
407
408 cherrypy.log( "Request Decode: PlaybookName " + PlaybookName)
409 PlayBookFunction = PlaybookName.rsplit("/",2)[1]
410 PlayBookFile = PlayBookFunction + "/site.yml"
411 cherrypy.log( "Request Decode: PlaybookFunction " + PlayBookFunction)
412 cherrypy.log( "Request Decode: Playbook file " + PlayBookFile)
413
414 BaseDir = ansible_path + "/" + PlaybookName.rsplit("/",1)[0]
415 CopyDir = ansible_path + "/" + PlaybookName.rsplit("/",2)[0]
416 cherrypy.log( "Request Decode: Basedir " + BaseDir)
417 cherrypy.log( "Request Decode: Copydir " + CopyDir)
418
419
420 PlaybookDir = ansible_temp + "/" + \
421 VNF_instance + "_" + str_uuid + "_" + str(Id)
422
423 # AnsibleInv is the directory where the host file to be run exsists
424 AnsibleInv = ansible_path + "/" + VnfType + "/latest/ansible/inventory/" + VNF_instance
Timoney, Dan (dt5972)12622052018-09-12 10:53:10 -0400425 ArchiveFlag = False
426
Taka Chodc4950b2019-01-29 09:30:22 -0500427 # Create base run directory if it doesn't exist
428 if not os.path.exists(ansible_temp):
429 cherrypy.log( "Creating Base Run Directory: " + ansible_temp)
430 os.makedirs(ansible_temp)
Timoney, Dan (dt5972)12622052018-09-12 10:53:10 -0400431
Taka Chodc4950b2019-01-29 09:30:22 -0500432 if not os.path.exists( CopyDir ):
433 cherrypy.log("Playbook Not Found")
434 return {"StatusCode": 101,
435 "StatusMessage": "PLAYBOOK NOT FOUND"}
Timoney, Dan (dt5972)12622052018-09-12 10:53:10 -0400436
Taka Chodc4950b2019-01-29 09:30:22 -0500437 # copy static playbook dir to run dir
438 cherrypy.log("Copying from " + CopyDir + " to " + PlaybookDir)
439 shutil.copytree(CopyDir, PlaybookDir)
440 cmd="/usr/bin/find " + PlaybookDir + " -exec /usr/bin/touch {} \;"
441 cmd="/usr/bin/find " + PlaybookDir + " -exec chmod +rx {} \;"
442 sys_call(cmd)
443 cherrypy.log(cmd)
444
445 cherrypy.log( "PlaybookDir: " + PlaybookDir)
446 cherrypy.log( "AnsibleInv: " + AnsibleInv)
Timoney, Dan (dt5972)12622052018-09-12 10:53:10 -0400447
448 # Process inventory file for target
449
450 hostgrouplist = []
451 hostnamelist = []
452
453 NodeList = []
454 if 'NodeList' in input_json:
455 NodeList = input_json['NodeList']
456
Taka Chodc4950b2019-01-29 09:30:22 -0500457 cherrypy.log("NodeList: " + str(NodeList));
Timoney, Dan (dt5972)12622052018-09-12 10:53:10 -0400458
Taka Chodc4950b2019-01-29 09:30:22 -0500459 # if NodeList empty
Timoney, Dan (dt5972)12622052018-09-12 10:53:10 -0400460 if NodeList == []:
Taka Chodc4950b2019-01-29 09:30:22 -0500461 cherrypy.log( "*** NodeList - Empty ***")
Timoney, Dan (dt5972)12622052018-09-12 10:53:10 -0400462
463 else:
Taka Chodc4950b2019-01-29 09:30:22 -0500464 HaveNodeList = True
Timoney, Dan (dt5972)12622052018-09-12 10:53:10 -0400465
Taka Chodc4950b2019-01-29 09:30:22 -0500466 ###############################################################################
467 ##### Host file processing ###########################
468 ##### 1. Use file delivered with playbook ###########################
469 ##### 2. If HostNames + NodeList generate and use ###########################
470 ###############################################################################
Timoney, Dan (dt5972)12622052018-09-12 10:53:10 -0400471
Taka Chodc4950b2019-01-29 09:30:22 -0500472 #Verify inventory directory exists
473 path = PlaybookDir + "/inventory/"
474 if not os.path.isdir(path):
475 cherrypy.log ("Inventory directory %s does not exist - create it" % path)
476 try:
477 os.mkdir(path)
478 except OSError:
479 cherrypy.log ("Creation of the directory %s failed" % path)
480 else:
481 cherrypy.log ("Successfully created the directory %s " % path)
Timoney, Dan (dt5972)12622052018-09-12 10:53:10 -0400482
Taka Chodc4950b2019-01-29 09:30:22 -0500483 #location of host file - Default
484 HostFile = PlaybookDir + "/inventory/" + VNF_instance + "hosts"
485 cherrypy.log("HostFile: " + HostFile)
Timoney, Dan (dt5972)12622052018-09-12 10:53:10 -0400486
Taka Chodc4950b2019-01-29 09:30:22 -0500487 # if NodeList and InventoryNames need to build host file
488 if HaveInventoryNames & HaveNodeList:
489 cherrypy.log("Build host file from NodeList")
490 ret = buildHostsSysCall (input_json, PlaybookDir, inventory_names)
491 if (ret < 0):
492 cherrypy.log("Returning Error: Not running Playbook")
493 return {"StatusCode": 105,
494 "StatusMessage": "NodeList: Missing vnfc-type field"}
Timoney, Dan (dt5972)12622052018-09-12 10:53:10 -0400495
Taka Chodc4950b2019-01-29 09:30:22 -0500496 # Having been built now copy new file to correct file
497 shutil.copy(PlaybookDir + "/host_file.txt", HostFile)
498 cherrypy.log("Copying Generated host file to: " + HostFile)
Timoney, Dan (dt5972)12622052018-09-12 10:53:10 -0400499
500 timeout = timeout_seconds
501 if 'Timeout' in input_json:
502 timeout = int (input_json['Timeout'])
Taka Chodc4950b2019-01-29 09:30:22 -0500503 cherrypy.log("Timeout from API: " + str(timeout))
504
505 else:
506 cherrypy.log("Timeout not passed from API using default: " + str(timeout))
Timoney, Dan (dt5972)12622052018-09-12 10:53:10 -0400507
508 EnvParam = {}
509 if 'EnvParameters' in input_json:
510 EnvParam = input_json['EnvParameters']
511
512 LocalParam = {}
513 if 'LocalParameters' in input_json:
514 LocalParam = input_json['LocalParameters']
515
516 FileParam = {}
517 if 'FileParameters' in input_json:
518 FileParam = input_json['FileParameters']
519
520 callback_flag = None
521 if 'CallBack' in input_json:
522 callback_flag = input_json['CallBack']
523
Taka Chodc4950b2019-01-29 09:30:22 -0500524 # if AnsibleServer is not set to 'na' don't send AnsibleServer in PENDING responce.
525 if AnsibleServer != 'na':
526 TestRecord[Id] = {'PlaybookName': PlaybookName,
527 'Version': version,
528 'NodeList': NodeList,
529 'HostGroupList': hostgrouplist,
530 'HostNameList': hostnamelist,
531 'Time': time_now,
532 'Duration': timeout,
533 'Timeout': timeout,
534 'EnvParameters': EnvParam,
535 'LocalParameters': LocalParam,
536 'FileParameters': FileParam,
537 'CallBack': callback_flag,
538 'Result': {"StatusCode": 100,
539 "StatusMessage": 'PENDING',
540 "AnsibleServer": str(AnsibleServer),
541 "ExpectedDuration": str(timeout) + "sec"},
542 'Log': '',
543 'Output': {},
544 'Path': PlaybookDir,
545 'Mandatory': None}
546 else:
547 TestRecord[Id] = {'PlaybookName': PlaybookName,
Timoney, Dan (dt5972)12622052018-09-12 10:53:10 -0400548 'Version': version,
549 'NodeList': NodeList,
550 'HostGroupList': hostgrouplist,
551 'HostNameList': hostnamelist,
552 'Time': time_now,
553 'Duration': timeout,
554 'Timeout': timeout,
555 'EnvParameters': EnvParam,
556 'LocalParameters': LocalParam,
557 'FileParameters': FileParam,
558 'CallBack': callback_flag,
559 'Result': {"StatusCode": 100,
560 "StatusMessage": 'PENDING',
561 "ExpectedDuration": str(timeout) + "sec"},
562 'Log': '',
563 'Output': {},
564 'Path': PlaybookDir,
565 'Mandatory': None}
566
Taka Chodc4950b2019-01-29 09:30:22 -0500567 cherrypy.log("Test_Record: " + str(TestRecord[Id]))
Timoney, Dan (dt5972)12622052018-09-12 10:53:10 -0400568 # Write files
569
570 if not TestRecord[Id]['FileParameters'] == {}:
571 for key in TestRecord[Id]['FileParameters']:
572 filename = key
573 filecontent = TestRecord[Id]['FileParameters'][key]
574 f = open(PlaybookDir + "/" + filename, "w")
575 f.write(filecontent)
576 f.close()
577
578
579 # Process playbook
Taka Chodc4950b2019-01-29 09:30:22 -0500580 if os.path.exists( ansible_path + '/' + PlaybookName):
581 AnsiblePlaybookFail = False
Timoney, Dan (dt5972)12622052018-09-12 10:53:10 -0400582
Taka Chodc4950b2019-01-29 09:30:22 -0500583 if AnsiblePlaybookFail:
584 #if os.path.exists(PlaybookDir):
585 #shutil.rmtree (PlaybookDir)
Timoney, Dan (dt5972)12622052018-09-12 10:53:10 -0400586 del TestRecord[Id]
587 return {"StatusCode": 101,
588 "StatusMessage": "PLAYBOOK NOT FOUND"}
Timoney, Dan (dt5972)12622052018-09-12 10:53:10 -0400589 else:
590
591 # Test EnvParameters
Taka Chodc4950b2019-01-29 09:30:22 -0500592 playbook_path = PlaybookDir
Timoney, Dan (dt5972)12622052018-09-12 10:53:10 -0400593
594 # Store local vars
595 if not os.path.exists(playbook_path + "/vars"):
596 os.mkdir(playbook_path + "/vars")
597 if not os.path.isfile(playbook_path + "/vars/defaults.yml"):
598 os.mknod(playbook_path + "/vars/defaults.yml")
599
Taka Chodc4950b2019-01-29 09:30:22 -0500600 ###################################################
601 # PAP
602 #write local parameters passed into defaults.yml
603 # PAP
604 f = open(playbook_path + "/vars/defaults.yml","a")
605 #for id, record in TestRecord.items():
606 print TestRecord[Id]['LocalParameters']
607 local_parms = TestRecord[Id]['LocalParameters']
608 for key, value in local_parms.items():
609 f.write(key +"=" + value + "\n");
610 f.close()
611 ###################################################
612
Timoney, Dan (dt5972)12622052018-09-12 10:53:10 -0400613 for key in TestRecord[Id]['LocalParameters']:
614 host_index = []
615 for i in range(len(TestRecord[Id]['HostNameList'])):
616 if key in TestRecord[Id]['HostNameList'][i]:
617 host_index.append(i)
618 if len(host_index) == 0:
619 for i in range(len(TestRecord[Id]['HostGroupList'])):
620 if key in TestRecord[Id]['HostGroupList'][i]:
621 host_index.append(i)
622 if len(host_index) > 0:
623 for i in range(len(host_index)):
624 f = open(playbook_path + "/vars/" +
625 TestRecord[Id]['HostNameList'][host_index[i]] +
626 ".yml", "a")
627 for param in TestRecord[Id]['LocalParameters'][key]:
628 f.write(param + ": " +
629 str (TestRecord[Id]['LocalParameters'][key][param]) +
630 "\n")
631 f.close()
632
Timoney, Dan (dt5972)12622052018-09-12 10:53:10 -0400633
Taka Chodc4950b2019-01-29 09:30:22 -0500634 # write some info out to files before running
635 if auth:
636 f = open(playbook_path + "/User.txt", "a")
637 f.write(cherrypy.request.login)
638 f.close()
639 f = open(playbook_path + "/PlaybookName.txt", "a")
640 f.write(PlaybookName)
641 f.close()
642 f = open(playbook_path + "/PlaybookExDir.txt", "a")
643 f.write(PlaybookDir + "/" + PlayBookFunction)
644 f.close()
645 f = open(playbook_path + "/JsonRequest.txt", "w")
646 #f.write(str(input_json))
647 #print( json.dumps(input_json, indent=4, sort_keys=True))
648 f.write( json.dumps(input_json, indent=4, sort_keys=True))
649 f.close()
650
651
652 # Check that HostFile exists
653 if not os.path.isfile(HostFile):
654 cherrypy.log("Inventory file Not Found: " + HostFile)
655 return {"StatusCode": 101,
656 "StatusMessage": "PLAYBOOK INVENTORY FILE NOT FOUND"}
657
Timoney, Dan (dt5972)12622052018-09-12 10:53:10 -0400658 # Cannot use thread because ansible module uses
659 # signals which are only supported in main thread.
660 # So use multiprocess with shared object
Taka Chodc4950b2019-01-29 09:30:22 -0500661 # args = (callback, Id, PlaybookDir + "/" + AnsibleInv,
Timoney, Dan (dt5972)12622052018-09-12 10:53:10 -0400662
663 p = Process(target = RunAnsible_Playbook,
Taka Chodc4950b2019-01-29 09:30:22 -0500664 args = (callback, Id, HostFile,
665 PlaybookDir + '/' + PlayBookFile,
666 NodeList, TestRecord, PlaybookDir + "/" + PlayBookFunction,
Timoney, Dan (dt5972)12622052018-09-12 10:53:10 -0400667 ArchiveFlag))
668 p.start()
669 ActiveProcess[Id] = p
670 return TestRecord[Id]['Result']
671 else:
Taka Chodc4950b2019-01-29 09:30:22 -0500672 cherrypy.log("TEST ID ALREADY DEFINED")
Timoney, Dan (dt5972)12622052018-09-12 10:53:10 -0400673 return {"StatusCode": 101, "StatusMessage": "TEST ID ALREADY DEFINED"}
674
675 else:
676 return {"StatusCode": 500, "StatusMessage": "REQUEST MUST INCLUDE: NODELIST"}
677
678 else:
Taka Chodc4950b2019-01-29 09:30:22 -0500679 return {"StatusCode": 500, "StatusMessage": "JSON OBJECT MUST INCLUDE: ID, PLAYBOOKNAME, EnvParameters"}
Timoney, Dan (dt5972)12622052018-09-12 10:53:10 -0400680
681 elif 'GET' in cherrypy.request.method:
682
Taka Chodc4950b2019-01-29 09:30:22 -0500683 # Lets pause for a second just incase the resquest was just kicked off
684 time.sleep(1)
685
Timoney, Dan (dt5972)12622052018-09-12 10:53:10 -0400686 input_data = parse_query_string(cherrypy.request.query_string)
Taka Chodc4950b2019-01-29 09:30:22 -0500687
688 # Verify we have a Type passed in GET request
689 if not ( 'Type' in input_data):
690 return {"StatusCode": 500, "StatusMessage": "RESULTS TYPE UNDEFINED"}
691
692 if auth:
693 cherrypy.log( "Request USER: " + cherrypy.request.login)
694 cherrypy.log("Payload: " + str(input_data) + " Type " + input_data['Type'])
695
696 if 'LogRest' in input_data['Type']:
697 sys.stdout.close()
698 sys.stdout = open("/var/log/RestServer.log", "w")
699
700 # Just a debug to dump any records
701 if 'GetStatus' in input_data['Type']:
702 cherrypy.log( "******** Dump Records **********")
703 if TestRecord.items():
704 for id, record in TestRecord.items():
705 cherrypy.log( " Id: " + id)
706 cherrypy.log( "Record: " + str(record))
707 else:
708 cherrypy.log(" No Records to dump")
Timoney, Dan (dt5972)12622052018-09-12 10:53:10 -0400709
710 if 'Id' in input_data and 'Type' in input_data:
Taka Chodc4950b2019-01-29 09:30:22 -0500711 if not ('GetResult' in input_data['Type'] or 'GetOutputLog' in input_data['Type'] or'GetTheOutput' in input_data['Type'] or 'GetLog' in input_data['Type']):
Timoney, Dan (dt5972)12622052018-09-12 10:53:10 -0400712 return {"StatusCode": 500, "StatusMessage": "RESULTS TYPE UNDEFINED"}
713 if input_data['Id'] in TestRecord:
714
715 if 'GetResult' in input_data['Type']:
716
Taka Chodc4950b2019-01-29 09:30:22 -0500717 cherrypy.log( " ** GetResult for: " + str (input_data['Id']))
Timoney, Dan (dt5972)12622052018-09-12 10:53:10 -0400718
719 if 'StatusMessage' in TestRecord[input_data['Id']]['Result'] and getresults_block:
720
Timoney, Dan (dt5972)12622052018-09-12 10:53:10 -0400721
Taka Chodc4950b2019-01-29 09:30:22 -0500722 #check if playbook is still running
Timoney, Dan (dt5972)12622052018-09-12 10:53:10 -0400723 while ActiveProcess[input_data['Id']].is_alive():
Taka Chodc4950b2019-01-29 09:30:22 -0500724 cherrypy.log( "*** Playbook running returning PENDING for " + str(input_data['Id']))
725 ##
726 ## If still running return PENDING response
727 ##
728 if AnsibleServer != 'na':
729 return {"StatusCode": 100,
730 "StatusMessage": 'PENDING',
731 "AnsibleServer": str(AnsibleServer)}
732 else:
733 return {"StatusCode": 100,
734 "StatusMessage": 'PENDING'}
735 #time.sleep(5)
Timoney, Dan (dt5972)12622052018-09-12 10:53:10 -0400736
Taka Chodc4950b2019-01-29 09:30:22 -0500737 #cherrypy.log( "*** Request released " + input_data['Id'])
Timoney, Dan (dt5972)12622052018-09-12 10:53:10 -0400738
Taka Chodc4950b2019-01-29 09:30:22 -0500739 cherrypy.log(str( TestRecord[input_data['Id']]['Result']))
740 cherrypy.log("Output: " + str( TestRecord[input_data['Id']]['Output']))
741 cherrypy.log("StatusCode: " + str( TestRecord[input_data['Id']]['Result']['StatusCode']))
742 cherrypy.log("StatusMessage: " + str( TestRecord[input_data['Id']]['Result']['StatusMessage']))
743
744 #out_obj gets returned to GET request
Timoney, Dan (dt5972)12622052018-09-12 10:53:10 -0400745 if TestRecord[input_data['Id']]['Result']['StatusCode'] == 500:
746 out_obj = TestRecord[input_data['Id']]['Result']['Results']
747 else:
748 out_obj = {"StatusCode": 200,
749 "StatusMessage": "FINISHED",
750 "PlaybookName": TestRecord[input_data['Id']]["PlaybookName"],
751 "Version": TestRecord[input_data['Id']]["Version"],
752 "Duration": TestRecord[input_data['Id']]["Duration"],
Taka Chodc4950b2019-01-29 09:30:22 -0500753 "Output": TestRecord[input_data['Id']]["Output"]["Output"],
Timoney, Dan (dt5972)12622052018-09-12 10:53:10 -0400754 "Results": TestRecord[input_data['Id']]['Result']['Results']}
755 if not TestRecord[input_data['Id']]['Output']['Output'] == {}:
Taka Chodc4950b2019-01-29 09:30:22 -0500756 cherrypy.log("TestRecord has Output:" + str(TestRecord[input_data['Id']]['Output']['Output']))
757 # PAP
Timoney, Dan (dt5972)12622052018-09-12 10:53:10 -0400758 for key in out_obj["Results"]:
Taka Chodc4950b2019-01-29 09:30:22 -0500759 cherrypy.log("Output key: " + str(key))
Timoney, Dan (dt5972)12622052018-09-12 10:53:10 -0400760 if key in TestRecord[input_data['Id']]['Output']['Output']:
761 out_obj["Results"][key]["Output"] = TestRecord[input_data['Id']]['Output']['Output'][key]
762
Taka Chodc4950b2019-01-29 09:30:22 -0500763 cherrypy.log("***** GET RETURNING RESULTS Back ****")
764 cherrypy.log(str(out_obj))
Timoney, Dan (dt5972)12622052018-09-12 10:53:10 -0400765 return out_obj
766
Taka Chodc4950b2019-01-29 09:30:22 -0500767 elif 'GetStatus' in input_data['Type']:
768 print " Dump Records"
769 for id, record in TestRecord,items():
770 print " id: " + id
771 print " Record:" + str(reecord)
772
773 elif 'GetTheOutput' in input_data['Type']:
Timoney, Dan (dt5972)12622052018-09-12 10:53:10 -0400774
775 if TestRecord[input_data['Id']]['Output'] == {} and \
776 getresults_block:
777
Taka Chodc4950b2019-01-29 09:30:22 -0500778 cherrypy.log( "*** Request blocked " + input_data['Id'])
Timoney, Dan (dt5972)12622052018-09-12 10:53:10 -0400779
780 while TestRecord[input_data['Id']]['Output'] == {} \
781 or 'StatusMessage' in TestRecord[input_data['Id']]['Result']:
782 time.sleep(5)
783
Taka Chodc4950b2019-01-29 09:30:22 -0500784 cherrypy.log( "*** Request released " + input_data['Id'])
Timoney, Dan (dt5972)12622052018-09-12 10:53:10 -0400785
Taka Chodc4950b2019-01-29 09:30:22 -0500786 cherrypy.log( "Output: " + str(TestRecord[input_data['Id']]['Output']))
Timoney, Dan (dt5972)12622052018-09-12 10:53:10 -0400787 return {"Output": TestRecord[input_data['Id']]['Output']['Output']}
Taka Chodc4950b2019-01-29 09:30:22 -0500788
789 elif 'GetOutputLog' in input_data['Type']:
790 cherrypy.log("GetOutputLog: processing.")
791 if glob.glob( ansible_temp + '/*_' + input_data['Id']):
792 id = input_data['Id']
793 cherrypy.log("Old directory found for ID: " + id)
794 run_dir = glob.glob( ansible_temp + '/*_' + input_data['Id'])
795 for dir in run_dir:
796 rdir=dir
797 if os.path.exists (rdir + "/PlaybookExDir.txt"):
798 cherrypy.log("Found PlaybookExDir.txt file")
799 f = open( rdir + '/PlaybookExDir.txt', 'r')
800 playbookexdir = f.readline()
801 rdir = playbookexdir
802 f.close()
803 cherrypy.log("Id: " + id)
804 cherrypy.log("RunDir: " + rdir)
805 if os.path.exists( rdir + "/output.log"):
806 cherrypy.log("Found output.log file")
807 f = open( rdir + '/output.log', 'r')
808 output_log = f.readline()
809 f.close()
810 return output_log
811 else:
812 cherrypy.log("Globglob failed:")
813 return
814
Timoney, Dan (dt5972)12622052018-09-12 10:53:10 -0400815 else:
816 # GetLog
817
818 if TestRecord[input_data['Id']]['Log'] == '' and \
819 getresults_block:
820
Taka Chodc4950b2019-01-29 09:30:22 -0500821 cherrypy.log( "*** Request blocked " + input_data['Id'])
Timoney, Dan (dt5972)12622052018-09-12 10:53:10 -0400822
823 while TestRecord[input_data['Id']]['Log'] == '' \
824 or 'StatusMessage' in TestRecord[input_data['Id']]['Result']:
825 time.sleep(5)
826
Taka Chodc4950b2019-01-29 09:30:22 -0500827 cherrypy.log( "*** Request released " + input_data['Id'])
Timoney, Dan (dt5972)12622052018-09-12 10:53:10 -0400828
Taka Chodc4950b2019-01-29 09:30:22 -0500829 cherrypy.log( "Log:" + str(TestRecord[input_data['Id']]['Log']))
Timoney, Dan (dt5972)12622052018-09-12 10:53:10 -0400830 return {"Log": TestRecord[input_data['Id']]['Log']}
831 else:
Taka Chodc4950b2019-01-29 09:30:22 -0500832 # Not in memory check for a file
833 if glob.glob( ansible_temp + '/*_' + input_data['Id']):
834 id = input_data['Id']
835 cherrypy.log("Old directory found for ID: " + id)
836 run_dir = glob.glob( ansible_temp + '/*_' + input_data['Id'])
837 for dir in run_dir:
838 rdir=dir
839 if os.path.exists (rdir + "/PlaybookExDir.txt"):
840 cherrypy.log("Found PlaybookExDir.txt file")
841 f = open( rdir + '/PlaybookExDir.txt', 'r')
842 playbookexdir = f.readline()
843 rdir = playbookexdir
844 f.close()
845 cherrypy.log("Id: " + id)
846 cherrypy.log("RunDir: " + rdir)
847 if 'GetLog' in input_data['Type']:
848 if os.path.exists( rdir + "/output.log"):
849 cherrypy.log("Found output.log file")
850 f = open( rdir + '/output.log', 'r')
851 output_log = f.readline()
852 f.close()
853 return output_log
854 elif 'GetOutputLog' in input_data['Type']:
855 if os.path.exists( rdir + "/output.log"):
856 cherrypy.log("Found output.log file")
857 f = open( rdir + '/output.log', 'r')
858 output_log = f.readline()
859 f.close()
860 return output_log
861 elif 'GetResult' in input_data['Type']:
862 if os.path.exists (rdir + "/PlaybookName.txt"):
863 cherrypy.log("Found PlaybookName.txt file")
864 f = open( rdir + '/PlaybookName.txt', 'r')
865 playbooknametxt = f.readline()
866 f.close()
867 else:
868 playbooknametxt = "NA"
869
870 # Add code to get other items not just output.log from files
871 if os.path.exists( rdir + "/log.file"):
872 cherrypy.log("Found log.file")
873 out_results = "NA:"
874 f = open( rdir + '/log.file', 'r')
875
876 line = f.readline()
877 while line :
878 if "fatal" in line:
879 out_results = out_results + line
880 elif "RECAP" in line:
881 out_results = out_results + line
882 recap_line = f.readline()
883 while recap_line :
884 out_results = out_results + recap_line
885 recap_line = f.readline()
886 line = f.readline()
887 f.close()
888 out_obj = {"StatusCode": 200,
889 "StatusMessage": "FINISHED",
890 "PlaybookName": playbooknametxt,
891 "Version": "Version",
892 "Duration": 200,
893 "Results": out_results}
894 return out_obj
895 else:
896 return {"StatusCode": 500, "StatusMessage": "PLAYBOOK FAILED "}
897
898
899 return {"StatusCode": 500, "StatusMessage": "TEST ID UNDEFINED"}
Timoney, Dan (dt5972)12622052018-09-12 10:53:10 -0400900 else:
901 return {"StatusCode": 500, "StatusMessage": "MALFORMED REQUEST"}
902 elif 'DELETE' in cherrypy.request.method:
903 input_data = parse_query_string(cherrypy.request.query_string)
904
Taka Chodc4950b2019-01-29 09:30:22 -0500905 cherrypy.log( "***> in RestServer.DELETE")
906 cherrypy.log("Payload: " + str(input_data))
Timoney, Dan (dt5972)12622052018-09-12 10:53:10 -0400907
908 if input_data['Id'] in TestRecord:
909 if not 'PENDING' in TestRecord[input_data['Id']]['Result']:
Taka Chodc4950b2019-01-29 09:30:22 -0500910 cherrypy.log(" Path: " + str(TestRecord[input_data['Id']]['Path']))
Timoney, Dan (dt5972)12622052018-09-12 10:53:10 -0400911 TestRecord.pop (input_data['Id'])
912 if input_data['Id'] in ActiveProcess:
913 ActiveProcess.pop (input_data['Id'])
914
915 return {"StatusCode": 200, "StatusMessage": "PLAYBOOK EXECUTION RECORDS DELETED"}
916 else:
917 return {"StatusCode": 200, "StatusMessage": "PENDING"}
918 else:
919 return {"StatusCode": 500, "StatusMessage": "TEST ID UNDEFINED"}
920
921
922if __name__ == '__main__':
923
924 # Read configuration
925
926 config_file_path = "RestServer_config"
927
928 if not os.path.exists(config_file_path):
929 print '[INFO] The config file does not exist'
930 sys.exit(0)
931
932 ip = 'na'
Taka Chodc4950b2019-01-29 09:30:22 -0500933 AnsibleServer = 'na'
Timoney, Dan (dt5972)12622052018-09-12 10:53:10 -0400934 port = 'na'
935 tls = False
936 auth = False
937 pub = 'na'
Timoney, Dan (dt5972)12622052018-09-12 10:53:10 -0400938 priv = 'na'
Timoney, Dan (dt5972)12622052018-09-12 10:53:10 -0400939 timeout_seconds = 'na'
940 ansible_path = 'na'
Timoney, Dan (dt5972)12622052018-09-12 10:53:10 -0400941 ansible_temp = 'na'
942 host = 'na'
Taka Chodc4950b2019-01-29 09:30:22 -0500943 users= 'na'
Timoney, Dan (dt5972)12622052018-09-12 10:53:10 -0400944 getresults_block = False
945 from_files = False
946
947 file = open(config_file_path, 'r')
948 for line in file.readlines():
949 if '#' not in line:
950 if 'ip:' in line:
951 ip = line.split(':')[1].strip()
Taka Chodc4950b2019-01-29 09:30:22 -0500952 elif 'AnsibleServer:' in line:
953 AnsibleServer = line.split(':')[1].strip()
Timoney, Dan (dt5972)12622052018-09-12 10:53:10 -0400954 elif 'port:' in line:
955 port = line.split(':')[1].strip()
Taka Chodc4950b2019-01-29 09:30:22 -0500956 elif 'ksalt:' in line:
957 salt = line.split(':')[1].strip()
Timoney, Dan (dt5972)12622052018-09-12 10:53:10 -0400958 elif 'tls:' in line:
959 tls = 'YES' in line.split(':')[1].strip().upper()
960 elif 'auth:' in line:
961 auth = 'YES' in line.split(':')[1].strip().upper()
962 if tls and 'priv:' in line:
963 priv = line.split(':')[1].strip()
964 if tls and 'pub:' in line:
965 pub = line.split(':')[1].strip()
Taka Chodc4950b2019-01-29 09:30:22 -0500966 if tls and 'inter_cert:' in line:
967 intermediate = line.split(':')[1].strip()
Timoney, Dan (dt5972)12622052018-09-12 10:53:10 -0400968 if 'timeout_seconds' in line:
969 timeout_seconds = int (line.split(':')[1].strip())
970 if 'ansible_path' in line:
971 ansible_path = line.split(':')[1].strip()
Timoney, Dan (dt5972)12622052018-09-12 10:53:10 -0400972 if 'ansible_temp' in line:
973 ansible_temp = line.split(':')[1].strip()
974 if 'host' in line:
975 host = line.split(':')[1].strip()
Taka Chodc4950b2019-01-29 09:30:22 -0500976 if 'users' in line:
977 users = line.split(':')[1].strip()
Timoney, Dan (dt5972)12622052018-09-12 10:53:10 -0400978 if 'getresults_block' in line:
979 getresults_block = 'YES' in line.split(':')[1].strip().upper()
980 if 'from_files' in line:
981 from_files = 'YES' in line.split(':')[1].strip().upper()
982 file.close()
983
984 # Initialization
985
986 global_conf = {
987 'global': {
Taka Chodc4950b2019-01-29 09:30:22 -0500988 'log.screen': True,
989 'response.timeout': 5400,
Timoney, Dan (dt5972)12622052018-09-12 10:53:10 -0400990 'server.socket_host': ip,
991 'server.socket_port': int(port),
992 'server.protocol_version': 'HTTP/1.1'
993 }
994 }
995
996 if tls:
997 # Use pythons built-in SSL
998 cherrypy.server.ssl_module = 'builtin'
999
1000 # Point to certificate files
1001
1002 if not os.path.exists(pub):
1003 print '[INFO] The public certificate does not exist'
1004 sys.exit(0)
1005
1006 if not os.path.exists(priv):
1007 print '[INFO] The private key does not exist'
1008 sys.exit(0)
Taka Chodc4950b2019-01-29 09:30:22 -05001009
1010 if not os.path.exists(intermediate):
1011 print '[INFO] The intermediate certificate does not exist'
1012 sys.exit(0)
1013
Timoney, Dan (dt5972)12622052018-09-12 10:53:10 -04001014
1015 cherrypy.server.ssl_certificate = pub
Taka Chodc4950b2019-01-29 09:30:22 -05001016 cherrypy.server.ssl_certificate_chain = intermediate
Timoney, Dan (dt5972)12622052018-09-12 10:53:10 -04001017 cherrypy.server.ssl_private_key = priv
1018
1019 if auth:
Taka Chodc4950b2019-01-29 09:30:22 -05001020 # Read in and build user dictionary
1021 if not os.path.exists(users):
1022 print '[INFO] The users file does not exist: ' + users
1023 sys.exit(0)
1024 userpassdict = {}
1025 user_file = open(users, 'r')
1026 for line in user_file.readlines():
1027 if '#' not in line:
1028 id = line.split(':')[0].strip()
1029 pw = line.split(':')[1].strip()
1030 userpassdict[id] = pw
1031 #print str(userpassdict)
Timoney, Dan (dt5972)12622052018-09-12 10:53:10 -04001032
1033 app_conf = {'/':
1034 {'tools.auth_basic.on': True,
1035 'tools.auth_basic.realm': 'earth',
Taka Chodc4950b2019-01-29 09:30:22 -05001036 'tools.auth_basic.checkpassword': validate_password,
Timoney, Dan (dt5972)12622052018-09-12 10:53:10 -04001037 }
1038 }
1039
Taka Chodc4950b2019-01-29 09:30:22 -05001040 application = cherrypy.tree.mount(TestManager(), '/', app_conf)
Timoney, Dan (dt5972)12622052018-09-12 10:53:10 -04001041 else:
Taka Chodc4950b2019-01-29 09:30:22 -05001042 application = cherrypy.tree.mount(TestManager(), '/')
Timoney, Dan (dt5972)12622052018-09-12 10:53:10 -04001043
Taka Chodc4950b2019-01-29 09:30:22 -05001044 cherrypy.config.update({
1045 'log.access_file': "/var/log/RestServer.access"
1046 })
1047 accessLogName = "/var/log/RestServer.access"
1048 applicationLogName = "/var/log/RestServer.log"
Timoney, Dan (dt5972)12622052018-09-12 10:53:10 -04001049 cherrypy.config.update(global_conf)
1050
Taka Chodc4950b2019-01-29 09:30:22 -05001051 log = application.log
1052 log.error_file = ""
1053 log.access_file = ""
1054 from logging import handlers
1055 applicationLogFileHandler = handlers.RotatingFileHandler(applicationLogName, 'a', 1000000, 5000)
1056 accessLogFileHandler = handlers.RotatingFileHandler(accessLogName, 'a', 1000000, 5000)
1057 import logging
1058 applicationLogFileHandler.setLevel(logging.DEBUG)
1059 log.error_log.addHandler(applicationLogFileHandler)
1060 log.access_log.addHandler(accessLogFileHandler)
1061
Timoney, Dan (dt5972)12622052018-09-12 10:53:10 -04001062 # Start server
1063
1064 cherrypy.engine.start()
1065 cherrypy.engine.block()