5 from PLC.Config import Config
6 from PLC.Interfaces import Interface, Interfaces
7 from PLC.InterfaceTags import InterfaceTag, InterfaceTags
8 from PLC.Keys import Key, Keys
12 from PLC.Methods.GetSliceFamily import GetSliceFamily
16 from PLC.NodeGroups import NodeGroup, NodeGroups
17 from PLC.NodeTags import NodeTag, NodeTags
18 from PLC.Nodes import Node, Nodes
19 from PLC.Persons import Person, Persons
20 from PLC.SliceTags import SliceTag, SliceTags
21 from PLC.Slices import Slice, Slices
22 from PLC.TagTypes import TagTypes
24 from pyaspects.meta import MetaAspect
26 import func.overlord.client
28 def absorb_exception(function_name):
29 def _wrapper(*args, **kwargs):
31 return function_name(*args, **kwargs)
37 class BaseFunc(object):
40 self.log = open("/var/log/funcaspect/plc_slice_calls.log", "a")
43 self.interface_id = None
46 self.person_name_or_id = None
49 self.slice_name_or_id = None
51 self.tag_name_or_id = None
54 def logit(self, call, args, kwargs, data, slice):
55 if not self.log: return
57 self.log.write("%s : args: %s kwargs: %s\n" % (call, args, kwargs))
58 self.log.write("data: %s\n" % data)
59 self.log.write("%s\n\n" % slice)
63 def get_slice(self, api, slice_id_or_name):
66 slice_filter["slice_id"] = int(str(slice_id_or_name))
69 slice_filter["name"] = slice_id_or_name
70 slice = Slices(api, slice_filter = slice_filter)[0]
74 def get_node_tag(self, api, node_id_or_name):
77 tag_filter["node_tag_id"] = int(str(node_id_or_name))
80 tag_filter["tagname"] = node_id_or_name
81 tag = NodeTags(api, node_tag_filter = tag_filter)[0]
85 def get_person(self, api, person_id_or_name):
88 person_filter["person_id"] = int(str(person_id_or_name))
91 person_filter["email"] = person_id_or_name
92 person = Persons(api, person_filter = person_filter)[0]
96 def get_interface(self, api, interface_id):
97 return Interfaces(api, interface_filter = {"interface_id": interface_id})
100 def get_interfaces(self, api, node_id):
101 return Interfaces(api, interface_filter = {"node_id": node_id})
104 def get_slice_family(self, api, slice_id_or_name):
107 return GetSliceFamily(api).call(api, slice_id_or_name)
109 return "planetlab-f8-i386"
112 def get_slice_tag(self, api, tag_id_or_name):
115 tag_filter["slice_tag_id"] = int(str(tag_id_or_name))
118 tag_filter["tagname"] = tag_id_or_name
119 tag = SliceTags(api, slice_tag_filter = tag_filter)[0]
123 def get_tag_type(self, api, type_id_or_name):
126 tag_filter["tag_type_id"] = int(str(type_id_or_name))
129 tag_filter["tagname"] = type_id_or_name
130 tag = TagTypes(api, tag_type_filter = tag_filter)[0]
134 def get_node_hostname(self, api, node_id_or_hostname):
137 node_filter["node_id"] = int(str(node_id_or_hostname))
140 node_filter["hostname"] = node_id_or_hostname
141 node = Nodes(api, node_filter = node_filter)[0]
142 return node["hostname"]
145 def get_slice_tags(self, api, slice_id):
146 return SliceTags(api, slice_tag_filter = {"slice_id": slice_id})
149 def get_slice_tags_with_tag_type(self, api, tag_type_id):
150 return SliceTags(api, slice_tag_filter = {"tag_type_id": tag_type_id})
153 def get_person_keys(self, api, person_ids):
154 return Keys(api, key_filter = {"person_id": person_ids})
157 def get_node_tags(self, api, node_id):
158 return NodeTags(api, node_tag_filter = {"node_id": node_id})
161 def get_interface_tags(self, api, interface_id):
162 return InterfaceTags(api, interface_tag_filter = {"interface_id": interface_id})
165 def get_node_groups(self, api, nodegroup_id):
166 return NodeGroups(api, nodegroup_filter = {"nodegroup_id": nodegroup_id})
168 def add_slice_to_node(self, slice, node, family, tags, keys):
171 def delete_slice_from_node(self, slice, node):
174 def add_person_to_slice(self, slice, node, person, value):
177 def delete_person_from_slice(self, slice, node, person, value):
180 def add_slice_tag(self, slice, node, tag, value):
183 def add_node_tag(self, node, tag, value):
186 def add_interface(self, node, value):
189 def delete_interface(self, node, value):
192 def delete_node_tag(self, node, tag, value):
195 def delete_slice_tag(self, slice, node, tag, value):
198 def update_node_tag(self, node, tag, value):
201 def update_slice_tag(self, slice, node, tag, value):
204 # aspect method which assigns the required variables
205 def before(self, wobj, data, *args, **kwargs):
206 api_method_name = wobj.name
208 if api_method_name == "AddSliceToNodes" or api_method_name == "DeleteSliceFromNodes":
209 self.slice_name_or_id = args[1]
210 self.node_ids = args[2]
211 elif api_method_name == "AddPersonToSlice" or api_method_name == "DeletePersonFromSlice":
212 self.person_name_or_id = args[1]
213 self.slice_name_or_id = args[2]
215 elif api_method_name == "AddSliceTag":
216 self.slice_name_or_id = args[1]
217 self.tag_name_or_id = args[2]
218 self.tag_value = args[3]
219 elif api_method_name == "DeleteSliceTag":
220 self.tag_name_or_id = args[1]
222 self.tag = self.get_slice_tag(wobj.api, self.tag_name_or_id)
223 self.slice = self.get_slice(wobj.api, self.tag["slice_id"])
225 elif api_method_name == "AddNodeTag":
226 self.node_ids = [args[1]]
227 self.tag_name_or_id = args[2]
228 self.tag_value = args[3]
229 elif api_method_name == "DeleteNodeTag":
230 self.tag_name_or_id = args[1]
232 self.tag = self.get_node_tag(wobj.api, self.tag_name_or_id)
233 elif api_method_name == "UpdateSliceTag" or api_method_name == "UpdateNodeTag":
234 self.tag_name_or_id = args[1]
235 self.tag_value = args[2]
237 elif api_method_name == "AddInterface" or api_method_name == "UpdateInterface":
238 self.node_ids = [args[1]]
239 elif api_method_name == "DeleteInterface":
240 self.interface_id = args[1]
242 elif api_method_name == "DeleteSlice":
243 self.slice_name_or_id = args[1]
244 elif api_method_name == "DeletePerson":
245 self.person_name_or_id = args[1]
247 self.person = self.get_person(wobj.api, self.person_name_or_id)
248 elif api_method_name == "DeleteTagType":
249 self.tag_name_or_id = args[1]
251 tag_type = self.get_tag_type(wobj.api, self.tag_name_or_id)[0]["tag_type_id"]
252 self.slice_ids = [slice_ids["slice_id"] for slice_ids in self.get_slice_tags_with_tag_type(wobj.api, tag_type)]
253 self.slice_ids = list(set(self.slice_ids))
254 # Node/NodeGroups ???
257 else: # ignore the rest
260 if self.slice_name_or_id != None:
261 self.slice = self.get_slice(wobj.api, self.slice_name_or_id)
263 # self.logit(wobj.name, args, kwargs, data, slice)
266 def after(self, wobj, data, *args, **kwargs):
267 #if data.has_key("method_return_value") and data['method_return_value'] > 0:
268 # # return value 1 means that API call was successful, we can go on.
273 api_method_name = wobj.name
275 # assign globals to locals
276 interface_id = self.interface_id
277 node_ids = self.node_ids
278 person_name_or_id = self.person_name_or_id
282 tag_name_or_id = self.tag_name_or_id
283 tag_value = self.tag_value
285 if api_method_name == "AddSliceToNodes":
286 slice_tags = self.get_slice_tags(wobj.api, slice["slice_id"])
287 slice_keys = self.get_person_keys(wobj.api, slice["person_ids"])
288 slice_family = self.get_slice_family(wobj.api, slice["slice_id"])
289 for node_id in node_ids:
290 node_hostname = self.get_node_hostname(wobj.api, node_id)
291 self.add_slice_to_node(slice["name"], node_hostname, slice_family, slice_tags, slice_keys)
292 elif api_method_name == "DeleteSliceFromNodes":
293 for node_id in node_ids:
294 node_hostname = self.get_node_hostname(wobj.api, node_id)
295 self.delete_slice_from_node(slice["name"], node_hostname)
297 elif api_method_name == "AddPersonToSlice":
298 person = self.get_person(wobj.api, person_name_or_id)
299 keys = self.get_person_keys(wobj.api, slice["person_ids"])
300 keys += self.get_person_keys(wobj.api, person["person_id"])
301 for node_id in slice["node_ids"]:
302 node_hostname = self.get_node_hostname(wobj.api, node_id)
303 self.add_person_to_slice(slice["name"], node_hostname, person["email"], keys)
304 elif api_method_name == "DeletePersonFromSlice":
305 person = self.get_person(wobj.api, person_name_or_id)
306 keys = self.get_person_keys(wobj.api, slice["person_ids"])
307 keys.remove(self.get_person_keys(wobj.api, slice["person_ids"])[0])
308 for node_id in slice["node_ids"]:
309 node_hostname = self.get_node_hostname(wobj.api, node_id)
310 self.delete_person_from_slice(slice["name"], node_hostname, person["email"], keys)
312 elif api_method_name == "AddSliceTag":
313 tag = self.get_tag_type(wobj.api, tag_name_or_id)
316 node_ids = slice["node_ids"]
320 node_groups = self.get_node_groups(wobj.api, args[5])
321 node_ids = set.intersection(set(node_groups[0]["node_ids"]), set(slice["node_ids"]))
323 for node_id in node_ids:
324 node_hostname = self.get_node_hostname(wobj.api, node_id)
325 self.add_slice_tag(slice["name"], node_hostname, tag["tagname"], tag_value)
326 elif api_method_name == "DeleteSliceTag":
327 slice = self.get_slice(wobj.api, tag["slice_id"])
328 for node_id in slice["node_ids"]:
329 node_hostname = self.get_node_hostname(wobj.api, node_id)
330 self.delete_slice_tag(slice["name"], node_hostname, tag["tagname"], tag["value"])
331 elif api_method_name == "UpdateSliceTag":
332 tag = self.get_slice_tag(wobj.api, tag_name_or_id)
333 slice = self.get_slice(wobj.api, tag["slice_id"])
334 for node_id in slice["node_ids"]:
335 node_hostname = self.get_node_hostname(wobj.api, tag["node_id"])
336 self.update_slice_tag(slice, node_hostname, tag["tagname"], tag_value)
338 elif api_method_name == "AddNodeTag":
339 tag = self.get_tag_type(wobj.api, tag_name_or_id)
340 for node_id in node_ids:
341 node_hostname = self.get_node_hostname(wobj.api, node_id)
342 self.add_node_tag(node_hostname, tag["tagname"], tag_value)
343 elif api_method_name == "DeleteNodeTag":
344 node_hostname = self.get_node_hostname(wobj.api, tag["node_id"])
345 self.delete_node_tag(node_hostname, tag["tagname"], tag["value"])
346 elif api_method_name == "UpdateNodeTag":
347 tag = self.get_node_tag(wobj.api, tag_name_or_id)
348 for node_id in [tag["node_id"]]:
349 node_hostname = self.get_node_hostname(wobj.api, tag["node_id"])
350 self.update_node_tag(node_hostname, tag["tagname"], tag_value)
352 elif api_method_name == "AddInterface" or api_method_name == "UpdateInterface":
353 for node_id in node_ids:
354 node_hostname = self.get_node_hostname(wobj.api, node_id)
355 node_interfaces = self.get_interfaces(wobj.api, node_id)
356 for node_interface in node_interfaces:
357 #FIXME: Requires pyplnet changes
358 interface_tags = self.get_interface_tags(wobj.api, node_interface["interface_tag_ids"])
359 node_interface["interface_tags"] = interface_tags
360 self.add_interface(node_hostname, node_interfaces)
361 # elif api_method_name == "DeleteInterface":
362 # node_interface = self.get_interface(wobj.api, interface_id)
363 # for node_id in node_interface["node_id"]:
364 # node_hostname = self.get_node_hostname(wobj.api, node_id)
365 # node_interfaces = self.get_interfaces(wobj.api, node_id)
366 # for node_interface in node_interfaces:
367 # #FIXME: Requires pyplnet changes
368 # interface_tags = self.get_interface_tags(wobj.api, node_interface["interface_tag_ids"])
369 # node_interface["interface_tags"] = interface_tags
370 # self.delete_interface(node_hostname, node_interfaces)
372 elif api_method_name == "DeleteSlice":
373 for node_id in slice["node_ids"]:
374 node_hostname = self.get_node_hostname(wobj.api, node_id)
375 self.delete_slice_from_node(slice["name"], node_hostname)
376 elif api_method_name == "DeletePerson":
378 slice_ids = person["slice_ids"]
379 for slice_id in slice_ids:
380 slice = self.get_slice(wobj.api, slice_id)
381 keys = self.get_person_keys(wobj.api, slice["person_ids"])
382 for node_id in slice["node_ids"]:
383 node_hostname = self.get_node_hostname(wobj.api, node_id)
384 self.delete_person_from_slice(slice["name"], node_hostname, person["email"], keys)
385 elif api_method_name == "DeleteTagType":
386 #FIXME: NodeGroups etc.
387 for slice in self.slice_ids:
388 slice = self.get_slice(wobj.api, tag["slice_id"])
389 for node_id in slice["node_ids"]:
390 node_hostname = self.get_node_hostname(wobj.api, node_id)
391 self.delete_slice_tag(slice["name"], node_hostname, tag["tagname"], tag["value"])
393 # self.logit(wobj.name, args, kwargs, data, slice)
395 class FuncAspect_class(BaseFunc):
396 __metaclass__ = MetaAspect
397 name = "funcaspect_class"
399 #node_list = func.overlord.client.Client("*").list_minions()
400 #FIXME: Only control following nodes
401 node_list = ["planetlab-01.cs.princeton.edu", "planetlab-02.cs.princeton.edu", "planetlab-04.cs.princeton.edu", "planetlab-05.cs.princeton.edu"]
406 BaseFunc.__init__(self)
408 def write_to_log(self, line):
409 if not self.log: return
411 date = datetime.datetime.now().strftime("%d/%m/%y %H:%M")
412 self.log.write("%s - %s" % (date, line))
415 def ping(self, node):
417 self.client = func.overlord.client.Client(node, timeout = 10)
422 if self.client.test.ping()[node]:
423 self.client = func.overlord.client.Client(node, timeout = 10, async = True)
429 def add_slice_to_node(self, slice, node, family, tags, keys):
430 self.write_to_log("Func: AddSlice: %s toNode: %s Family: %s\n" % (slice, node, family))
432 if node in self.node_list:
433 self.increment_revision_for_node(node)
435 self.client.nm.AddSliceToNode(slice, tags, keys)
437 self.write_to_log("Func: (AddSlice)Cannot access to node: %s" % node)
439 # if self.ping(node):
440 # self.client.nm.AddSliceToNode(slice, interfaces, family, tags, keys)
444 def delete_slice_from_node(self, slice, node):
445 self.write_to_log("Func: DeleteSlice: %s FromNode: %s\n" % (slice, node))
447 if node in self.node_list:
448 self.increment_revision_for_node(node)
450 self.client.nm.DeleteSliceFromNode(slice)
452 self.write_to_log("Func: (DeleteSlice)Cannot access to node: %s" % node)
454 # if self.pingnode(node):
455 # self.client.nm.DeleteSliceFromNode(slice)
459 def add_person_to_slice(self, slice, node, person, value):
460 self.write_to_log("Func: AddPerson: %s ToSlice: %s onNode: %s\n" % (person, slice, node))
462 if node in self.node_list:
463 self.increment_revision_for_node(node)
465 self.client.nm.AddPersonToSlice(slice, value)
467 self.write_to_log("Func: (AddPersonToSlice)Cannot access to node: %s" % node)
469 # if self.ping(node):
470 # self.client.nm.AddPersonToSlice(slice, value)
474 def delete_person_from_slice(self, slice, node, person, value):
475 self.write_to_log("Func: DeletePerson: %s FromSlice: %s onNode: %s\n" % (person, slice, node))
477 if node in self.node_list:
478 self.increment_revision_for_node(node)
480 self.client.nm.DeletePersonFromSlice(slice, value)
482 self.write_to_log("Func: (DeletePersonFromSlice)Cannot access to node: %s" % node)
484 # if self.ping(node):
485 # self.client.nm.DeletePersonFromSlice(slice, value)
489 def add_slice_tag(self, slice, node, tag, value):
490 self.write_to_log("Func: AddSliceTag: %s Value: %s onSlice:%s onNode: %s\n" % (tag, value, slice, node))
492 if node in self.node_list:
493 self.increment_revision_for_node(node)
495 self.client.nm.AddSliceTag(slice, tag, value)
497 self.write_to_log("Func: (AddSliceTag)Cannot access to node: %s" % node)
499 # if self.ping(node):
500 # self.client.nm.AddSliceTag(slice, tag, value)
504 def delete_slice_tag(self, slice, node, tag, value):
505 self.write_to_log("Func: DeleteSliceTag: %s Value: %s onSlice:%s onNode: %s\n" % (tag, value, slice, node))
507 if node in self.node_list:
508 self.increment_revision_for_node(node)
510 self.client.nm.DeleteSliceTag(slice, tag, value)
512 self.write_to_log("Func: (DeleteSliceTag)Cannot access to node: %s" % node)
514 # if self.ping(node):
515 # self.client.nm.DeleteSliceTag(slice, tag, value)
519 def update_slice_tag(self, slice, node, tag, value):
520 self.write_to_log("Func: UpdateSliceTag: %s Value: %s toSlice: %s onNode: %s\n" % (tag, value, slice, node))
522 # client = func.overlord.client.Client(node, timeout=5, async=True)
523 # if self.ping(node):
524 # self.client.nm.UpdateSliceTag(slice, tag, value)
528 def add_node_tag(self, node, tag, value):
529 self.write_to_log("Func: AddNodeTag: %s Value: %s toNode: %s\n" % (tag, value, node))
531 # if self.ping(node):
532 # self.client.nm.AddNodeTag(tag, value)
536 def delete_node_tag(self, node, tag, value):
537 self.write_to_log("Func: DeleteNodeTag: %s Value: %s fromNode: %s\n" % (tag, value, node))
539 # if self.ping(node):
540 # self.client.nm.DeleteSliceTag(tag, value)
544 def update_node_tag(self, node, tag, value):
545 self.write_to_log("Func: UpdateNodeTag: %s Value: %s toNode: %s\n" % (tag, value, node))
547 # if self.ping(node):
548 # self.client.nm.UpdateNodeTag(tag, value)
552 def add_interface(self, node, value):
553 self.write_to_log("Func: AddInterface: %s toNode: %s\n" % (len(value), node))
555 # if self.ping(node):
556 # self.client.nm.AddInterface(value)
560 def delete_interface(self, node, value):
561 self.write_to_log("Func: DeleteInterface: %s toNode: %s\n" % (len(value), node))
563 # if self.ping(node):
564 # self.client.nm.DeleteInterface(value)
569 def increment_revision_for_node(self, node):
570 filename = "/var/www/html/func/%s" % node
573 if os.path.exists(filename):
574 f = open(filename, "r")
575 value = int(f.read().strip())
578 f = open(filename, "w")
580 f.write("%d" % int(value))
583 def before(self, wobj, data, *args, **kwargs):
584 BaseFunc.before(self, wobj, data, *args, **kwargs)
586 def after(self, wobj, data, *args, **kwargs):
587 BaseFunc.after(self, wobj, data, *args, **kwargs)
589 FuncAspect = FuncAspect_class