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