- Change .py files to use 4-space indents and no hard tab characters.
[nodemanager.git] / plugins / sliverauth.py
1 #!/usr/bin/python -tt
2 # vim:set ts=4 sw=4 expandtab:
3 #
4 # $Id$
5 # $URL$
6 #
7 # NodeManager plugin to empower slivers to make API calls
8
9 """
10 Sliver authentication support for NodeManager.
11
12 """
13
14 import errno
15 import os
16 import random
17 import string
18 import tempfile
19 import time
20
21 import logger
22 import tools
23
24 def start(options, conf):
25     logger.log("sliverauth: plugin starting up...")
26
27 def SetSliverTag(plc, slice, tagname, value):
28     node_id = tools.node_id()
29     slivertags=plc.GetSliceTags({"name":slice,"node_id":node_id,"tagname":tagname})
30     if len(slivertags)==0:
31         # looks like GetSlivers reports about delegated/nm-controller slices that do *not* belong to this node
32         # and this is something that AddSliceTag does not like
33         try:
34             slivertag_id=plc.AddSliceTag(slice,tagname,value,node_id)
35         except:
36             logger.log ("sliverauth: SetSliverTag - CAUGHT exception for (probably delegated) slice=%(slice)s tag=%(tagname)s node_id=%(node_id)d"%locals())
37             pass
38     else:
39         slivertag_id=slivertags[0]['slice_tag_id']
40         plc.UpdateSliceTag(slivertag_id,value)
41
42 def GetSlivers(data, config, plc):
43     if 'OVERRIDES' in dir(config):
44         if config.OVERRIDES.get('sliverauth') == '-1':
45             logger.log("sliverauth:  Disabled", 2)
46             return
47
48     if 'slivers' not in data:
49         logger.log_missing_data("sliverauth.GetSlivers", 'slivers')
50         return
51
52     for sliver in data['slivers']:
53         path = '/vservers/%s' % sliver['name']
54         if not os.path.exists(path):
55             # ignore all non-plc-instantiated slivers
56             instantiation = sliver.get('instantiation','')
57             if instantiation == 'plc-instantiated':
58                 logger.log("sliverauth: plc-instantiated slice %s does not yet exist. IGNORING!" % sliver['name'])
59             continue
60
61         found_hmac = False
62         for attribute in sliver['attributes']:
63             name = attribute.get('tagname',attribute.get('name',''))
64             if name == 'hmac':
65                 found_hmac = True
66                 hmac = attribute['value']
67                 break
68
69         if not found_hmac:
70             # XXX need a better random seed?!
71             random.seed(time.time())
72             d = [random.choice(string.letters) for x in xrange(32)]
73             hmac = "".join(d)
74             SetSliverTag(plc,sliver['name'],'hmac',hmac)
75             logger.log("sliverauth: setting %s hmac" % sliver['name'])
76
77         path = '/vservers/%s/etc/planetlab' % sliver['name']
78         if os.path.exists(path):
79             keyfile = '%s/key' % path
80             oldhmac = ''
81             if os.path.exists(keyfile):
82                 f = open(keyfile,'r')
83                 oldhmac = f.read()
84                 f.close()
85
86             if oldhmac <> hmac:
87                 # create a temporary file in the vserver
88                 fd, name = tempfile.mkstemp('','key',path)
89                 os.write(fd,hmac)
90                 os.close(fd)
91                 if os.path.exists(keyfile):
92                     os.unlink(keyfile)
93                 os.rename(name,keyfile)
94                 logger.log("sliverauth: writing hmac to %s " % keyfile)
95
96             os.chmod(keyfile,0400)