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/>.
20 from lxml import etree
24 class SFAResourcesParser(object):
25 # Maybe this init method is not necessary, it was aim to check that the
26 # aggregate was supported by nepi
28 def __init__(self, aggr_pattern):
29 if not isinstance(aggr_pattern, list):
30 self._aggr_pattern = [aggr_pattern]
32 self._aggr_pattern = aggr_pattern
34 def resources_from_xml(self, xml, sliver = False, resources = False):
38 RSpec = etree.fromstring(xml)
39 RSpec_attr = dict(RSpec.attrib)
40 network = RSpec.findall('.//network')
42 aggr = net.get('name')
43 if aggr == 'ple' and resources:
44 node_tree = net.iterfind('node')
45 for node in list(node_tree):
46 if isinstance(node.tag, basestring):
47 data_ple = dict(node.attrib)
48 data_ple['aggregate'] = aggr
49 data_ple['resource_type'] = 'node'
50 data_ple = self._get_node_info(node, data_ple)
51 hostname = node.find('hostname')
52 rdata[hostname.text] = data_ple
54 sliver_defaults = net.find('sliver_defaults')
55 if len(sliver_defaults):
56 stags = self._get_sliver_tags(sliver_defaults, stags)
57 elif aggr == 'omf' and resources:
58 node_tree = net.iterfind('node')
59 for node in node_tree:
60 if isinstance(node.tag, basestring):
61 data_omf = dict(node.attrib)
62 data_omf['aggregate'] = aggr
63 data_omf['resource_type'] = 'node'
64 data_omf = self._get_node_info(node, data_omf)
65 hostname = node.find('hostname')
66 rdata[hostname.text] = data_omf
67 spectrum = net.find('spectrum')
68 for channel in list(spectrum):
69 if isinstance(channel.tag, basestring):
70 data_omf = dict(channel.attrib)
71 data_omf['aggregate'] = aggr
72 data_omf['resource_type'] = 'channel'
73 channelnum = data_omf['channel_num']
74 rdata[channelnum] = data_omf
75 leases = net.iterfind('lease')
76 for lease in list(leases):
77 if isinstance(lease.tag, basestring):
78 (st, duration) = lease.attrib['start_time'], lease.attrib['duration']
79 data_lease = dict(lease.attrib)
80 data_lease['aggregate'] = aggr
81 data_lease['resource_type'] = 'lease'
82 data_lease = self._get_leases_info(lease, data_lease)
83 ldata[(st, duration)] = data_lease
84 elif aggr == 'omf' and not resources:
85 leases = net.iterfind('lease')
86 for lease in list(leases):
87 if isinstance(lease.tag, basestring):
88 (st, duration) = lease.attrib['start_time'], lease.attrib['duration']
89 data_lease = dict(lease.attrib)
90 data_lease['aggregate'] = aggr
91 data_lease['resource_type'] = 'lease'
92 data_lease = self._get_leases_info(lease, data_lease)
93 ldata[(st, duration)] = data_lease
97 return rdata, ldata, stags
103 def _get_node_info(self, node_tag, data_dict):
104 for n in list(node_tag):
105 if isinstance(n.tag, basestring):
107 data_dict[n.tag] = dict(n.attrib)
109 data_dict[n.tag] = n.text
112 def _get_leases_info(self, lease_tag, data_dict):
115 for l in list(lease_tag):
117 node = l.attrib['component_id'].split('+').pop()
119 if l.tag == 'channel':
120 #TODO: find out key when channel reservation
121 #channels.append(l.attrib['averiguar']) channel_num
123 data_dict['nodes'] = nodes
124 data_dict['channels'] = channels
127 def _get_sliver_tags(self, sliverdefaults_tag, sliver_tag_dict):
129 for info in list(sliverdefaults_tag):
130 if info.tag == 'vsys_vnet':
131 sliver_tag_dict['vsys_vnet'] = info.text
132 elif info.tag == 'vsys':
133 vsys.append(info.text)
134 sliver_tag_dict['vsys'] = vsys
135 return sliver_tag_dict
137 def create_reservation_xml(self, xml, slice_hrn, new_resource, start_time, duration, aggregate):
139 RSpec = etree.fromstring(xml)
140 network = RSpec.findall('.//network')
142 aggr = net.get('name')
144 if aggr == aggregate:
145 new_xml = self._create_tags(RSpec, net, slice_hrn, new_resource, start_time, duration)
146 if aggregate not in aggrs:
147 new_net = etree.SubElement(RSpec, 'network', name = aggregate)
148 new_xml = self._create_tags(RSpec, new_net, slice_hrn, new_resource, start_time, duration)
151 def _create_tags(self, RSpec, net, slice_hrn, new_resource, start_time, duration):
152 resource = new_resource.keys()[0]
153 res_type = new_resource[resource]['resource_type']
154 if res_type == 'node':
155 node = etree.SubElement(net, res_type, \
156 component_manager_id = new_resource[resource]['component_manager_id'],\
157 component_id = new_resource[resource]['component_id'],\
158 component_name = new_resource[resource]['component_name'], \
159 site_id = new_resource[resource]['site_id'])
160 sliver_tag = etree.SubElement(node, 'sliver')
161 elif res_type == 'channel':
162 spectrum = etree.SubElement(net, spectrum)
163 channel = etree.SubElement(spectrum, channel,\
164 channel_num = new_resource[resource]['channel_num'],\
165 frequency = new_resource[resource]['frequency'],\
166 standard = new_resource[resource]['standard'])
167 if start_time is not None and duration is not None:
168 slice_id = "urn:publicid:IDN+" + slice_hrn.split('.')[0] + ':' + slice_hrn.split('.')[1]\
169 + '+slice+' + slice_hrn.split('.')[2]
170 lease = etree.SubElement(net, 'lease', slice_id = slice_id,\
171 start_time = str(start_time), duration = str(duration))
172 if res_type == 'node':
173 res = etree.SubElement(lease, res_type,\
174 component_id = new_resource[resource]['component_id'])
175 elif res_type == 'channel':
176 res = etree.SubElement(lease, res_type,\
177 channel_num = new_resource[resource]['channel_num'])
178 new_xml = etree.tostring(RSpec, xml_declaration=True)
181 def verify_reservation_xml(self, xml, slice_hrn, new_resource, start_time, duration, aggregate):
182 slice_id = "urn:publicid:IDN+" + slice_hrn.split('.')[0] + ':' + slice_hrn.split('.')[1]\
183 + '+slice+' + slice_hrn.split('.')[2]
184 rdata, ldata, stags = self.resources_from_xml(xml, sliver = True, resources = True)
185 res_name = new_resource.keys()[0]
186 if res_name in rdata.keys():
187 if start_time and duration:
188 if ldata[(start_time, duration)]:
189 nodes = ldata[(start_time, duration)]['nodes']
190 sliceid = ldata[(start_time, duration)]['slice_id']
191 if res_name in nodes and sliceid == slice_id:
198 def release_reservation_xml(self, xml, slice_hrn, resource, start_time, duration, aggregate):
199 RSpec = etree.fromstring(xml)
200 network = RSpec.findall('.//network')
202 aggr = net.get('name')
203 if aggr == aggregate:
204 new_xml = self._delete_tag(RSpec, net, slice_hrn, resource, start_time, duration)
207 def _delete_tag(self, RSpec, net, slice_hrn, resource, start_time, duration):
208 resource_name = resource.keys()[0]
209 res_type = resource[resource_name]['resource_type']
210 if res_type == 'node':
211 node_tree = net.iterfind('node')
212 for node in list(node_tree):
213 if isinstance(node.tag, basestring):
214 data_node = dict(node.attrib)
215 if data_node['component_name'] == resource_name:
217 elif res_type == 'channel':
218 spectrum = net.find('spectrum')
219 for channel in list(spectrum):
220 if isinstance(channel.tag, basestring):
221 data_channel = dict(channel.attrib)
222 if data_channel['channel_num'] == resource_name:
223 spectrum.remove(channel)
224 if start_time is not None and duration is not None:
225 slice_id = "urn:publicid:IDN+" + slice_hrn.split('.')[0] + ':' + slice_hrn.split('.')[1]\
226 + '+slice+' + slice_hrn.split('.')[2]
227 leases = net.iterfind('lease')
228 for lease in list(leases):
229 if isinstance(lease.tag, basestring):
230 (st, duration) = lease.attrib['start_time'], lease.attrib['duration']
231 sliceid = lease.attrib['slice_id']
232 if st == str(start_time) and duration == str(duration) and sliceid == slice_id:
233 for l in list(lease):
234 if l.tag == 'node' and res_type == 'node':
235 if l.attrib['component_id'].split('+').pop() == resource_name:
237 elif l.tag == 'channel' and res_type == 'channel':
238 if l.attrib['channel_num'] == resource_name:
240 new_xml = etree.tostring(RSpec, xml_declaration=True)