Merge branch 'fibre' of ssh://git.onelab.eu/git/myslice into fibre
[unfold.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     for o in objects :
66         if (o in log) :
67             log[o] = objects[o]
68     
69     try :
70         result = urllib2.urlopen(server, urllib.urlencode(log))
71         print "===============>> activity: %s <%s> %s" % (action, request.user,message)
72         content = result.read()
73     except urllib2.URLError as e:
74         print "===============>> activity: connection to " + server + " impossible, could not log action"
75         print "==>> " + e.strerror
76
77 def log(request, action, message, objects = None):
78     # Create a new thread in Daemon mode to send the log entry
79     t = threading.Thread(target=logWrite, args=(request, action, message, objects))
80     t.setDaemon(True)
81     t.start()
82
83 def getClientIp(request):
84     x_forwarded_for = request.META.get('HTTP_X_FORWARDED_FOR')
85     if x_forwarded_for:
86         ip = x_forwarded_for.split(',')[0]
87     else:
88         ip = request.META.get('REMOTE_ADDR')
89     return ip
90
91 #
92 # sign the request with the secret key
93 def sign(secret, message):
94     return hmac.new(secret, msg=message, digestmod=hashlib.sha256).hexdigest()