ddb75e3f31dcccc9d0cb4099234c01820bc48e6a
[nodemanager.git] / vsys.py
1 # $Id$
2 # $URL$
3
4 """vsys configurator.  Maintains ACLs and script pipes inside vservers based on slice attributes."""
5
6 import logger
7 import os
8 from sets import Set
9
10 VSYSCONF="/etc/vsys.conf"
11 VSYSBKEND="/tmp/vsys"
12
13 def start(options, config):
14     pass
15
16
17 def GetSlivers(data):
18     """For each sliver with the vsys attribute, set the script ACL, create the vsys directory in the slice, and restart vsys."""
19     # Touch ACLs and create dict of available
20     scripts = dict.fromkeys(touchAcls(),[])
21     # slices that need to be written to the conf
22     slices = []
23     # Parse attributes and update dict of scripts
24     for sliver in data['slivers']:
25         for attribute in sliver['attributes']:
26             if attribute['name'] == 'vsys':
27                 # add to conf
28                 slices.append(sliver['name'])
29                 # As the name implies, when we find an attribute, we
30                 createVsysDir(sliver['name'])
31                 # add it to our list of slivers that need vsys
32                 if attribute['value'] in scripts.keys():
33                     scripts[attribute['value']].append(slice['name'])
34  
35     # Write the conf
36     writeConf(slices, parseConf())
37     # Write out the ACLs
38     if writeAcls(scripts, parseAcls()): 
39         logger.log("vsys: restarting vsys service")
40         os.system("/etc/init.d/vsys restart")
41
42 def createVsysDir(sliver):
43     '''Create /vsys directory in slice.  Update vsys conf file.'''
44     try: os.makedirs("/vservers/%s/vsys" % sliver['name'])
45     except OSError: pass
46
47
48 def touchAcls()
49     '''Creates empty acl files for scripts.  
50     To be ran in case of new scripts that appear in the backend.
51     Returns list of available scripts.'''
52     acls = []
53     scripts = []
54     for (root, dirs, files) in os.walk(VSYSBKEND):
55         for file in files:
56             if file.endswith(".acl"):
57                 acls.append(file.rstrip(".acl")
58             else:
59                 scripts.append(file)
60
61     for new in (Set(scripts) - Set(acls)):
62         logger.log("vsys:  Found new script %s.  Writing empty acl.")
63         f = open("%s/%s.acl" %(VSYSBKEND, new), "w")
64         f.write("\n")
65         f.close()
66     
67     return scripts
68
69
70 def writeAcls(currentscripts, oldscripts):
71     '''Creates .acl files for script in the script repo.'''
72     # Check each oldscript entry to see if we need to modify
73     _restartvsys = False
74     for (acl, oldslivers) in oldscripts.iteritems():
75         if (len(oldslivers) != len(currentscripts[acl])) or \
76         (len(Set(oldslivers) - Set(currentscript[acl])) != 0:
77             _restartvsys = True
78             logger.log("vsys: Updating %s.acl w/ slices %s" % (acl, currentscripts[acl])
79             f = open("%s/%s.acl" % (VSYSBKEND, acl), "w")
80             for slice in currentscripts[acl]: f.write("%s\n" % slice)
81             f.close()
82     # Trigger a restart
83     return _restartvsys
84
85
86 def parseAcls():
87     '''Parse the frontend script acls.  Return {script: [slices]} in conf.'''
88     # make a dict of what slices are in what acls.
89     for (root, dirs, files) in os.walk(VSYSBKEND):
90         for file in files:
91             if file.endswith(".acl"):
92                 f = open(root+"/"+file,"r+")
93                 scriptname = file.rstrip(".acl")
94                 scriptacls[scriptname] = []
95                 for slice in f.readlines():  
96                     scriptacls[scriptname].append(slice.rstrip())
97                 f.close()
98     # return what scripts are configured for which slices.
99     return scriptacls
100
101
102 def writeConf(slivers, oldslivers):
103     # Check if this is needed
104     if (len(slivers) != len(oldslivers)) or \
105     (len(Set(oldslivers) - Set(slivers)) ! = 0):
106         logger.log("vsys:  Updating %s" % VSYSCONF)
107         f = open(VSYSCONF,"w")
108         for sliver in slivers:
109             f.write("/vservers/%(name)s/vsys %(name)s\n" % {"name": sliver})
110         f.truncate()
111         f.close()
112
113 def parseConf();
114     '''Parse the vsys conf and return list of slices in conf.'''
115     scriptacls = {}
116     slicesinconf = []
117     f = open(VSYSCONF)
118     for line in f.readlines():
119         (slice, path) = line.split()
120         slicesinconf.append(slice)
121     f.close()
122     return slicesinconf
123
124