source: branches/exodus-admin/views.py@ 6382

Last change on this file since 6382 was 6382, checked in by roland, 16 years ago

Added new branch, for admin interface

  • Property svn:mergeinfo set to
File size: 12.6 KB
Line 
1# (c) Roland van Laar 2006
2
3from django.db import models
4from django.http import HttpResponse, HttpResponseRedirect
5from django.template import Context, loader
6from django.shortcuts import render_to_response
7from django.core.urlresolvers import reverse, NoReverseMatch
8from django.forms.formsets import formset_factory
9from django import forms
10from socket import gethostname
11
12from exodus.models import *
13from exodus.wllogic import free_masterip, newSSIDName, addInterlinkIP, \
14 freeInterlinkIP, freePublicAPIP
15
16from exodus.utils import pdebug
17
18class GenericHandler(object):
19 """Conventions used: type has to to the same name as the dependency
20 object, delet template is named delete<type>.html
21 """
22 def __init__(self, request, mode):
23 pdebug(100, "Function: GenericHandler.__init__")
24 # Strip 'Handler' of name
25 type = self.__class__.__name__[:-7:]
26 formClass = eval(type + 'Form')
27
28 self.object = eval('self.' + type[0].lower() + type[1::])
29 self.title = self.object._meta.verbose_name
30 self.request = request
31 self.mode = mode
32 self.is_changed = {}
33
34 if request.POST.has_key('cancel'):
35 pdebug(100, "Action cancel")
36 self.form_action = 'cancel'
37 # Allow overriding cancel call, in particular with regards to the
38 # response call
39 self._cancel()
40 elif request.POST.has_key('proceed'):
41 pdebug(100, "Action proceed")
42 self.form_action = 'proceed'
43
44 # Delete does not require a valid form
45 if mode == 'delete':
46 self._delete()
47 else:
48 # First checking whether form is valid, then add/edit actions
49 self.form = formClass(request.POST, instance=self.object)
50 try:
51 if self.form.is_valid():
52 pdebug(100, "Form valid")
53 # Set response on forehand, to allow override \
54 # in procedure
55 try:
56 self.response = HttpResponseRedirect(reverse( \
57 'exodus.views.viewNode', args=[self.node.name]))
58 except (AttributeError, NoReverseMatch):
59 self.response = HttpResponseRedirect(reverse( \
60 'exodus.views.viewNodelist'))
61
62 #Checking whether data did change
63 _oldInstance = dict(self.object.as_list())
64 _instance = dict(self.form.save(commit=False).as_list())
65 for key,value in _instance.items():
66 if value != _oldInstance[key]:
67 pdebug(100, "Key %s changed value '%s' -> '%s'"\
68 % (key, _oldInstance[key], value))
69 self.is_changed[key] = value
70
71 # Call override procedure
72 if mode == 'add':
73 self._add()
74 elif mode == 'edit':
75 self._edit()
76 else:
77 raise ValueError, 'Mode "%s" not defined' % mode
78 else:
79 raise ValueError, 'Form error, please edit and resubmit'
80 except ValueError, message:
81 self.response = render_to_response('genericForm.html', {
82 'form': self.form, 'message' : message,
83 'title' : self.title, 'mode' : mode,
84 'type' : type, 'object': self.object,
85 'delInclude' : "delete" + type.capitalize() + ".html",
86 'addInclude' : "add" + type.capitalize() + ".html",
87 'editInclude' : "edit" + type.capitalize() + ".html" })
88 else:
89 message = 'Please edit and submit'
90
91 # Dirty? hack to allow initial form to be filled with date \
92 # for GET request, no errors raised
93 if request.GET and mode == 'add':
94 self.form = formClass(request.GET, instance=self.object)
95 self.form._errors = {}
96 else:
97 self.form = formClass(instance=self.object)
98
99 self.response = render_to_response('genericForm.html', {
100 'form': self.form, 'message' : message, 'title' : self.title,
101 'mode' : mode, 'type' : type, 'object': self.object,
102 'delInclude' : "delete" + type.capitalize() + ".html",
103 'addInclude' : "add" + type.capitalize() + ".html",
104 'editInclude' : "edit" + type.capitalize() + ".html" })
105
106 def _add(self):
107 pdebug(100, "Function: GenericHandler._add")
108 self.form.save()
109
110 def _edit(self):
111 pdebug(100, "Function: GenericHandler._edit")
112 self.form.save()
113
114 def _delete(self):
115 pdebug(100, "Function: GenericHandler._delete")
116 self.object.delete()
117 self.response = HttpResponseRedirect(reverse('exodus.views.viewNode',\
118 args=[self.node.name]))
119
120 def _cancel(self):
121 pdebug(100, "Function: GenericHandler._cancel")
122 self.response = HttpResponseRedirect(reverse('exodus.views.viewNode',\
123 args=[self.node.name]))
124 #self.response = HttpResponseRedirect(reverse('exodus.views.viewNodelist'))
125
126 def render_to_response(self):
127 pdebug(100, "Function: GenericHandler.render_to_response")
128 return self.response
129
130
131#
132# PublicAP
133class PublicAPForm(forms.ModelForm):
134 class Meta:
135 model = PublicAP
136 exclude = ('shortdesc', 'desc', 'ip', 'dhcpstart', 'dhcpstop')
137
138class PublicAPHandler(GenericHandler):
139
140 def __init__(self, request, node, interface, publicAP, mode):
141 pdebug(100, "Function: PublicAPHandler.__init__")
142 self.node = Node.objects.get(name=node)
143 self.interface = Interface.objects.get(node=self.node, iface=interface)
144 if mode == 'add':
145 self.publicAP = PublicAP(iface=self.interface)
146 else:
147 self.publicAP = PublicAP.objects.get(iface=self.interface, \
148 pk=publicAP)
149 super(PublicAPHandler, self).__init__(request, mode)
150
151 def _add(self):
152 pdebug(100, "Function: PublicAPHandler._add")
153 _instance = self.form.save(commit=False)
154 # Find IP range inside interface range with disired size/subnet
155 _instance.ip = freePublicAPIP(_instance.iface, _instance.netmask)
156 _instance.dhcpstart = 1
157 _instance.dhcpstop = 2
158 # If wireless generate ssid name
159 _instance.ssid = newSSIDName(_instance.iface.node, _instance.iface, \
160 'omni')
161 _instance.save()
162
163def genericPublicAP(request, node, interface, publicAP, mode):
164 pdebug(100, "Function: genericPublicAP")
165 handler = PublicAPHandler(request, node, interface, publicAP, mode)
166 return handler.render_to_response()
167
168#
169# Interface
170class InterfaceForm(forms.ModelForm):
171 class Meta:
172 model = Interface
173 exclude = ( 'ip', 'ssid', 'mode', 'channel', 'shortdesc', \
174 'netmask' )
175
176class InterfaceHandler(GenericHandler):
177 def __init__(self, request, node, interface, mode):
178 pdebug(100, "Function: InterfaceHandler.__init__")
179 self.node = Node.objects.get(name=node)
180 if mode == 'add':
181 self.interface = Interface(node=self.node)
182 else:
183 self.interface = Interface.objects.get(node=self.node, \
184 iface=interface)
185 super(InterfaceHandler, self).__init__(request, mode)
186
187 def _add(self):
188 pdebug(100, "Function: InterfaceHandler._add")
189 self._saveInterface()
190
191 def _edit(self):
192 pdebug(100, "Function: InterfaceHandler._edit")
193 self._saveInterface()
194
195 def _saveInterface(self):
196 pdebug(100, "Function: InterfaceHandler._saveInterface")
197 _instance = self.form.save(commit=False)
198 if _instance.link and (_instance.type != _instance.link.type):
199 raise ValueError,'Type of local and remote interface needs to match'
200 if str(_instance.type) != "eth":
201 _instance.ssid = newSSIDName(_instance.node, _instance.iface, \
202 'unused')
203 _instance.channel = '1'
204 _instance.mode = 1 # set to master
205
206 # Only change IP if changes in interface link/mask or new of course :-)
207 if self.mode == 'add' or self.is_changed.has_key('link') or \
208 self.is_changed.has_key('netmask'):
209 if not _instance.link:
210 _instance.ip = freeInterlinkIP(_instance)
211 else:
212 _instance.ip = addInterlinkIP(_instance.link)
213
214 # XXX: Change in netmask requires full range of netmask changes \
215 # on slaves
216 _instance.save()
217 #Dirty to hack to get reference to self working
218 if not _instance.link:
219 _instance.link = _instance
220 _instance.save()
221
222def genericInterface(request, node, interface, mode):
223 pdebug(100, "Function: genericInterface")
224 handler = InterfaceHandler(request, node, interface, mode)
225 return handler.render_to_response()
226
227#
228# Node
229class NodeForm(forms.ModelForm):
230 class Meta:
231 model = Node
232 exclude = ( 'masterip' )
233
234class NodeHandler(GenericHandler):
235 def __init__(self, request, node, mode):
236 pdebug(100, "Function: NodeHandler.__init__")
237 if mode == 'add':
238 self.node = Node()
239 else:
240 self.node = Node.objects.get(name=node)
241 super(NodeHandler, self).__init__(request, mode)
242
243 def _add(self):
244 pdebug(100, "Function: NodeHandler._add")
245 # input a valid master ip into new_data
246 _instance = self.form.save(commit=False)
247 _instance.masterip = free_masterip(_instance.network)
248 _instance.save()
249 self.response = HttpResponseRedirect(reverse('exodus.views.viewNode', \
250 args=[_instance.name]))
251
252 def _delete(self):
253 pdebug(100, "Function: NodeHandler._delete")
254 for _master in Interface.objects.filter(node=self.object):
255 if _master.link == _master:
256 for _makeMaster in Interface.objects.filter(link=_master):
257 _makeMaster.link = _makeMaster
258 _makeMaster.save()
259 self.object.delete()
260 # As node is deleted, goto overview page
261 self.response = HttpResponseRedirect(reverse( \
262 'exodus.views.viewNodelist'))
263
264 def _cancel(self):
265 pdebug(100, "Function: NodeHandler._cancel")
266 if self.mode == 'new':
267 self.response = HttpResponseRedirect(reverse( \
268 'exodus.views.viewNodelist'))
269 else:
270 self.response = HttpResponseRedirect(reverse( \
271 'exodus.views.viewNode', args=[self.node.name]))
272
273def genericNode(request, node, mode):
274 pdebug(100, "Function: genericNode")
275 handler = NodeHandler(request, node, mode)
276 return handler.render_to_response()
277
278#
279# location
280class LocationForm(forms.ModelForm):
281 class Meta:
282 model = Location
283
284class LocationHandler(GenericHandler):
285 def __init__(self, request, location, mode):
286 pdebug(100, "Function: LocationHandler.__init__")
287 if mode == 'add':
288 self.location = Location()
289 else:
290 self.location = Location.objects.get(description=location)
291
292 super(LocationHandler,self).__init__(request, mode)
293
294 def _add(self):
295 pdebug(100, "Function: LocationHandler._add")
296 _instance = self.form.save()
297 # After adding a location, allow adding a Node with this location
298 self.response = HttpResponseRedirect( \
299 reverse('exodus.views.genericNode', args=["add", "new"]) + \
300 "?location=%i" % _instance.pk)
301
302 def _delete(self):
303 pdebug(100, "Function: LocationHandler._delete")
304 self.object.delete()
305 self.response = HttpResponseRedirect(reverse( \
306 'exodus.views.viewNodelist'))
307
308 def _cancel(self):
309 pdebug(100, "Function: LocationHandler._cancel")
310 self.response = HttpResponseRedirect(reverse( \
311 'exodus.views.viewNodelist'))
312
313#
314# Views
315def viewNode(request, node):
316 pdebug(100, "Function: viewNode")
317 node = Node.objects.get(name=node)
318 return render_to_response('viewNode.html', {'node': node})
319
320def viewNodelist(request):
321 pdebug(100, "Function: viewNodelist")
322 nodes = Node.objects.all()
323 configFiles = (
324 'rc.local',
325 'rc.node.local',
326 'dhcpd.conf',
327 'named.conf',
328 'resolv.conf' )
329 return render_to_response('viewNodelist.html', {'nodes' : nodes, \
330 'configFiles' : configFiles})
331
332def configFile(request, version, node, file):
333 pdebug(100, "Function: configFile")
334 node = Node.objects.get(name=node)
335
336 # Extra statictics information for use of generation
337 server = {}
338 server['host'] = gethostname()
339
340 templateFile = version + '/' + file
341 return render_to_response(templateFile, {'node' : node, 'server' : server},\
342 mimetype='text/plain')
343
344#
345# DnsServer
346class DnsServerForm(forms.ModelForm):
347 class Meta:
348 model = DnsServer
349
350class DnsServerHandler(GenericHandler):
351 def __init__(self, request, dnsServer, mode):
352 pdebug(100, "Function: DnsServerHandler.__init__")
353 if mode == 'add':
354 self.dnsServer = DnsServer()
355 else:
356 self.dnsServer= DnsServer.objects.get(ipaddress=dnsServer)
357 super(DnsServerHandler, self).__init__(request, mode)
358
359 def _add(self):
360 pdebug(100, "Function: DnsServerHandler._add")
361 _instance = self.form.save()
362 self.response = HttpResponseRedirect(reverse('exodus.views.viewList', \
363 args=['dnsServer']))
364
365 def _delete(self):
366 pdebug(100, "Function: DnsServerHandler._delete")
367 self.object.delete()
368 self.response = HttpResponseRedirect(reverse('exodus.views.viewList', \
369 args=['dnsServer']))
370
371 def _cancel(self):
372 pdebug(100, "Function: DnsServerHandler._cancel")
373 self.response = HttpResponseRedirect(reverse('exodus.views.viewList', \
374 args=['dnsServer']))
375
376def genericModel(request, model, mode, object):
377 pdebug(100, "Function: genericModel %s, %s, %s" % (model, mode, object))
378 """Wrapper, to get to the function needed"""
379 model = model[0].upper() + model[1::]
380 model = eval(model + 'Handler')
381 handler = model(request, object, mode)
382 return handler.render_to_response()
383
384def viewList(request, model):
385 pdebug(100, "Function: viewList")
386 """Standard interface for simple overview pages, with view/edit/delete
387 buttons on it
388 """
389 modelURL = model
390 model = model[0].upper() + model[1::]
391 modelName = model
392 model = eval(model)
393 objects = model.objects.all()
394 return render_to_response('viewList.html', {'objects': objects, \
395 'modelURL' : modelURL, 'modelName' : modelName})
Note: See TracBrowser for help on using the repository browser.