1 """vsys configurator. Maintains ACLs and script pipes inside vservers based on slice attributes."""
7 VSYSCONF="/etc/vsys.conf"
11 logger.log("vsys: plugin starting up...")
13 def GetSlivers(data, config=None, plc=None):
14 """For each sliver with the vsys attribute, set the script ACL, create the vsys directory in the slice, and restart vsys."""
16 if 'slivers' not in data:
17 logger.log_missing_data("vsys.GetSlivers",'slivers')
20 # Touch ACLs and create dict of available
22 for script in touchAcls(): scripts[script] = []
23 # slices that need to be written to the conf
26 # Parse attributes and update dict of scripts
27 if 'slivers' not in data:
28 logger.log_missing_data("vsys.GetSlivers",'slivers')
30 for sliver in data['slivers']:
31 for attribute in sliver['attributes']:
32 if attribute['tagname'] == 'vsys':
33 if sliver['name'] not in slices:
35 slices.append(sliver['name'])
36 _restart = createVsysDir(sliver['name']) or _restart
37 if attribute['value'] in scripts.keys():
38 scripts[attribute['value']].append(sliver['name'])
41 _restart = writeConf(slices, parseConf()) or _restart
43 if writeAcls(scripts, parseAcls()) or _restart:
46 # check for systemctl, use it if present
47 def restartService ():
48 if tools.has_systemctl():
49 logger.log("vsys: restarting vsys service through systemctl")
50 logger.log_call(["systemctl", "restart", "vsys"])
52 logger.log("vsys: restarting vsys service through /etc/init.d/vsys")
53 logger.log_call(["/etc/init.d/vsys", "restart", ])
55 def createVsysDir(sliver):
56 '''Create /vsys directory in slice. Update vsys conf file.'''
58 os.mkdir("/vservers/%s/vsys" % sliver)
65 '''Creates empty acl files for scripts.
66 To be ran in case of new scripts that appear in the backend.
67 Returns list of available scripts.'''
70 for (root, dirs, files) in os.walk(VSYSBKEND):
72 # ingore scripts that start with local_
73 if file.startswith("local_"): continue
74 if file.endswith(".acl"):
75 acls.append(file.replace(".acl", ""))
78 for new in (set(scripts) - set(acls)):
79 logger.log("vsys: Found new script %s. Writing empty acl." % new)
80 f = open("%s/%s.acl" %(VSYSBKEND, new), "w")
87 def writeAcls(currentscripts, oldscripts):
88 '''Creates .acl files for script in the script repo.'''
89 # Check each oldscript entry to see if we need to modify
91 # for iteritems along dict(oldscripts), if length of values
92 # not the same as length of values of new scripts,
93 # and length of non intersection along new scripts is not 0,
94 # then dicts are different.
95 for (acl, oldslivers) in oldscripts.iteritems():
97 if (len(oldslivers) != len(currentscripts[acl])) or \
98 (len(set(oldslivers) - set(currentscripts[acl])) != 0):
100 logger.log("vsys: Updating %s.acl w/ slices %s" % (acl, currentscripts[acl]))
101 f = open("%s/%s.acl" % (VSYSBKEND, acl), "w")
102 for slice in currentscripts[acl]: f.write("%s\n" % slice)
105 logger.log("vsys: #:)# Warning,Not a valid Vsys script,%s"%acl)
111 '''Parse the frontend script acls. Return {script: [slices]} in conf.'''
112 # make a dict of what slices are in what acls.
114 for (root, dirs, files) in os.walk(VSYSBKEND):
116 if file.endswith(".acl") and not file.startswith("local_"):
117 f = open(root+"/"+file,"r+")
118 scriptname = file.replace(".acl", "")
119 scriptacls[scriptname] = []
120 for slice in f.readlines():
121 scriptacls[scriptname].append(slice.rstrip())
123 # return what scripts are configured for which slices.
127 def writeConf(slivers, oldslivers):
128 # Check if this is needed
129 # The assumption here is if lengths are the same,
130 # and the non intersection of both arrays has length 0,
131 # then the arrays are identical.
132 if (len(slivers) != len(oldslivers)) or \
133 (len(set(oldslivers) - set(slivers)) != 0):
134 logger.log("vsys: Updating %s" % VSYSCONF)
135 f = open(VSYSCONF,"w")
136 for sliver in slivers:
137 f.write("/vservers/%(name)s/vsys %(name)s\n" % {"name": sliver})
146 '''Parse the vsys conf and return list of slices in conf.'''
151 for line in f.readlines():
152 (path, slice) = line.split()
153 slicesinconf.append(slice)
155 except: logger.log_exc("vsys: failed parseConf")
159 # before shutting down slivers, it is safe to first remove them from vsys's scope
160 # so that we are sure that no dangling open file remains
161 # this will also restart vsys if needed
162 def removeSliverFromVsys (sliver):
163 current_slivers=parseConf()
164 new_slivers= [ s for s in current_slivers if s != sliver ]
165 if writeConf (current_slivers, new_slivers):
167 trashVsysHandleInSliver (sliver)
169 logger.log("vsys.removeSliverFromConf: no need to remove %s"%sliver)
172 def trashVsysHandleInSliver (sliver):
173 slice_vsys_area = "/vservers/%s/vsys"%sliver
174 if not os.path.exists(slice_vsys_area):
175 logger.log("vsys.trashVsysHandleInSliver: no action needed, %s not found"%slice_vsys_area)
177 ret=subprocess.call([ 'rm', '-rf' , slice_vsys_area])
178 logger.log ("vsys.trashVsysHandleInSliver: Removed %s (retcod=%s)"%(slice_vsys_area,retcod))