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