1.1 --- a/OpenSecurity/bin/opensecurity_client_restful_server.py Wed May 14 18:13:39 2014 +0100
1.2 +++ b/OpenSecurity/bin/opensecurity_client_restful_server.py Mon May 19 13:13:30 2014 +0200
1.3 @@ -33,19 +33,20 @@
1.4 # imports
1.5
1.6 import getpass
1.7 +import glob
1.8 import json
1.9 import os
1.10 import os.path
1.11 +import pickle
1.12 import platform
1.13 import socket
1.14 import subprocess
1.15 import sys
1.16 +import threading
1.17 +import time
1.18 import urllib
1.19 import urllib2
1.20 import web
1.21 -import threading
1.22 -import time
1.23 -import string
1.24
1.25 from opensecurity_util import logger, setupLogger, OpenSecurityException
1.26 if sys.platform == 'win32' or sys.platform == 'cygwin':
1.27 @@ -53,6 +54,7 @@
1.28
1.29 # local
1.30 import __init__ as opensecurity
1.31 +from environment import Environment
1.32
1.33
1.34 # ------------------------------------------------------------
1.35 @@ -76,6 +78,13 @@
1.36 # vars
1.37
1.38
1.39 +"""lock for read/write log file"""
1.40 +log_file_lock = threading.Lock()
1.41 +
1.42 +"""timer for the log file bouncer"""
1.43 +log_file_bouncer = None
1.44 +
1.45 +
1.46 """The REST server object"""
1.47 server = None
1.48
1.49 @@ -170,19 +179,13 @@
1.50 args['user'] = getpass.getuser()
1.51 args['system'] = platform.node() + " " + platform.system() + " " + platform.release()
1.52
1.53 - # bounce log data
1.54 - url_addr = 'http://GIMME-SERVER-TO-LOG-TO/log'
1.55 + # add these to new data to log
1.56 + global log_file_lock
1.57 + log_file_name = os.path.join(Environment('OpenSecurity').log_path, 'vm_new.log')
1.58 + log_file_lock.acquire()
1.59 + pickle.dump(args, open(log_file_name, 'ab'))
1.60 + log_file_lock.release()
1.61
1.62 - # by provided a 'data' we turn this into a POST statement
1.63 - d = urllib.urlencode(args)
1.64 - req = urllib2.Request(url_addr, d)
1.65 - try:
1.66 - res = urllib2.urlopen(req)
1.67 - except:
1.68 - print('failed to contact: ' + url_addr)
1.69 - print('log data: ' + d)
1.70 - return "Failed"
1.71 -
1.72 return "Ok"
1.73
1.74
1.75 @@ -488,12 +491,88 @@
1.76 return True
1.77
1.78
1.79 +def _bounce_vm_logs():
1.80 +
1.81 + """grab all logs from the VMs and push them to the log servers"""
1.82 +
1.83 + global log_file_lock
1.84 +
1.85 + # pick the highest current number
1.86 + cur = 0
1.87 + for f in glob.iglob(os.path.join(Environment('OpenSecurity').log_path, 'vm_cur.log.*')):
1.88 + try:
1.89 + n = f.split('.')[-1:][0]
1.90 + if cur < int(n):
1.91 + cur = int(n)
1.92 + except:
1.93 + pass
1.94 +
1.95 + cur = cur + 1
1.96 +
1.97 + # first add new vm logs to our existing one: rename the log file
1.98 + log_file_name_new = os.path.join(Environment('OpenSecurity').log_path, 'vm_new.log')
1.99 + log_file_name_cur = os.path.join(Environment('OpenSecurity').log_path, 'vm_cur.log.' + str(cur))
1.100 + log_file_lock.acquire()
1.101 + try:
1.102 + os.rename(log_file_name_new, log_file_name_cur)
1.103 + print('new log file: ' + log_file_name_cur)
1.104 + except:
1.105 + pass
1.106 + log_file_lock.release()
1.107 +
1.108 + # now we have a list of next log files to dump
1.109 + log_files = glob.glob(os.path.join(Environment('OpenSecurity').log_path, 'vm_cur.log.*'))
1.110 + log_files.sort()
1.111 + for log_file in log_files:
1.112 +
1.113 + try:
1.114 + f = open(log_file, 'rb')
1.115 + while True:
1.116 + l = pickle.load(f)
1.117 + _push_log(l)
1.118 +
1.119 + except EOFError:
1.120 +
1.121 + try:
1.122 + os.remove(log_file)
1.123 + except:
1.124 + logger.warning('tried to delete log file (pushed to EOF) "' + log_file + '" but failed')
1.125 +
1.126 + except:
1.127 + logger.warning('encountered error while pushing log file "' + log_file + '"')
1.128 +
1.129 + # start bouncer again ...
1.130 + global log_file_bouncer
1.131 + log_file_bouncer = threading.Timer(5.0, _bounce_vm_logs)
1.132 + log_file_bouncer.start()
1.133 +
1.134 +
1.135 +def _push_log(log):
1.136 + """POST a single log to log server
1.137 +
1.138 + @param log the log POST param
1.139 + """
1.140 +
1.141 + url_addr = 'http://GIMME-SERVER-TO-LOG-TO/log'
1.142 +
1.143 + # by provided a 'data' we turn this into a POST statement
1.144 + d = urllib.urlencode(log)
1.145 + req = urllib2.Request(url_addr, d)
1.146 + urllib2.urlopen(req)
1.147 + logger.debug('pushed log to server: ' + str(log))
1.148 +
1.149 +
1.150 def _serve(port):
1.151
1.152 """Start the REST server"""
1.153
1.154 global server
1.155
1.156 + # start the VM-log bouncer timer
1.157 + global log_file_bouncer
1.158 + log_file_bouncer = threading.Timer(5.0, _bounce_vm_logs)
1.159 + log_file_bouncer.start()
1.160 +
1.161 # trick the web.py server
1.162 sys.argv = [__file__, str(port)]
1.163 server = web.application(opensecurity_urls, globals())
1.164 @@ -521,9 +600,12 @@
1.165 if server is None:
1.166 return
1.167
1.168 + global log_file_bouncer
1.169 + if log_file_bouncer is not None:
1.170 + log_file_bouncer.cancel()
1.171 +
1.172 server.stop()
1.173
1.174 -
1.175 # start
1.176 if __name__ == "__main__":
1.177 serve()