Merge branch 'onelab' of ssh://git.onelab.eu/git/myslice into onelab
[myslice.git] / activity / __init__.py
1 #
2 # Activity monitor
3 #
4 # Client is authenticated with an API key and a secret
5 # The API key is a 64 chars string (digits and letters) that is passed to the request
6 # The secret is a 64 chars string that is used to sign the request
7 # The generated signature is a SHA256 hes digest
8
9 import urllib, urllib2
10 import threading
11 import hmac
12 import hashlib
13 import base64
14 import time
15 import datetime
16 from myslice.configengine import ConfigEngine
17
18 config = ConfigEngine()
19 if config.activity and config.activity.apikey :
20     apikey = config.activity.apikey
21 else :
22     # apikey will be necessary
23     apikey = None
24
25 if config.activity and config.activity.secret :
26     secret = config.activity.secret
27 else :
28     # secret will be necessary
29     secret = None
30
31 if config.activity and config.activity.server :
32     server = config.activity.server
33 else :
34     # default log server
35     server = "http://athos.ipv6.lip6.fr/activity/push/log"
36
37 def logWrite(request, action, message, objects = None):
38     
39     if not apikey :
40         print "===============>> activity: no apikey"
41         return
42     if not secret :
43         print "===============>> activity: no secret"
44         return
45     
46     timestamp = time.mktime(datetime.datetime.today().timetuple())
47     ip = getClientIp(request)
48     log = {
49         "timestamp" : timestamp,
50         "client_ip" : ip,
51         "host"      : request.get_host(),
52         "referrer"  : request.META.get('HTTP_REFERER'),
53         "user"      : request.user,
54         "action"    : action,
55         "message"   : message,
56         "apikey"    : apikey,
57         "signature" : sign(secret, "%s%s%s%s" % (timestamp, ip, request.user, action)),
58         "slice"     : None,
59         "resource"  : None,
60         "resource_type"     : None,
61         "facility"      : None,
62         "testbed"       : None,
63     }
64     
65     if objects is not None:
66         for o in objects :
67             if (o in log) :
68                 log[o] = objects[o]
69     
70     try :
71         result = urllib2.urlopen(server, urllib.urlencode(log))
72         print "===============>> activity: %s <%s> %s" % (action, request.user,message)
73         content = result.read()
74     except urllib2.URLError as e:
75         print "===============>> activity: connection to " + server + " impossible, could not log action"
76         print e.strerror
77         print ""
78
79 def log(request, action, message, objects = None):
80     # Create a new thread in Daemon mode to send the log entry
81     t = threading.Thread(target=logWrite, args=(request, action, message, objects))
82     t.setDaemon(True)
83     t.start()
84
85 def getClientIp(request):
86     x_forwarded_for = request.META.get('HTTP_X_FORWARDED_FOR')
87     if x_forwarded_for:
88         ip = x_forwarded_for.split(',')[0]
89     else:
90         ip = request.META.get('REMOTE_ADDR')
91     return ip
92
93 #
94 # sign the request with the secret key
95 def sign(secret, message):
96     return hmac.new(secret, msg=message, digestmod=hashlib.sha256).hexdigest()