unify handling calls in before and after aspects. check method's return value before...
[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, SliceTag
8 from PLC.TagTypes import TagTypes
9 from PLC.Nodes import Nodes
10 from PLC.Config import Config
11 from pyaspects.meta import MetaAspect
12
13
14 class BaseOMF(object):
15
16     def __init__(self):
17         self.config = Config("/etc/planetlab/plc_config")
18         self.slice = None
19
20         # this was only for debugging, no need to log all method calls here -baris
21         # self.log = open("/var/log/omf/plc_slice_calls.log", "a")
22         self.log = None
23         
24
25     def logit(self, call, args, kwargs, data, slice):
26         if not self.log: return
27
28         self.log.write("%s : args: %s  kwargs: %s\n" % (call, args, kwargs))
29         self.log.write("data: %s\n" % data)
30         self.log.write("%s\n\n" % slice)
31         self.log.flush()
32
33            
34     def get_slice(self, api, id_or_name):
35         slice_filter = {}
36         try: # if integer
37             slice_filter['slice_id'] = int(str(id_or_name))
38         except ValueError:
39             # we have a string
40             slice_filter['name'] = id_or_name
41         slice = Slices(api, slice_filter = slice_filter)[0]
42 # don't bother to check for slice tags for the moment. we'll only
43 # create XMPP pubsub groups for all slices
44 #
45 #         slice_tags = SliceTags(api, slice_tag_filter = { 'slice_id': slice['slice_id'] })
46 #         omf_tag = [tag for tag in slice_tags if tag['name'] == 'omf']
47 #         if omf_tag and omf_tag['value'] not in ('false','0','no'):
48 #             # OK, slice has the "omf" tag set.
49 #             return slice
50 #         return None
51         return slice
52
53     def get_node_hostname(self, api, node_id_or_hostname):
54         node_filter = {}
55         try:
56             node_filter['node_id'] = int(str(node_id_or_hostname))
57         except ValueError:
58             # we have a hostname
59             node_filter['hostname'] = node_id_or_hostname
60
61         try:
62             node = Nodes(api, node_filter = node_filter)[0]
63             return node['hostname']
64         except IndexError:
65             return None
66         
67     def get_slice_tags(self, api, slice_id):
68         return SliceTags(api, slice_tag_filter = {'slice_id': slice_id})
69
70     def get_tag_type(self, api, tagname):
71         try:
72             tag = TagTypes(api, {'tagname':tagname})[0]
73             return tag
74         except IndexError:
75             return None
76
77     def create_slice(self, slice):
78         pass
79
80     def add_resource(self, slice, resource):
81         pass
82
83     def delete_slice(self, slice):
84         pass
85
86     def delete_resource(self, slice, resource):
87         pass
88
89     # aspect method
90     def before(self, wobj, data, *args, **kwargs):
91         api_method_name = wobj.name
92         slice_name_or_id = None
93         node_ids = None
94
95         if api_method_name == "AddSlice":
96             slice_name_or_id = args[1]['name']
97         elif api_method_name == "AddSliceToNodes" or api_method_name == "DeleteSliceFromNodes":
98             slice_name_or_id = args[1]
99             node_ids = args[2]
100         elif api_method_name == "AddSliceTag":
101             slice_name_or_id = args[1]
102         elif api_method_name == "DeleteSlice":
103             slice_name_or_id = args[1]        
104         else: # ignore the rest
105             #self.logit(wobj.name, args, kwargs, data, "SLICE")
106             self.slice = None
107             return
108
109         self.slice = self.get_slice(wobj.api, slice_name_or_id)
110
111         self.logit(wobj.name, args, kwargs, data, slice)
112
113     # aspect method
114     def after(self, wobj, data, *args, **kwargs):
115         if not self.slice:
116             return
117
118         if data.has_key("method_return_value") and data['method_return_value'] == 1:
119             # return value 1 means that API call was successful, we can go on.
120             pass
121         else:
122             return
123
124         api_method_name = wobj.name
125
126         if api_method_name == "AddSlice":
127             self.create_slice(slice['name'])
128         elif api_method_name == "AddSliceToNodes":
129             for node_id in node_ids:
130                 node_hostname = self.get_node_hostname(wobj.api, node_id)
131                 self.add_resource(slice['name'], node_hostname)
132         elif api_method_name == "DeleteSlice":
133             self.delete_slice(slice['name'])
134         elif api_method_name == "DeleteSliceFromNodes":
135             for node_id in node_ids:
136                 node_hostname = self.get_node_hostname(wobj.api, node_id)
137                 self.delete_resource(slice['name'], node_hostname)
138         elif api_method_name == "AddSliceTag":
139             # OMF slices need to have dotsshmount vsys tag set to be
140             # able to access users' public keys.
141             tag_type_id_or_name = args[2]
142             omf_tag = self.get_tag_type(wobj.api, "omf_control")
143             vsys_tag = self.get_tag_type(wobj.api, "vsys")
144             if tag_type_id_or_name in (omf_tag['tagname'], omf_tag['tag_type_id']):
145                 slice_tag = SliceTag(wobj.api)
146                 slice_tag['slice_id'] = slice['slice_id']
147                 slice_tag['tag_type_id'] = vsys_tag['tag_type_id']
148                 slice_tag['value'] = u'dotsshmount'
149                 slice_tag.sync()
150
151         self.logit(wobj.name, args, kwargs, data, slice)
152
153
154
155 class OMFAspect_xmlrpc(BaseOMF):
156     __metaclass__ = MetaAspect
157     name = "omfaspect_xmlrpc"
158
159     def __init__(self):
160         BaseOMF.__init__(self)
161
162         slicemgr_url = self.config.PLC_OMF_SLICEMGR_URL
163         self.server = xmlrpclib.ServerProxy(slicemgr_url, allow_none = 1)
164
165     def create_slice(self, slice):
166         self.server.createSlice(slice)
167
168     def add_resource(self, slice, resource):
169         self.server.addResource(slice, resource)
170
171     def delete_slice(self, slice):
172         self.server.deleteSlice(slice)
173         
174     def delete_resource(self, slice, resource):
175         self.server.removeResource(slice, resource)
176
177     def before(self, wobj, data, *args, **kwargs):
178         BaseOMF.before(self, wobj, data, *args, **kwargs)
179
180     def after(self, wobj, data, *args, **kwargs):
181         BaseOMF.after(self, wobj, data, *args, **kwargs)
182
183
184
185 OMFAspect = OMFAspect_xmlrpc
186