0f545b0038bd60cff21baa803cc7c939a06f4bcf
[nepi.git] / src / neco / util / sfa_sfav1.py
1 # -*- coding: utf-8 -*-
2
3 from lxml import etree
4 #import collections
5 import sys
6
7 class SFAResourcesParser(object):
8     # Maybe this init method is not necessary, it was aim to check that the
9     # aggregate was supported by nepi
10
11     def __init__(self, aggr_pattern):
12         if not isinstance(aggr_pattern, list):
13             self._aggr_pattern = [aggr_pattern]
14         else:
15             self._aggr_pattern = aggr_pattern
16     
17     def resources_from_xml(self, xml, sliver = False, resources = False):
18         rdata = dict()
19         ldata = dict()
20         stags = dict()
21         RSpec = etree.fromstring(xml)
22         RSpec_attr = dict(RSpec.attrib)
23         network = RSpec.findall('.//network')
24         for net in network:
25             aggr = net.get('name') 
26             if aggr == 'ple' and resources:
27                 node_tree = net.iterfind('node')
28                 for node in list(node_tree): 
29                     if isinstance(node.tag, basestring):
30                         data_ple = dict(node.attrib)
31                         data_ple['aggregate'] = aggr
32                         data_ple['resource_type'] = 'node'
33                         data_ple = self._get_node_info(node, data_ple)
34                         hostname = node.find('hostname')
35                         rdata[hostname.text] = data_ple
36                 if sliver:
37                     sliver_defaults = net.find('sliver_defaults')
38                     if len(sliver_defaults):
39                         stags = self._get_sliver_tags(sliver_defaults, stags)
40             elif aggr == 'omf' and resources:
41                 node_tree = net.iterfind('node')
42                 for node in node_tree:
43                     if isinstance(node.tag, basestring):
44                         data_omf = dict(node.attrib)
45                         data_omf['aggregate'] = aggr
46                         data_omf['resource_type'] = 'node'
47                         data_omf = self._get_node_info(node, data_omf)
48                         hostname = node.find('hostname')
49                         rdata[hostname.text] = data_omf
50                 spectrum = net.find('spectrum')
51                 for channel in list(spectrum):
52                     if isinstance(channel.tag, basestring):
53                         data_omf = dict(channel.attrib)
54                         data_omf['aggregate'] = aggr
55                         data_omf['resource_type'] = 'channel'
56                         channelnum = data_omf['channel_num']
57                         rdata[channelnum] = data_omf
58                 leases = net.iterfind('lease')
59                 for lease in list(leases):
60                     if isinstance(lease.tag, basestring):
61                         (st, duration) = lease.attrib['start_time'], lease.attrib['duration']
62                         data_lease = dict(lease.attrib)
63                         data_lease['aggregate'] = aggr
64                         data_lease['resource_type'] = 'lease'
65                         data_lease = self._get_leases_info(lease, data_lease)
66                         ldata[(st, duration)] = data_lease
67             elif aggr == 'omf' and not resources:
68                 leases = net.iterfind('lease')
69                 for lease in list(leases):
70                     if isinstance(lease.tag, basestring):
71                         (st, duration) = lease.attrib['start_time'], lease.attrib['duration']
72                         data_lease = dict(lease.attrib)
73                         data_lease['aggregate'] = aggr
74                         data_lease['resource_type'] = 'lease'
75                         data_lease = self._get_leases_info(lease, data_lease)
76                         ldata[(st, duration)] = data_lease
77             else:
78                 pass
79         if sliver:
80             return rdata, ldata, stags
81         elif resources:
82             return rdata, ldata
83         elif not resources:
84             return ldata
85
86     def _get_node_info(self, node_tag, data_dict):
87         for n in list(node_tag):
88             if isinstance(n.tag, basestring):
89                 if n.attrib:
90                     data_dict[n.tag] = dict(n.attrib)
91                 else:
92                     data_dict[n.tag] = n.text
93         return data_dict
94
95     def _get_leases_info(self, lease_tag, data_dict):
96         nodes = list()
97         channels = list()
98         for l in list(lease_tag):
99             if l.tag == 'node':
100                 node = l.attrib['component_id'].split('+').pop()
101                 nodes.append(node)
102             if l.tag == 'channel':
103                 #TODO: find out key when channel reservation
104                 #channels.append(l.attrib['averiguar']) channel_num
105                 pass
106             data_dict['nodes'] = nodes
107             data_dict['channels'] = channels
108         return data_dict
109
110     def _get_sliver_tags(self, sliverdefaults_tag, sliver_tag_dict):
111         vsys = list()
112         for info in list(sliverdefaults_tag):
113             if info.tag == 'vsys_vnet':
114                 sliver_tag_dict['vsys_vnet'] = info.text
115             elif info.tag == 'vsys':
116                 vsys.append(info.text)
117         sliver_tag_dict['vsys'] = vsys
118         return sliver_tag_dict
119             
120     def create_reservation_xml(self, xml, slice_hrn, new_resource, start_time, duration, aggregate):
121         aggrs = []
122         RSpec = etree.fromstring(xml)
123         network = RSpec.findall('.//network')
124         for net in network:
125             aggr = net.get('name')
126             aggrs.append(aggr)
127             if aggr == aggregate:
128                 new_xml = self._create_tags(RSpec, net, slice_hrn, new_resource, start_time, duration)
129         if aggregate not in aggrs:
130             new_net = etree.SubElement(RSpec, 'network', name = aggregate)
131             new_xml = self._create_tags(RSpec, new_net, slice_hrn, new_resource, start_time, duration)
132         return new_xml
133
134     def _create_tags(self, RSpec, net, slice_hrn, new_resource, start_time, duration):
135         resource = new_resource.keys()[0]
136         res_type = new_resource[resource]['resource_type']
137         if res_type == 'node':
138             node = etree.SubElement(net, res_type, \
139             component_manager_id = new_resource[resource]['component_manager_id'],\
140             component_id = new_resource[resource]['component_id'],\
141             component_name = new_resource[resource]['component_name'], \
142             site_id = new_resource[resource]['site_id'])
143             sliver_tag = etree.SubElement(node, 'sliver')
144         elif res_type == 'channel':
145             spectrum = etree.SubElement(net, spectrum)
146             channel = etree.SubElement(spectrum, channel,\
147             channel_num = new_resource[resource]['channel_num'],\
148             frequency = new_resource[resource]['frequency'],\
149             standard = new_resource[resource]['standard'])
150         if start_time is not None and duration is not None:
151             slice_id = "urn:publicid:IDN+" + slice_hrn.split('.')[0] + ':' + slice_hrn.split('.')[1]\
152             + '+slice+' + slice_hrn.split('.')[2]
153             lease = etree.SubElement(net, 'lease', slice_id = slice_id,\
154             start_time = str(start_time), duration = str(duration))
155             if res_type == 'node':
156                 res = etree.SubElement(lease, res_type,\
157                 component_id = new_resource[resource]['component_id'])
158             elif res_type == 'channel':
159                 res = etree.SubElement(lease, res_type,\
160                 channel_num = new_resource[resource]['channel_num'])
161         new_xml = etree.tostring(RSpec, xml_declaration=True)
162         return new_xml
163                 
164     def verify_reservation_xml(self, xml, slice_hrn, new_resource, start_time, duration, aggregate):
165         slice_id = "urn:publicid:IDN+" + slice_hrn.split('.')[0] + ':' + slice_hrn.split('.')[1]\
166         + '+slice+' + slice_hrn.split('.')[2]
167         rdata, ldata, stags = self.resources_from_xml(xml, sliver = True, resources = True)
168         res_name = new_resource.keys()[0]
169         if res_name in rdata.keys():
170             if start_time and duration:
171                 if ldata[(start_time, duration)]:
172                     nodes = ldata[(start_time, duration)]['nodes']
173                     sliceid = ldata[(start_time, duration)]['slice_id']
174                     if res_name in nodes and sliceid == slice_id:
175                         return True
176                     else: return False
177                 else: return False
178             else: return True
179         else: return False
180
181     def release_reservation_xml(self, xml, slice_hrn, resource, start_time, duration, aggregate):
182         RSpec = etree.fromstring(xml)
183         network = RSpec.findall('.//network')
184         for net in network:
185             aggr = net.get('name')
186             if aggr == aggregate:
187                 new_xml = self._delete_tag(RSpec, net, slice_hrn, resource, start_time, duration)
188                 return new_xml
189
190     def _delete_tag(self, RSpec, net, slice_hrn, resource, start_time, duration):
191         resource_name = resource.keys()[0]
192         res_type = resource[resource_name]['resource_type']
193         if res_type == 'node':
194             node_tree = net.iterfind('node')
195             for node in list(node_tree):
196                 if isinstance(node.tag, basestring):
197                     data_node = dict(node.attrib)
198                     if data_node['component_name'] == resource_name:
199                         net.remove(node)
200         elif res_type == 'channel':
201             spectrum = net.find('spectrum')
202             for channel in list(spectrum):
203                 if isinstance(channel.tag, basestring):
204                     data_channel = dict(channel.attrib)
205                     if data_channel['channel_num'] == resource_name:
206                         spectrum.remove(channel)
207         if start_time is not None and duration is not None:
208             slice_id = "urn:publicid:IDN+" + slice_hrn.split('.')[0] + ':' + slice_hrn.split('.')[1]\
209             + '+slice+' + slice_hrn.split('.')[2]
210             leases = net.iterfind('lease')
211             for lease in list(leases):
212                 if isinstance(lease.tag, basestring):
213                     (st, duration) = lease.attrib['start_time'], lease.attrib['duration']
214                     sliceid = lease.attrib['slice_id']
215                     if st == str(start_time) and duration == str(duration) and sliceid == slice_id:
216                         for l in list(lease):
217                             if l.tag == 'node' and res_type == 'node':
218                                 if l.attrib['component_id'].split('+').pop() == resource_name:
219                                     lease.remove(l)
220                             elif l.tag == 'channel' and res_type == 'channel':
221                                 if l.attrib['channel_num'] == resource_name:
222                                     lease.remove(l)
223         new_xml = etree.tostring(RSpec, xml_declaration=True)
224         return new_xml
225
226