2 # NEPI, a framework to manage network experiments
3 # Copyright (C) 2013 INRIA
5 # This program is free software: you can redistribute it and/or modify
6 # it under the terms of the GNU General Public License as published by
7 # the Free Software Foundation, either version 3 of the License, or
8 # (at your option) any later version.
10 # This program is distributed in the hope that it will be useful,
11 # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 # GNU General Public License for more details.
15 # You should have received a copy of the GNU General Public License
16 # along with this program. If not, see <http://www.gnu.org/licenses/>.
18 # Author: Alina Quereilhac <alina.quereilhac@inria.fr>
19 # Lucia Guevgeozian Odizzio <lucia.guevgeozian_odizzio@inria.fr>
22 from lxml import etree
26 class SFAResourcesParser(object):
27 # Maybe this init method is not necessary, it was aim to check that the
28 # aggregate was supported by nepi
30 def __init__(self, aggr_pattern):
31 if not isinstance(aggr_pattern, list):
32 self._aggr_pattern = [aggr_pattern]
34 self._aggr_pattern = aggr_pattern
36 def resources_from_xml(self, xml, sliver = False, resources = False):
40 RSpec = etree.fromstring(xml)
41 RSpec_attr = dict(RSpec.attrib)
42 network = RSpec.findall('.//network')
44 aggr = net.get('name')
45 if aggr == 'ple' and resources:
46 node_tree = net.iterfind('node')
47 for node in list(node_tree):
48 if isinstance(node.tag, basestring):
49 data_ple = dict(node.attrib)
50 data_ple['aggregate'] = aggr
51 data_ple['resource_type'] = 'node'
52 data_ple = self._get_node_info(node, data_ple)
53 hostname = node.find('hostname')
54 rdata[hostname.text] = data_ple
56 sliver_defaults = net.find('sliver_defaults')
57 if len(sliver_defaults):
58 stags = self._get_sliver_tags(sliver_defaults, stags)
59 elif aggr == 'omf' and resources:
60 node_tree = net.iterfind('node')
61 for node in node_tree:
62 if isinstance(node.tag, basestring):
63 data_omf = dict(node.attrib)
64 data_omf['aggregate'] = aggr
65 data_omf['resource_type'] = 'node'
66 data_omf = self._get_node_info(node, data_omf)
67 hostname = node.find('hostname')
68 rdata[hostname.text] = data_omf
69 spectrum = net.find('spectrum')
70 for channel in list(spectrum):
71 if isinstance(channel.tag, basestring):
72 data_omf = dict(channel.attrib)
73 data_omf['aggregate'] = aggr
74 data_omf['resource_type'] = 'channel'
75 channelnum = data_omf['channel_num']
76 rdata[channelnum] = data_omf
77 leases = net.iterfind('lease')
78 for lease in list(leases):
79 if isinstance(lease.tag, basestring):
80 (st, duration) = lease.attrib['start_time'], lease.attrib['duration']
81 data_lease = dict(lease.attrib)
82 data_lease['aggregate'] = aggr
83 data_lease['resource_type'] = 'lease'
84 data_lease = self._get_leases_info(lease, data_lease)
85 ldata[(st, duration)] = data_lease
86 elif aggr == 'omf' and not resources:
87 leases = net.iterfind('lease')
88 for lease in list(leases):
89 if isinstance(lease.tag, basestring):
90 (st, duration) = lease.attrib['start_time'], lease.attrib['duration']
91 data_lease = dict(lease.attrib)
92 data_lease['aggregate'] = aggr
93 data_lease['resource_type'] = 'lease'
94 data_lease = self._get_leases_info(lease, data_lease)
95 ldata[(st, duration)] = data_lease
99 return rdata, ldata, stags
105 def _get_node_info(self, node_tag, data_dict):
106 for n in list(node_tag):
107 if isinstance(n.tag, basestring):
109 data_dict[n.tag] = dict(n.attrib)
111 data_dict[n.tag] = n.text
114 def _get_leases_info(self, lease_tag, data_dict):
117 for l in list(lease_tag):
119 node = l.attrib['component_id'].split('+').pop()
121 if l.tag == 'channel':
122 #TODO: find out key when channel reservation
123 #channels.append(l.attrib['averiguar']) channel_num
125 data_dict['nodes'] = nodes
126 data_dict['channels'] = channels
129 def _get_sliver_tags(self, sliverdefaults_tag, sliver_tag_dict):
131 for info in list(sliverdefaults_tag):
132 if info.tag == 'vsys_vnet':
133 sliver_tag_dict['vsys_vnet'] = info.text
134 elif info.tag == 'vsys':
135 vsys.append(info.text)
136 sliver_tag_dict['vsys'] = vsys
137 return sliver_tag_dict
139 def create_reservation_xml(self, xml, slice_hrn, new_resource, start_time, duration, aggregate):
141 RSpec = etree.fromstring(xml)
142 network = RSpec.findall('.//network')
144 aggr = net.get('name')
146 if aggr == aggregate:
147 new_xml = self._create_tags(RSpec, net, slice_hrn, new_resource, start_time, duration)
148 if aggregate not in aggrs:
149 new_net = etree.SubElement(RSpec, 'network', name = aggregate)
150 new_xml = self._create_tags(RSpec, new_net, slice_hrn, new_resource, start_time, duration)
153 def _create_tags(self, RSpec, net, slice_hrn, new_resource, start_time, duration):
154 resource = new_resource.keys()[0]
155 res_type = new_resource[resource]['resource_type']
156 if res_type == 'node':
157 node = etree.SubElement(net, res_type, \
158 component_manager_id = new_resource[resource]['component_manager_id'],\
159 component_id = new_resource[resource]['component_id'],\
160 component_name = new_resource[resource]['component_name'], \
161 site_id = new_resource[resource]['site_id'])
162 sliver_tag = etree.SubElement(node, 'sliver')
163 elif res_type == 'channel':
164 spectrum = etree.SubElement(net, spectrum)
165 channel = etree.SubElement(spectrum, channel,\
166 channel_num = new_resource[resource]['channel_num'],\
167 frequency = new_resource[resource]['frequency'],\
168 standard = new_resource[resource]['standard'])
169 if start_time is not None and duration is not None:
170 slice_id = "urn:publicid:IDN+" + slice_hrn.split('.')[0] + ':' + slice_hrn.split('.')[1]\
171 + '+slice+' + slice_hrn.split('.')[2]
172 lease = etree.SubElement(net, 'lease', slice_id = slice_id,\
173 start_time = str(start_time), duration = str(duration))
174 if res_type == 'node':
175 res = etree.SubElement(lease, res_type,\
176 component_id = new_resource[resource]['component_id'])
177 elif res_type == 'channel':
178 res = etree.SubElement(lease, res_type,\
179 channel_num = new_resource[resource]['channel_num'])
180 new_xml = etree.tostring(RSpec, xml_declaration=True)
183 def verify_reservation_xml(self, xml, slice_hrn, new_resource, start_time, duration, aggregate):
184 slice_id = "urn:publicid:IDN+" + slice_hrn.split('.')[0] + ':' + slice_hrn.split('.')[1]\
185 + '+slice+' + slice_hrn.split('.')[2]
186 rdata, ldata, stags = self.resources_from_xml(xml, sliver = True, resources = True)
187 res_name = new_resource.keys()[0]
188 if res_name in rdata.keys():
189 if start_time and duration:
190 if ldata[(start_time, duration)]:
191 nodes = ldata[(start_time, duration)]['nodes']
192 sliceid = ldata[(start_time, duration)]['slice_id']
193 if res_name in nodes and sliceid == slice_id:
200 def release_reservation_xml(self, xml, slice_hrn, resource, start_time, duration, aggregate):
201 RSpec = etree.fromstring(xml)
202 network = RSpec.findall('.//network')
204 aggr = net.get('name')
205 if aggr == aggregate:
206 new_xml = self._delete_tag(RSpec, net, slice_hrn, resource, start_time, duration)
209 def _delete_tag(self, RSpec, net, slice_hrn, resource, start_time, duration):
210 resource_name = resource.keys()[0]
211 res_type = resource[resource_name]['resource_type']
212 if res_type == 'node':
213 node_tree = net.iterfind('node')
214 for node in list(node_tree):
215 if isinstance(node.tag, basestring):
216 data_node = dict(node.attrib)
217 if data_node['component_name'] == resource_name:
219 elif res_type == 'channel':
220 spectrum = net.find('spectrum')
221 for channel in list(spectrum):
222 if isinstance(channel.tag, basestring):
223 data_channel = dict(channel.attrib)
224 if data_channel['channel_num'] == resource_name:
225 spectrum.remove(channel)
226 if start_time is not None and duration is not None:
227 slice_id = "urn:publicid:IDN+" + slice_hrn.split('.')[0] + ':' + slice_hrn.split('.')[1]\
228 + '+slice+' + slice_hrn.split('.')[2]
229 leases = net.iterfind('lease')
230 for lease in list(leases):
231 if isinstance(lease.tag, basestring):
232 (st, duration) = lease.attrib['start_time'], lease.attrib['duration']
233 sliceid = lease.attrib['slice_id']
234 if st == str(start_time) and duration == str(duration) and sliceid == slice_id:
235 for l in list(lease):
236 if l.tag == 'node' and res_type == 'node':
237 if l.attrib['component_id'].split('+').pop() == resource_name:
239 elif l.tag == 'channel' and res_type == 'channel':
240 if l.attrib['channel_num'] == resource_name:
242 new_xml = etree.tostring(RSpec, xml_declaration=True)