fix observer for pubsub/configure
[plcapi.git] / aspects / omfaspects.py
1 # Baris Metin <tmetin@sophia.inria.fr>
2
3 import os
4 import xmlrpclib
5
6 from PLC.Slices import Slices
7 from PLC.SliceTags import SliceTags
8 from PLC.Nodes import Nodes
9 from PLC.Config import Config
10 from pyaspects.meta import MetaAspect
11
12
13 class BaseOMF(object):
14
15     def __init__(self):
16         self.config = Config("/etc/planetlab/plc_config")
17         self.log = open("/var/log/omf/plc_slice_calls.log", "a")
18
19     def logit(self, call, args, kwargs, data, slice):
20         self.log.write("%s : args: %s  kwargs: %s\n" % (call, args, kwargs))
21         self.log.write("data: %s\n" % data)
22         self.log.write("%s\n\n" % slice)
23         self.log.flush()
24
25            
26     def get_slice(self, api, id_or_name):
27         slice_filter = {}
28         try: # if integer
29             slice_filter['slice_id'] = int(str(id_or_name))
30         except ValueError:
31             # we have a string
32             slice_filter['name'] = id_or_name
33         slice = Slices(api, slice_filter = slice_filter)[0]
34 # don't bother to check for slice tags for the moment. we'll only
35 # create XMPP pubsub groups for all slices
36 #
37 #         slice_tags = SliceTags(api, slice_tag_filter = { 'slice_id': slice['slice_id'] })
38 #         omf_tag = [tag for tag in slice_tags if tag['name'] == 'omf']
39 #         if omf_tag and omf_tag['value'] not in ('false','0','no'):
40 #             # OK, slice has the "omf" tag set.
41 #             return slice
42 #         return None
43         return slice
44
45     def get_node_hostname(self, api, node_id_or_hostname):
46         node_filter = {}
47         try:
48             node_filter['node_id'] = int(str(node_id_or_hostname))
49         except ValueError:
50             # we have a hostname
51             node_filter['hostname'] = node_id_or_hostname
52
53         try:
54             node = Nodes(api, node_filter = node_filter)[0]
55             return node['hostname']
56         except IndexError:
57             return None
58         
59     def get_slice_tags(self, api, slice_id):
60         return SliceTags(api, slice_tag_filter = {'slice_id': slice_id})
61
62     def create_slice(self, slice):
63         pass
64
65     def add_resource(self, slice, resource):
66         pass
67
68     def delete_slice(self, slice):
69         pass
70
71     def delete_resource(self, slice, resource):
72         pass
73
74     # aspect method
75     def before(self, wobj, data, *args, **kwargs):
76         api_method_name = wobj.name
77         slice_name_or_id = None
78         node_ids = None
79
80         # DeleteSlice shall be handled before the actual method call;
81         # after the call we won't be able to acess the slice.
82         if api_method_name == "DeleteSlice":
83             slice_name_or_id = args[1]        
84         else: # ignore the rest
85             return
86
87         slice = self.get_slice(wobj.api, slice_name_or_id)
88         if not slice:
89             return
90
91         if api_method_name == "DeleteSlice":
92             self.delete_slice(slice['name'])
93
94         self.logit(wobj.name, args, kwargs, data, slice)
95
96     # aspect method
97     def after(self, wobj, data, *args, **kwargs):
98         api_method_name = wobj.name
99         slice_name_or_id = None
100         node_ids = None
101         if api_method_name == "AddSlice":
102             slice_name_or_id = args[1]['name']
103         elif api_method_name == "AddSliceToNodes" or api_method_name == "DeleteSliceFromNodes":
104             slice_name_or_id = args[1]
105             node_ids = args[2]
106         else: # ignore the rest
107             #self.logit(wobj.name, args, kwargs, data, "SLICE")
108             return
109
110         slice = self.get_slice(wobj.api, slice_name_or_id)
111         if not slice:
112             return
113
114         if api_method_name == "AddSlice":
115             self.create_slice(slice['name'])
116         elif api_method_name == "AddSliceToNodes":
117             for node_id in node_ids:
118                 node_hostname = self.get_node_hostname(wobj.api, node_id)
119                 self.add_resource(slice['name'], node_hostname)
120         elif api_method_name == "DeleteSliceFromNodes":
121             for node_id in node_ids:
122                 node_hostname = self.get_node_hostname(wobj.api, node_id)
123                 self.delete_resource(slice['name'], node_hostname)
124
125         self.logit(wobj.name, args, kwargs, data, slice)
126
127
128
129 class OMFAspect_xmlrpc(BaseOMF):
130     __metaclass__ = MetaAspect
131     name = "omfaspect_xmlrpc"
132
133     def __init__(self):
134         BaseOMF.__init__(self)
135
136         slicemgr_url = self.config.PLC_OMF_SLICEMGR_URL
137         self.server = xmlrpclib.ServerProxy(slicemgr_url)
138
139     def create_slice(self, slice):
140         self.server.createSlice(slice)
141
142     def add_resource(self, slice, resource):
143         self.server.addResource(slice, resource)
144
145     def delete_slice(self, slice):
146         self.server.deleteSlice(slice)
147         
148     def delete_resource(self, slice, resource):
149         self.server.removeResource(slice, resource)
150
151     def before(self, wobj, data, *args, **kwargs):
152         BaseOMF.before(self, wobj, data, *args, **kwargs)
153
154     def after(self, wobj, data, *args, **kwargs):
155         BaseOMF.after(self, wobj, data, *args, **kwargs)
156
157
158
159 OMFAspect = OMFAspect_xmlrpc
160