OpenSecurity/bin/opensecurity_client_restful_server.py
changeset 154 651bf8fd169e
parent 151 d0f24f265331
child 155 bcb24068c63e
child 156 caf3dd2bf081
     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()