OMF integration for plcapi, only activated when PLC_OMF_ENABLED is true.
[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         if isinstance(id_or_name, str):
29             slice_filter['name'] = id_or_name
30         else:
31             slice_filter['slice_id']= id_or_name
32         slice = Slices(api, slice_filter = slice_filter)[0]
33 # don't bother to check for slice tags for the moment. we'll only
34 # create XMPP pubsub groups for all slices
35 #
36 #         slice_tags = SliceTags(api, slice_tag_filter = { 'slice_id': slice['slice_id'] })
37 #         omf_tag = [tag for tag in slice_tags if tag['name'] == 'omf']
38 #         if omf_tag and omf_tag['value'] not in ('false','0','no'):
39 #             # OK, slice has the "omf" tag set.
40 #             return slice
41 #         return None
42         return slice
43
44     def get_node_hostname(self, api, node_id):
45         node_filter = {'node_id': node_id }
46         try:
47             node = Nodes(api, node_filter = node_filter)[0]
48             return node['hostname']
49         except IndexError:
50             return None
51         
52     def get_slice_tags(self, api, slice_id):
53         return SliceTags(api, slice_tag_filter = {'slice_id': slice_id})
54
55     def create_slice(self, slice):
56         pass
57
58     def add_resource(self, slice, resource):
59         pass
60
61     def delete_slice(self, slice):
62         pass
63
64     def delete_resource(self, slice, resource):
65         pass
66
67     # aspect method
68     def before(self, wobj, data, *args, **kwargs):
69         api_method_name = wobj.name
70         slice_name_or_id = None
71         node_ids = None
72
73         # DeleteSlice shall be handled before the actual method call;
74         # after the call we won't be able to acess the slice.
75         if api_method_name == "DeleteSlice":
76             slice_name_or_id = args[1]        
77         else: # ignore the rest
78             return
79
80         slice = self.get_slice(wobj.api, slice_name_or_id)
81         if not slice:
82             return
83
84         if api_method_name == "DeleteSlice":
85             self.delete_slice(slice['name'])
86
87         self.logit(wobj.name, args, kwargs, data, slice)
88
89     # aspect method
90     def after(self, wobj, data, *args, **kwargs):
91         api_method_name = wobj.name
92         slice_name_or_id = None
93         node_ids = None
94         if api_method_name == "AddSlice":
95             slice_name_or_id = args[1]['name']
96         elif api_method_name == "AddSliceToNodes" or api_method_name == "DeleteSliceFromNodes":
97             slice_name_or_id = args[1]
98             node_ids = args[2]
99         else: # ignore the rest
100             #self.logit(wobj.name, args, kwargs, data, "SLICE")
101             return
102
103         slice = self.get_slice(wobj.api, slice_name_or_id)
104         if not slice:
105             return
106
107         if api_method_name == "AddSlice":
108             self.create_slice(slice['name'])
109         elif api_method_name == "AddSliceToNodes":
110             for node_id in node_ids:
111                 node_hostname = self.get_node_hostname(wobj.api, node_id)
112                 self.add_resource(slice['name'], node_hostname)
113         elif api_method_name == "DeleteSliceFromNodes":
114             for node_id in node_ids:
115                 node_hostname = self.get_node_hostname(wobj.api, node_id)
116                 self.delete_resource(slice['name'], node_hostname)
117
118         self.logit(wobj.name, args, kwargs, data, slice)
119
120
121 class OMFAspect_xmpp(BaseOMF):
122     __metaclass__ = MetaAspect
123     name = "omfaspect_xmpp"
124
125     def __init__(self):
126         BaseOMF.__init__(self)
127         xmppserver = self.config.PLC_OMF_XMPP_SERVER
128         xmppuser = "@".join([self.config.PLC_OMF_XMPP_USER, xmppserver])
129         xmpppass = self.config.PLC_OMF_XMPP_PASSWORD
130         self.slicemgr = Slicemgr(xmppuser, xmpppass,
131                                  log=open("/var/log/omf/pubsub_client.log", "a"),
132                                  verbose=True)
133
134     def create_slice(self, slice):
135         self.slicemgr.create_slice(slice)
136
137     def add_resource(self, slice, resource):
138         self.slicemgr.add_resource(slice, resource)
139
140     def delete_slice(self, slice):
141         self.slicemgr.delete_slice(slice)
142
143     def delete_resource(self, slice, resource):
144         self.slicemgr.delete_resource(slice, resource)
145
146     def before(self, wobj, data, *args, **kwargs):
147         BaseOMF.before(self, wobj, data, *args, **kwargs)
148
149     def after(self, wobj, data, *args, **kwargs):
150         BaseOMF.after(self, wobj, data, *args, **kwargs)
151
152
153 class OMFAspect_xmlrpc(BaseOMF):
154     __metaclass__ = MetaAspect
155     name = "omfaspect_xmlrpc"
156
157     def __init__(self):
158         BaseOMF.__init__(self)
159
160         slicemgr_url = self.config.PLC_OMF_SLICEMGR_URL
161         self.server = xmlrpclib.ServerProxy(slicemgr_url)
162
163     def create_slice(self, slice):
164         self.server.slicemgr.createSlice(slice)
165
166     def add_resource(self, slice, resource):
167         self.server.slicemgr.addResource(slice, resource)
168
169     def delete_slice(self, slice):
170         self.server.slicemgr.deleteSlice(slice)
171         
172     def delete_resource(self, slice, resource):
173         self.server.slicemgr.removeResource(slice, resource)
174
175     def before(self, wobj, data, *args, **kwargs):
176         BaseOMF.before(self, wobj, data, *args, **kwargs)
177
178     def after(self, wobj, data, *args, **kwargs):
179         BaseOMF.after(self, wobj, data, *args, **kwargs)
180
181
182
183 OMFAspect = OMFAspect_xmlrpc
184