743d562b469d12cf388045e6b320e1c00149466b
[sfa.git] / sfa / rspecs / elements / versions / nitosv1Node.py
1 from sfa.util.sfalogging import logger
2 from sfa.util.xml import XpathFilter
3 from sfa.util.xrn import Xrn
4
5 from sfa.rspecs.elements.element import Element
6 from sfa.rspecs.elements.node import NodeElement
7 from sfa.rspecs.elements.sliver import Sliver
8 from sfa.rspecs.elements.location import Location
9 from sfa.rspecs.elements.position_3d import Position3D
10 from sfa.rspecs.elements.hardware_type import HardwareType
11 from sfa.rspecs.elements.disk_image import DiskImage
12 from sfa.rspecs.elements.interface import Interface
13 from sfa.rspecs.elements.bwlimit import BWlimit
14 from sfa.rspecs.elements.pltag import PLTag
15 from sfa.rspecs.elements.versions.nitosv1Sliver import NITOSv1Sliver
16 from sfa.rspecs.elements.versions.nitosv1PLTag import NITOSv1PLTag
17 from sfa.rspecs.elements.versions.pgv2Services import PGv2Services
18
19
20 class NITOSv1Node:
21
22     @staticmethod
23     def add_nodes(xml, nodes):
24         network_elems = xml.xpath('//network')
25         if len(network_elems) > 0:
26             network_elem = network_elems[0]
27         elif len(nodes) > 0 and nodes[0].get('component_manager_id'):
28             network_urn = nodes[0]['component_manager_id']
29             network_elem = xml.add_element('network', name = Xrn(network_urn).get_hrn())
30         else:
31             network_elem = xml
32
33         # needs to be improuved to retreive the gateway addr dynamically.
34         gateway_addr = 'nitlab.inf.uth.gr'
35
36         node_elems = []       
37         for node in nodes:
38             node_fields = ['component_manager_id', 'component_id', 'boot_state']
39             node_elem = network_elem.add_instance('node', node, node_fields)
40             node_elems.append(node_elem)
41
42             # determine network hrn
43             network_hrn = None 
44             if 'component_manager_id' in node and node['component_manager_id']:
45                 network_hrn = Xrn(node['component_manager_id']).get_hrn()
46
47             # set component_name attribute and  hostname element
48             if 'component_id' in node and node['component_id']:
49                 component_name = Xrn(xrn=node['component_id']).get_leaf()
50                 node_elem.set('component_name', component_name)
51                 hostname_elem = node_elem.add_element('hostname')
52                 hostname_elem.set_text(component_name)
53
54             # set site id
55             if 'authority_id' in node and node['authority_id']:
56                 node_elem.set('site_id', node['authority_id'])
57
58             # add locaiton
59             location = node.get('location')
60             if location:
61                 node_elem.add_instance('location', location, Location.fields)
62
63             # add 3D Position of the node
64             position_3d = node.get('position_3d')
65             if position_3d:
66                 node_elem.add_instance('position_3d', position_3d, Position3D.fields)
67
68             # all nitos nodes are exculsive
69             exclusive_elem = node_elem.add_element('exclusive')
70             exclusive_elem.set_text('TRUE')
71  
72             # In order to access nitos nodes, one need to pass through the nitos gateway
73             # here we advertise Nitos access gateway address
74             gateway_elem = node_elem.add_element('gateway')
75             gateway_elem.set_text(gateway_addr)
76
77             # add granularity of the reservation system
78             granularity = node.get('granularity')['grain']
79             if granularity:
80                 #node_elem.add_instance('granularity', granularity, granularity.fields)
81                 granularity_elem = node_elem.add_element('granularity')
82                 granularity_elem.set_text(str(granularity))
83             # add hardware type
84             #hardware_type = node.get('hardware_type')
85             #if hardware_type:
86             #    node_elem.add_instance('hardware_type', hardware_type)
87             hardware_type_elem = node_elem.add_element('hardware_type')
88             hardware_type_elem.set_text(node.get('hardware_type'))
89
90
91             if isinstance(node.get('interfaces'), list):
92                 for interface in node.get('interfaces', []):
93                     node_elem.add_instance('interface', interface, ['component_id', 'client_id', 'ipv4']) 
94             
95             #if 'bw_unallocated' in node and node['bw_unallocated']:
96             #    bw_unallocated = etree.SubElement(node_elem, 'bw_unallocated', units='kbps').text = str(int(node['bw_unallocated'])/1000)
97
98             PGv2Services.add_services(node_elem, node.get('services', []))
99             tags = node.get('tags', [])
100             if tags:
101                 for tag in tags:
102                     tag_elem = node_elem.add_element(tag['tagname'])
103                     tag_elem.set_text(tag['value'])
104             NITOSv1Sliver.add_slivers(node_elem, node.get('slivers', []))
105             
106             # add sliver tag in Request Rspec
107             if rspec_content_type == "request":
108                 node_elem.add_instance('sliver', '', [])
109
110     @staticmethod 
111     def add_slivers(xml, slivers):
112         component_ids = []
113         for sliver in slivers:
114             filter = {}
115             if isinstance(sliver, str):
116                 filter['component_id'] = '*%s*' % sliver
117                 sliver = {}
118             elif 'component_id' in sliver and sliver['component_id']:
119                 filter['component_id'] = '*%s*' % sliver['component_id']
120             if not filter:
121                 continue 
122             nodes = NITOSv1Node.get_nodes(xml, filter)
123             if not nodes:
124                 continue
125             node = nodes[0]
126             NITOSv1Sliver.add_slivers(node, sliver)
127
128     @staticmethod
129     def remove_slivers(xml, hostnames):
130         for hostname in hostnames:
131             nodes = NITOSv1Node.get_nodes(xml, {'component_id': '*%s*' % hostname})
132             for node in nodes:
133                 slivers = NITOSv1Sliver.get_slivers(node.element)
134                 for sliver in slivers:
135                     node.element.remove(sliver.element)
136         
137     @staticmethod
138     def get_nodes(xml, filter={}):
139         xpath = '//node%s | //default:node%s' % (XpathFilter.xpath(filter), XpathFilter.xpath(filter))
140         node_elems = xml.xpath(xpath)
141         return NITOSv1Node.get_node_objs(node_elems)
142
143     @staticmethod
144     def get_nodes_with_slivers(xml):
145         xpath = '//node[count(sliver)>0] | //default:node[count(default:sliver)>0]' 
146         node_elems = xml.xpath(xpath)
147         return NITOSv1Node.get_node_objs(node_elems)
148
149
150     @staticmethod
151     def get_node_objs(node_elems):
152         nodes = []    
153         for node_elem in node_elems:
154             node = NodeElement(node_elem.attrib, node_elem)
155             if 'site_id' in node_elem.attrib:
156                 node['authority_id'] = node_elem.attrib['site_id']
157             # get location
158             location_elems = node_elem.xpath('./default:location | ./location')
159             locations = [loc_elem.get_instance(Location) for loc_elem in location_elems]  
160             if len(locations) > 0:
161                 node['location'] = locations[0]
162             # get bwlimit
163             bwlimit_elems = node_elem.xpath('./default:bw_limit | ./bw_limit')
164             bwlimits = [bwlimit_elem.get_instance(BWlimit) for bwlimit_elem in bwlimit_elems]
165             if len(bwlimits) > 0:
166                 node['bwlimit'] = bwlimits[0]
167             # get interfaces
168             iface_elems = node_elem.xpath('./default:interface | ./interface')
169             ifaces = [iface_elem.get_instance(Interface) for iface_elem in iface_elems]
170             node['interfaces'] = ifaces
171             # get services
172             node['services'] = PGv2Services.get_services(node_elem) 
173             # get slivers
174             node['slivers'] = NITOSv1Sliver.get_slivers(node_elem)
175             # get tags
176             node['tags'] =  NITOSv1PLTag.get_pl_tags(node_elem, ignore=NodeElement.fields+["hardware_type"])
177             # get hardware types
178             hardware_type_elems = node_elem.xpath('./default:hardware_type | ./hardware_type')
179             node['hardware_types'] = [hw_type.get_instance(HardwareType) for hw_type in hardware_type_elems]
180
181             # temporary... play nice with old slice manager rspec
182             if not node['component_name']:
183                 hostname_elem = node_elem.find("hostname")
184                 if hostname_elem != None:
185                     node['component_name'] = hostname_elem.text
186
187             nodes.append(node)
188         return nodes            
189