7396630c39888b3801ecea0ce02d718a2f450611
[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 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         try:
42             slice = Slices(api, slice_filter = slice_filter)[0]
43             return slice
44         except IndexError:
45             return None
46 # don't bother to check for slice tags for the moment. we'll only
47 # create XMPP pubsub groups for all slices
48 #
49 #         slice_tags = SliceTags(api, slice_tag_filter = { 'slice_id': slice['slice_id'] })
50 #         omf_tag = [tag for tag in slice_tags if tag['name'] == 'omf']
51 #         if omf_tag and omf_tag['value'] not in ('false','0','no'):
52 #             # OK, slice has the "omf" tag set.
53 #             return slice
54 #         return None
55
56     def get_node_hrn(self, api, node_id_or_hostname):
57         tag_filter = {'tagname': 'hrn'}
58         try:
59             tag_filter['node_id'] = int(str(node_id_or_hostname))
60         except ValueError:
61             # we have a hostname
62             tag_filter['hostname'] = node_id_or_hostname
63
64         try:
65             tag = NodeTags(api, node_tag_filter = tag_filter)[0]
66             return tag['value']
67         except IndexError:
68             return None
69
70     def get_slice_tags(self, api, slice_id):
71         return SliceTags(api, slice_tag_filter = {'slice_id': slice_id})
72
73     def get_tag_type(self, api, tagname):
74         try:
75             tag = TagTypes(api, {'tagname':tagname})[0]
76             return tag
77         except IndexError:
78             return None
79
80     def create_slice(self, slice):
81         pass
82
83     def add_resource(self, slice, resource):
84         pass
85
86     def delete_slice(self, slice):
87         pass
88
89     def delete_resource(self, slice, resource):
90         pass
91
92     # aspect method
93     def before(self, wobj, data, *args, **kwargs):
94         api_method_name = wobj.name
95         slice_name_or_id = None
96
97         if api_method_name == "AddSlice":
98             slice_name_or_id = args[1]['name']
99         elif api_method_name == "AddSliceToNodes" or api_method_name == "DeleteSliceFromNodes":
100             slice_name_or_id = args[1]
101         elif api_method_name == "AddSliceTag":
102             slice_name_or_id = args[1]
103         elif api_method_name == "DeleteSlice":
104             slice_name_or_id = args[1]        
105         else: # ignore the rest
106             #self.logit(wobj.name, args, kwargs, data, "SLICE")
107             self.slice = None
108             return
109
110         self.slice = self.get_slice(wobj.api, slice_name_or_id)
111
112         self.logit(wobj.name, args, kwargs, data, slice)
113
114     # aspect method
115     def after(self, wobj, data, *args, **kwargs):
116         api_method_name = wobj.name
117
118         if not self.slice:
119             if api_method_name == "AddSlice":
120                 slice_name = args[1]['name']
121                 self.slice = self.get_slice(wobj.api, slice_name)
122             else:
123                 return
124
125         ret_val = None
126         if data.has_key("method_return_value"):
127             ret_val = data['method_return_value']
128
129         if api_method_name == "AddSlice" and ret_val > 0:
130             self.create_slice(self.slice['name'])
131
132         elif api_method_name == "AddSliceToNodes" and ret_val == 1:
133             node_ids = args[2]
134             for node_id in node_ids:
135                 node_hrn = self.get_node_hrn(wobj.api, node_id)
136                 self.add_resource(self.slice['name'], node_hrn)
137
138         elif api_method_name == "DeleteSlice" and ret_val == 1:
139             self.delete_slice(self.slice['name'])
140
141         elif api_method_name == "DeleteSliceFromNodes" and ret_val == 1:
142             node_ids = args[2]
143             for node_id in node_ids:
144                 node_hrn = self.get_node_hrn(wobj.api, node_id)
145                 self.delete_resource(self.slice['name'], node_hrn)
146
147         elif api_method_name == "AddSliceTag":
148             # OMF slices need to have dotsshmount vsys tag set to be
149             # able to access users' public keys.
150             tag_type_id_or_name = args[2]
151             omf_tag = self.get_tag_type(wobj.api, "omf_control")
152             vsys_tag = self.get_tag_type(wobj.api, "vsys")
153             if tag_type_id_or_name in (omf_tag['tagname'], omf_tag['tag_type_id']):
154                 slice_tag = SliceTag(wobj.api)
155                 slice_tag['slice_id'] = self.slice['slice_id']
156                 slice_tag['tag_type_id'] = vsys_tag['tag_type_id']
157                 slice_tag['value'] = u'dotsshmount'
158                 slice_tag.sync()
159
160         self.logit(wobj.name, args, kwargs, data, self.slice)
161
162
163
164 class OMFAspect_xmlrpc(BaseOMF):
165     __metaclass__ = MetaAspect
166     name = "omfaspect_xmlrpc"
167
168     def __init__(self):
169         BaseOMF.__init__(self)
170
171         slicemgr_url = self.config.PLC_OMF_SLICEMGR_URL
172         self.server = xmlrpclib.ServerProxy(slicemgr_url, allow_none = 1)
173
174     def create_slice(self, slice):
175         self.server.createSlice(slice)
176
177     def add_resource(self, slice, resource):
178         self.server.addResource(slice, resource)
179
180     def delete_slice(self, slice):
181         self.server.deleteSlice(slice)
182         
183     def delete_resource(self, slice, resource):
184         self.server.removeResource(slice, resource)
185
186     def before(self, wobj, data, *args, **kwargs):
187         BaseOMF.before(self, wobj, data, *args, **kwargs)
188
189     def after(self, wobj, data, *args, **kwargs):
190         BaseOMF.after(self, wobj, data, *args, **kwargs)
191
192
193
194 OMFAspect = OMFAspect_xmlrpc
195