fixed typos.
[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="/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
43 def createVsysDir(sliver):
44     '''Create /vsys directory in slice.  Update vsys conf file.'''
45     try: os.makedirs("/vservers/%s/vsys" % sliver['name'])
46     except OSError: pass
47
48
49 def touchAcls():
50     '''Creates empty acl files for scripts.  
51     To be ran in case of new scripts that appear in the backend.
52     Returns list of available scripts.'''
53     acls = []
54     scripts = []
55     for (root, dirs, files) in os.walk(VSYSBKEND):
56         for file in files:
57             if file.endswith(".acl"):
58                 acls.append(file.rstrip(".acl"))
59             else:
60                 scripts.append(file)
61     print scripts
62     for new in (Set(scripts) - Set(acls)):
63         logger.log("vsys:  Found new script %s.  Writing empty acl." % new)
64         f = open("%s/%s.acl" %(VSYSBKEND, new), "w")
65         f.write("\n")
66         f.close()
67     
68     return scripts
69
70
71 def writeAcls(currentscripts, oldscripts):
72     '''Creates .acl files for script in the script repo.'''
73     # Check each oldscript entry to see if we need to modify
74     _restartvsys = False
75     for (acl, oldslivers) in oldscripts.iteritems():
76         if (len(oldslivers) != len(currentscripts[acl])) or \
77         (len(Set(oldslivers) - Set(currentscripts[acl])) != 0):
78             _restartvsys = True
79             logger.log("vsys: Updating %s.acl w/ slices %s" % (acl, currentscripts[acl]))
80             f = open("%s/%s.acl" % (VSYSBKEND, acl), "w")
81             for slice in currentscripts[acl]: f.write("%s\n" % slice)
82             f.close()
83     # Trigger a restart
84     return _restartvsys
85
86
87 def parseAcls():
88     '''Parse the frontend script acls.  Return {script: [slices]} in conf.'''
89     # make a dict of what slices are in what acls.
90     scriptacls = {}
91     for (root, dirs, files) in os.walk(VSYSBKEND):
92         for file in files:
93             if file.endswith(".acl"):
94                 f = open(root+"/"+file,"r+")
95                 scriptname = file.rstrip(".acl")
96                 scriptacls[scriptname] = []
97                 for slice in f.readlines():  
98                     scriptacls[scriptname].append(slice.rstrip())
99                 f.close()
100     # return what scripts are configured for which slices.
101     return scriptacls
102
103
104 def writeConf(slivers, oldslivers):
105     # Check if this is needed
106     if (len(slivers) != len(oldslivers)) or \
107     (len(Set(oldslivers) - Set(slivers)) != 0):
108         logger.log("vsys:  Updating %s" % VSYSCONF)
109         f = open(VSYSCONF,"w")
110         for sliver in slivers:
111             f.write("/vservers/%(name)s/vsys %(name)s\n" % {"name": sliver})
112         f.truncate()
113         f.close()
114
115 def parseConf():
116     '''Parse the vsys conf and return list of slices in conf.'''
117     scriptacls = {}
118     slicesinconf = []
119     try: 
120         f = open(VSYSCONF)
121         for line in f.readlines():
122             (slice, path) = line.split()
123             slicesinconf.append(slice)
124         f.close()
125     except: logger.log_exc()
126     return slicesinconf
127
128